PHP 5.4 - Traits和self / static

14

我希望能够像下面这样在我的类上进行方法链调用:

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;

    // ...
}

但是看起来特质(trait)无法处理self或static关键字,而且我无法执行get_class($this),因为这是静态的。有没有明确的方法可以满足我的需求?

谢谢阅读。

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

$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')));

括号嵌套深度越浅,错误越少,修复这些错误所需的时间也越短,代码阅读起来更容易,并且在我看来,代码看起来更好。


2
使用括号有什么问题? - Spudley
减少括号的数量可以降低忘记其中一个括号所犯错误的概率,同时也减少了修复错误所需的时间,使代码更易于阅读和理解。 - Virus721
嗯,说实话,我觉得带括号的代码非常易读,特别是在使用良好的IDE时。但各有所好。 :-) - Spudley
3个回答

12

1
非常感谢,运行得完美! :D 他们的新功能工作方式对我来说不是很直观 :( - Virus721

0

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

但是如果你确实想在所有类中都有这样的工厂方法,为什么不只是创建一个基类,让所有其他类都继承自该基类,并定义create方法呢?我认为你不需要一个trait。

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

然后所有其他类都extends BaseClass,如果你还没有extends


感谢您的回答。正如我所解释的,简单继承是原因。 - Virus721
如果这是一个基类,并且您的核心类扩展它,那么扩展它们的类也将具有它。如果它将成为所有类的功能,则像这样的基类就非常合理。 - Spudley
是的,但在无法使类从此BaseClass继承以使子类也从中继承的情况下, trait 可派上用场。此外,重复使用方法或一组方法正是 trait 的确切目的。 - Virus721

-2

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 函数的值。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接