【问题标题】:PHP 5.4 - Traits and self / staticPHP 5.4 - 特征和自我/静态
【发布时间】:2013-03-04 19:40:44
【问题描述】:

我想在我的类上链接方法调用,如下所示:

new Obj($args, $if, $any)->foo()->bar();

不幸的是,我必须将结构括在括号内:

(new Obj($args, $if, $any))->foo()->bar();

所以我想拥有一个可以在每个班级重复使用的特质,我希望能够做类似的事情:

Obj::create($args, $if, $any)->foo()->bar();

我希望它成为一个特征,这样我的类仍然可以从其他类继承。 我已经到了这一点:

trait Create
{
    public static final function create()
    {
        $reflect = new ReflectionClass(/* self ? static ? Anything else ? */);
        return $reflect->newInstanceArgs(func_get_args());
    }
}

class Obj
{
    use Create;

    // ...
}

但似乎特质不处理 self 或 static 关键字,我不能这样做 get_class($this) 因为这是静态的。 请问有什么明确的方法可以做我想做的事吗?

感谢阅读。

编辑:对于那些想知道的人,这就是为什么我希望它成为一个特征而不是抽象基类:

$database = (new Database())
    ->addTable((new Table())
        ->addColumn((new Column('id', 'int'))
            ->setAttribute('primary', true)
            ->setAttribute('unsigned', true)
            ->setAttribute('auto_increment', true))
        ->addColumn(new Column('login', 'varchar'))
        ->addColumn(new Column('password', 'varchar')));

$database = Database::create()
    ->addTable(Table::create()
        ->addColumn(Column::create('id', 'int')
            ->setAttribute('primary', true)
            ->setAttribute('unsigned', true)
            ->setAttribute('auto_increment', true))
        ->addColumn(Column::create('login', 'varchar'))
        ->addColumn(Column::create('password', 'varchar')));

括号深度更少,错误更少,修复这些错误所需的时间更少,而且代码更易于阅读,而且在我看来,代码看起来更好。

【问题讨论】:

  • 使用括号到底有什么问题??
  • 减少括号的数量可以减少因忘记其中一个而犯错的可能性以及修复错误所需的时间,并使代码更易于阅读和理解。
  • 嗯,好吧,老实说,我想说带括号的代码是完全可读的,特别是如果你使用的是一个不错的 IDE。但各有各的。 :-)

标签: php static constructor traits


【解决方案1】:

是的,有get_called_class(),这正是你想要的。

【讨论】:

  • 工作完美,谢谢! :D 他们的新功能的工作方式对我来说不是那么直观:(
【解决方案2】:

我不明白你为什么不想使用方括号——它并不是世界上最糟糕的语法(事实上,我认为从视觉角度来看它比你想要的双冒号语法更好替换它)

但是,如果您确实希望在所有类上都有这样的工厂方法,为什么不创建一个基类,所有其他类都从该基类扩展定义 create 方法?我不认为你需要一个特质。

class BaseClass {
    public function create() {
        ...
    }
}

然后是所有其他类 extends BaseClass,您还没有 extends

【讨论】:

  • 感谢您的回答。正如我所解释的,原因是简单的继承。
  • 如果这是一个基类,并且您的核心类扩展了它,那么扩展它们的类也将拥有它。如果它会成为你所有类的一个特性,那么像这样的基类就非常有意义。
  • 是的,但是在我不能让类继承自这个 BaseClass 以便子类也继承自它的情况下,一个 trait 会派上用场。此外,重用一个方法或一组方法是 trait 的确切目的。
【解决方案3】:

Traits 是 PHP 中的一个新特性。此功能在 5.4 版本中引入。这是 PHP 中多重继承的替代品

示例:

trait Net
{
    public function net()
    {
        return 'Net';
    }
}

trait Tuts
{
    public function tuts()
    {
        return 'Tuts';
    }
}

class NetTuts
{
    use Net, Tuts;
    public function plus()
    {
        return 'Plus';
    }
}

$o = new NetTuts;
echo $o->net(), $o->tuts(), $o->plus();

输出是:NetTutsPlus

echo (new NetTuts)->net(), (new NetTuts)->tuts(), (new NetTuts)->plus();

输出是:NetTutsPlus

在对象 $o 的帮助下,我们可以访问 trait 函数值..

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-07-28
    • 1970-01-01
    • 1970-01-01
    • 2013-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多