Python和Ruby等OO语言中常用的一个习惯用法是实例化对象和链接方法,这些方法返回对对象本身的引用,例如:
s = User.new.login.get_db_data.get_session_data
在PHP中,可以复制这样的行为:
$u = new User();
$s = $u->login()->get_db_data()->get_session_data();
在syntax error, unexpected T_OBJECT_OPERATOR
:中尝试以下结果
$s = new User()->login()->get_db_data()->get_session_data();
这似乎可以使用静态方法来完成,这可能是我最终要做的,但我想检查lazyweb:是否真的有一种干净、简单的方法来"内联"实例化PHP类(如上面的代码片段所示)?
如果我决定使用静态方法,那么让类的静态方法返回类本身的实例化是否太麻烦了?(有效地编写我自己的构造函数,而不是构造函数?)这感觉有点脏,但如果没有太多可怕的副作用,我可能会这么做。
我想我也可以用get_user()方法预先实例化UserFactory,但我对上面所问的解决方案很好奇。
所有这些提出的解决方案都会使代码复杂化,从而使PHP实现一些语法上的精确性。想要PHP成为一个不太好的东西是走向疯狂的道路。
我只想使用:
$u = new User();
$s = $u->login()->get_db_data()->get_session_data();
它清晰、相对简洁,不涉及可能引入错误的黑魔法。
当然,您可以随时使用Ruby或Python。它将改变你的生活。
- 是的,我对PHP很苛刻。我每天都用它。我用了好几年了。事实是,它已经增生,而不是经过设计和显示
<?php
class User
{
function __construct()
{
}
function Login()
{
return $this;
}
function GetDbData()
{
return $this;
}
function GetSession()
{
return array("hello" => "world");
}
}
function Create($name)
{
return new $name();
}
$s = Create("User")->Login()->GetDbData()->GetSession();
var_dump($s);
?>
这是一个可能的解决方案:)当然,你应该为函数选择一个更好的名称。。。
或者,如果你不介意一点开销:
<?php
class User
{
function __construct($test)
{
echo $test;
}
...
}
function CreateArgs($name)
{
$ref = new ReflectionClass($name);
return $ref->newInstanceArgs(array_slice(func_get_args(), 1));
}
$s = CreateArgs("User", "hi")->Login()->GetDbData()->GetSession();
var_dump($s);
?>
的简单快捷方式
$Obj = new ClassName();
$result = $Obj->memberFunction();
是
$result = (new ClassName())->memberFunction();
没有理由把破解(解决语法问题)和对象创建代码本身粘在一起。
由于新表达式不能用作对象运算符的左成员,但函数调用表达式可以,因此您只需要在对返回自己参数的函数的调用中包装对象:
function hack($obj) { return $obj; }
$mail = hack(new Zend_Mail())
-> setBodyText('This is the text of the mail.')
-> setFrom('somebody@example.com', 'Some Sender')
-> addTo('somebody_else@example.com', 'Some Recipient')
-> setSubject('TestSubject');
获得类似内容的唯一方法是使用工厂或单例静态方法。例如:
class User
{
//...
/**
*
* @return User
*/
public static function instance()
{
$args = func_get_args();
$class = new ReflectionClass(__CLASS__);
return $class->newInstanceArgs($args);
}
//...
}
它使用PHP5反射API来创建一个新实例(使用发送到:instance()的任何参数)并返回它,允许您执行链接:
$s = User::instance()->login()->get_db_data()->get_session_data();
顺便说一句,代码足够灵活,在复制该静态方法时,您唯一需要更改的就是PHPDoc注释的@return。
如果你想像我们的朋友Nelson一样过早地优化你的代码,你可以用:替换User::instance()的内容
return new self();
<?php
//PHP 5.4+ class member access on instantiation support.
$s = (new User())->login()->get_db_data()->get_session_data();