PHP使用一个字符串调用多个方法
我有以下字符串:PHP使用一个字符串调用多个方法,php,reflection,Php,Reflection,我有以下字符串: $str = "methodA()->methodB()->methodC" 我想称之为物体上的“链” $obj->$str 我目前正在使用()->进行拆分并逐个调用,但肯定有更好的方法 我怎么能在一条线上叫它?谢谢 编辑:更多上下文信息: 我为symfony 1.4创建了一个条令行为,以便能够使用Zend Lucene从模式中搜索某些表 简而言之,我需要一种方法来说明这种行为“要获得可搜索字段,必须调用methodA()->methodB()->meth
$str = "methodA()->methodB()->methodC"
我想称之为物体上的“链”
$obj->$str
我目前正在使用()->进行拆分并逐个调用,但肯定有更好的方法
我怎么能在一条线上叫它?谢谢
编辑:更多上下文信息:
我为symfony 1.4创建了一个条令行为,以便能够使用Zend Lucene从模式中搜索某些表 简而言之,我需要一种方法来说明这种行为“要获得可搜索字段,必须调用methodA()->methodB()->methodC()” 编辑2: 也许我不够清楚$obj和$str是在运行时确定的,因此您的一些建议不适用 编辑3: 如果你想知道,我目前正在做:
<?php
$chain = explode("()->",$str);
$method = array_shift($chain);
$value = $obj->$method();
foreach($chain as $method){
$value = $value->$method();
}
我一般不建议使用,但是
不过,我会重新评估您的案例,可能会按照预期一个接一个地直接调用每个函数。您的方法已经很好了,但是。。。试一试
$str = "{$obj->methodA()->methodB()->methodC()}";
这是一种邪恶的做法
你能提供(我很好奇)一个用例吗
您可以连续使用,为此您可以编写一个帮助器方法,该方法能够解析您的符号并调用链。下面的方法行吗
$str = $methodA()->$methodB()->$methodC();
我的回答假设您有权访问这些方法(methodA、methodB和methodC),可以编辑它们,并且每个方法都属于$obj是其实例的类
更新每个方法以返回该类的实例,这将在假定它们不返回任何基本数据类型(如int、bool、string或其他)的情况下起作用:
<?php
class Example {
public function methodA() {
echo "method a\n";
return $this;
}
public function methodB() {
echo "method b\n";
return $this;
}
public function methodC() {
echo "method c\n";
return $this;
}
}
?>
在写下我对主要问题的评论后,我想到了一个可能的解决方案,尽管有点冗长和手工(你必须做出尽可能多的案例陈述,因为你合理地期望链式方法的数量)
用途如下:
$result = chain_execute($obj, "methodA->methodB->methodC");
那么字符串中的值是动态创建的吗?您可以实现一个助手函数来逐个创建它。在那之后,你将在一行中完成它。这通常就是编程的工作方式。@Javieh我认为在不知道会有固定数量的方法的情况下,你可以做一些事情,比如$obj->{$method[0]}()->{$method[1]}()->{$method[2]}()
,假设你不想使用eval()
,您当前的方法实际上是合适的。我认为PHP在默认情况下有一个方法可以做到这一点,我想我会像您指出的那样创建自己的方法。您的代码使它看起来像是在两次调用链中的第一个方法。看起来第3行应该是$value=$obj;我为symfony 1.4创建了一个条令行为,以便能够使用Zend Lucene从模式中搜索某些表。简言之,我需要一种方法来说明行为“要获得可搜索字段,必须调用methodA()->methodB()->methodC()”$obj是在运行时确定的。那又怎样?将$obj更改为您当前的运行时对象我想我不明白的是“{}”的作用是什么。它有什么作用?感谢这些方法不属于同一个类。相反,在返回“methodA()”时调用方法“methodB()”,如下所示。执行$obj->$chain[0]()和$obj->{$chain[0]}(),两者之间有什么区别?@javieh这只是围绕变量的括号符号,我认为在这种情况下,它更具可读性。我还想说,在某些情况下,我尝试过不使用括号,但遇到了问题,但我使用括号这么长时间了,我不知道是否仍然是这样。注意,我刚刚更改了分解位,因为以前的格式在最后一个数组成员的名称中会有一个额外的“()”。你可以做任何你喜欢的爆炸。或者保留旧的字符串格式并去掉“()”。
<?php
$obj = new Example();
$obj->methodA()->methodB()->methodC();
?>
method a
method b
method c
function chain_execute($obj, $str) {
$chain = explode("->",$str);
$chain = array_map('trim', $chain);
$chain_count = count($chain);
switch($chain_count) {
case 1:
return $obj->{$chain[0]}();
break;
case 2:
return $obj->{$chain[0]}()->{$chain[0]}();
break;
case 3:
return $obj->{$chain[0]}()->{$chain[1]}()->{$chain[2]}();
break;
// etc.
default:
// not a value you were expecting
throw new Exception('Invalid number of methods chained: ' . $chain_count);
break;
}
}
$result = chain_execute($obj, "methodA->methodB->methodC");