Php 字符串更改函数的按引用质量传递?
对于字符串函数,我发现自己经常做这种事情:Php 字符串更改函数的按引用质量传递?,php,string,pass-by-reference,Php,String,Pass By Reference,对于字符串函数,我发现自己经常做这种事情: $string = trim($string); 我希望可以很容易地使用函数,通过引用传递字符串,因此我可以改为使用function($string) 我在考虑为我想要使用的所有字符串函数编写包装器,并在其前面加上一个特殊字符,如下所示: function _trim(&$string) { trim($string); } function _str_replace($a, $b, &$string) { st
$string = trim($string);
我希望可以很容易地使用函数,通过引用传递字符串,因此我可以改为使用function($string)代码>
我在考虑为我想要使用的所有字符串函数编写包装器,并在其前面加上一个特殊字符,如下所示:
function _trim(&$string) {
trim($string);
}
function _str_replace($a, $b, &$string) {
str_replace($a, $b, $string);
}
但我想知道是否有一种方法比为每个函数编写包装器更简单?(已经有人编写了这个库了吗?对于只能接受一个参数(字符串)的函数,如trim()
,strtolower()
等,您可以这样做,也许
function modify_str (&$str, $funcName) {
if (function_exists($funcName)) $str = $funcName($str);
}
// So you can now do
modify_str($str, 'trim');
modify_str($str, 'strtolower');
…但说实话,我真的看不出这一点-首先,你不能通过引用链接接受参数的函数(也就是说,你不能做trim(strtolower($str))
)
我倾向于不写$str=trim($str)代码>非常多,因为我可能会在其他一些操作中立即使用结果。与此相反:
$str = trim($str);
some_func($str, $someOtherVar);
我只是这样做:
some_func(trim($str), $someOtherVar);
如果我需要这样做:
$str = trim($str);
some_func($str, $someOtherVar);
another_func($str, $yetAnotherVar);
我会这样做:
some_func($str = trim($str), $someOtherVar);
another_func($str, $yetAnotherVar);
…但是,无论您试图通过执行上述任何一项操作来实现什么,您实际上实现的是降低代码的可读性,而可能没有其他功能
编辑
在今天做了一些完全无关的事情之后,我意识到有一种方法可以链接函数并通过引用调用它:
function modify_str (&$str) {
$args = func_get_args();
for ($i = 1; isset($args[$i]); $i++) {
if (function_exists($funcName = $args[$i])) $str = $funcName($str);
}
}
// So you could do
modify_str($str,'trim','strtolower');
…但我仍然认为这不是一条路
另一次编辑
您可以通过执行以下操作(未测试)传递给使用多个参数的函数:
好的观点。我只是厌倦了键入$string=function($string)
,这显然是我比你经常做的。这是一个无关紧要的问题,但是如果你也返回了值,你能嵌套(或链接)引用函数吗?我刚刚测试过它。回答:不!由于Zend引擎的一个限制,您无法做到这一点,即表达式的结果不能通过引用传递,而不首先分配给变量(如果您仔细考虑的话,这是有意义的)。所以你可以做modify_str($str=modify_str($str,'strtolower'),'trim')
如果您返回了值,但没有得到任何结果,因为这实际上比键入$str=trim(strtolower($str))要长代码>太酷了!:)但我也在想一种方法,可以通过引用字符串将其传递给具有多个参数的字符串修改函数,这些参数的顺序不同,比如str\u replace()
。看起来如果你能做到这一点,那将是一个巨大的难题:P
function modify_str (&$str) {
$str_identifier = '$$$'; // This identifies the argument where $str should be used
$ops = func_get_args();
for ($i = 1; isset($args[$i]); $i++) { // Loop functions to be applied
if (function_exists($ops[$i]['function'])) {
$args = array();
for ($j = 0; isset($ops[$i][$j]); $j++) { // Loop arguments for this function and build an argument list in PHP syntax
$args[] = ($ops[$i][$j] === $str_identifier) ? '$str' : "\$ops[\$i][$j]";
}
// eval() it (as if you had written it as straight PHP)
eval("\$str = {$ops[$i]['function']}(".implode(',',$args).");");
}
}
}
// So you can call it like this
modify_str($str,array('function'=>'str_replace','&','&','$$$'),array('function'=>'explode',"\n",'$$$'));
// ..which should have the same effect as
$str = explode("\n",str_replace('&','&',$str));
// As you can see, the not-by-reference way is is much shorter and more readable