是否有可能编写一系列重复引用PHP中单个对象的语句?

时间:2014-07-18 07:59:33

标签: php php-5.3

是否可以编写一系列重复引用单个对象的语句而无需每次都写入对象?

我之所以这样,是因为我曾经在Visual Basic中这样做:

With person
    .setFullName(.firstName+" "+.lastName)
    .addParent(parent)
    .save()
End With

这是

的简写
person.setFullName(person.firstName+" "+person.lastName)
person.addParent(parent)
person.save()

有可能在PHP中实现这一点吗? 要重写以下代码而不必编写$person 5次?

$person->setFullName($person->firstName.' '.$person->lastName);
$person->addParent($parent);
$person->save();

注意:由于两个原因,我没有提及方法链接

1)我也想使用公共成员

2)我不能处理我写的课程,因此我无法将return $this;添加到所有方法

由于

4 个答案:

答案 0 :(得分:2)

存在允许执行此操作的PHP库: https://github.com/lisachenko/go-aop-php

实施示例: http://go.aopphp.com/blog/2013/03/19/implementing-fluent-interface-pattern-in-php/

创建您的方面

<?php
use Go\Aop\Aspect;
use Go\Aop\Intercept\MethodInvocation;
use Go\Lang\Annotation\Around;

class FluentInterfaceAspect implements Aspect
{
    /**
     * Fluent interface advice
     *
     * @Around("within(FluentInterface+) && execution(public **->set*(*))")
     *
     * @param MethodInvocation $invocation
     * @return mixed|null|object
     */
    protected function aroundMethodExecution(MethodInvocation $invocation)
    {
        $result = $invocation->proceed();
        return $result!==null ? $result : $invocation->getThis();
    }
}

添加匹配的界面

interface FluentInterface
{

}


class User implements FluentInterface
{
    protected $name;
    protected $surname;
    protected $password;

    public function setName($name)
    {
        $this->name = $name;
    }

    public function setSurname($surname)
    {
        $this->surname = $surname;
    }

    public function setPassword($password)
    {
        if (!$password) {
            throw new InvalidArgumentException("Password shouldn't be empty");
        }
        $this->password = $password;
    }
}

用法

$user = new User;
$user->setName('John')->setSurname('Doe')->setPassword('root');

但您可以在不添加新界面的情况下编写匹配规则。

P.S。这不是问题的正确答案,因为需要其他语法糖。 PHP不支持这种语法。

答案 1 :(得分:0)

你不能用PHP做到这一点。 该语言的语法不允许

答案 2 :(得分:0)

在PHP中你可以这样做,但当然你可以创建更短的变量

$p = &$person;

$p->setFullName($p->firstName.' '.$p->lastName);
$p->addParent($parent);
$p->save();

unset($p);

但在这种情况下,您仍然拥有->运算符和变量,并且没有提到过的库,您将无法获得更多。

答案 3 :(得分:0)

是的,你可以做到。它被称为方法链(如果我没记错的话)。我举个简单的例子:

class A {
    public $attributes;

    public function __construct() {
        return $this;
    }

    public function methodA($a) {
        if (!empty($a)) {
            $this->attributes["a"] = $a;
        }

        return $this;
    }

    public function methodB($b) {
        if (!empty($b)) {
            $this->attributes["b"] = $b;
        }

        return $this;
    }

    public function methodC($c) {
        if (!empty($c)) {
            $this->attributes["c"] = $c;
        }

        return $this;
    }
}

您正在寻找的关键是返回对象本身(因此,引用return $this;)并获得与VB相同的行为。在PHP中你会这样做:

$a = new A();
$a->methodA(5)->methodB(50)->methodC(500);

甚至:

$a = (new A())->methodA(5)->methodB(50)->methodC(500);

希望有所帮助:)