字符串更改函数的质量传递?

时间:2011-10-17 15:50:41

标签: php string pass-by-reference

对于字符串函数,我发现自己做了很多这样的事情:

$string = trim($string);

我想轻松拥有可以通过引用传递字符串的函数,所以我可以改为function($string);

我正在考虑为我想要使用的所有字符串函数编写包装器,并在其前面添加一个特殊字符,如下所示:

 function _trim(&$string) {
   trim($string);
 }

 function _str_replace($a, $b, &$string) {
    str_replace($a, $b, $string);
 }

但我想知道是否有一种比为每个函数编写包装更容易的方法? (有人写过这个库吗?)

1 个答案:

答案 0 :(得分:2)

对于只能使用一个参数(字符串)的函数,如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');

......但我仍然认为这不是可行的方法。

另一个编辑

你可以通过做这样的事情(未经测试)传递给使用多个参数的函数:

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