【问题标题】:Changing the Privacy Scope of PHP Class Functions更改 PHP 类函数的隐私范围
【发布时间】:2012-12-19 16:12:15
【问题描述】:

我有一个抽象类,它扩展类以提供基本的 orm 函数。它提供的所有功能都受类保护,因此它可以决定哪些字段对外部对象公开可用。但最近,我开始使用一些不需要如此复杂性的较小数据类,并且将受益于公开可用的 orm 编辑功能且没有特殊功能。

由于函数的命名约定足够紧凑,有没有办法将现有函数更改为公共(不需要相同的类或临时扩展),或者我必须使用新的traits php 的特性是添加一个现有类,其中包含作为内部受保护函数的抽象层的函数的公共版本?

编辑:

对于 traits 方法,我认为它会有所帮助:

abstract class ORMClass {
    public function __construct($pk) {}
    protected function __get($k) {}
    protected function __set($k,$v) {}
    protected function save() {}
}

trait publicORM {
    public function __get($k) { return parent::__get($k); }
    public function __set($k,$v) { return parent::__set($k,$v); }
    public function save() { return parent::save(); }
}

class myOrm extends ORMClass {
    use publicORM;
    protected static $table = 'myTable';
}

那么我可以使用myOrm 像:

$myOrm = new myOrm(1);
$myOrm->foo = 'alice'
echo $myOrm->bar;
$myOrm->save();

不需要:

public function __get($k) { return parent::__get($k); }
public function __set($k,$v) { return parent::__set($k,$v); }
public function save() { return parent::save(); }

在类 myOrm 中列出

【问题讨论】:

  • 那么您有一个带有受保护方法的类,并且在外部,您想修改该类以将其某些方法从受保护更改为公共?
  • 我认为你提到的临时类方法将是最好的。创建另一个扩展您的基础但具有公共访问器的抽象类,并在您想要该行为时将其子类化。
  • 谈论过于复杂的事情...... :)
  • 这不是一半的乐趣吗?
  • @SDC,从 PHP 5.3.2 开始,您可以使用 ReflectionMethod::setAccessible 来执行此操作。

标签: php class scope abstract-class


【解决方案1】:

由于从未正确回答,因此我添加了查尔斯的答案。

这可以使用 PHP 的 Reflection 库来完成,该库从 PHP 版本 5 开始就内置在 PHP 中。这种特殊的方法相当 hacky:

<?php

abstract class BaseClass {
    protected function testMe() {
        echo 'I WORK!';
    }
}

class ConcreteClass extends BaseClass {
    // Class Code
}


$method = new ReflectionMethod('BaseClass', 'testMe');
$method->setAccessible(true);
$method->invoke(new ConcreteClass()); // Prints 'I WORK!'

这是使用扩展基类但使用公共方法的临时抽象类的更好方法:

<?php

abstract class BaseClass {
    protected function testMe() {
        echo 'I WORK!';
    }
}

abstract class PublicBaseClass extends BaseClass {
    public function testMe() {
        parent::testMe();
    }
}

class ConcreteClass extends PublicBaseClass {
    // Class Code
}


$obj = new ConcreteClass();
$obj->testMe();

【讨论】:

    猜你喜欢
    • 2020-04-20
    • 1970-01-01
    • 2015-09-20
    • 2012-09-14
    • 1970-01-01
    • 2020-10-14
    • 1970-01-01
    • 1970-01-01
    • 2012-08-03
    相关资源
    最近更新 更多