【问题标题】:mass pass-by-reference for string changing functions?字符串更改函数的质量传递引用?
【发布时间】:2011-12-09 10:09:14
【问题描述】:

对于字符串函数,我发现自己经常做这种事情:

$string = trim($string);

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

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

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

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

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

【问题讨论】:

    标签: php string pass-by-reference


    【解决方案1】:

    对于只能接受一个参数(字符串)的函数,例如 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
    

    【讨论】:

    • 好点。我只是厌倦了输入$string = function($string),显然我这样做的频率比你发现自己做的要多。
    • 这是一个切题的问题,但如果你也返回了值,你能嵌套(或链接)引用函数吗?
    • 我刚刚测试过了。答:没有!
    • 你不能这样做,因为 Zend 引擎的限制,即表达式的结果不能通过引用传递,除非先分配给变量(如果你考虑一下,这是有道理的)。因此,如果您返回值,您可以执行modify_str($str = modify_str($str, 'strtolower'), 'trim');,但是您没有获得任何东西,因为这实际上比输入$str = trim(strtolower($str));更长
    • 这太酷了! :) 但我也试图想出一种方法,您可以通过引用字符串将字符串传递给具有多个参数的字符串修改函数,以各种顺序,例如str_replace()。如果你能做到的话,这将是一个巨大的混乱:P
    猜你喜欢
    • 2021-03-20
    • 1970-01-01
    • 2016-10-26
    • 1970-01-01
    • 1970-01-01
    • 2010-12-01
    • 1970-01-01
    • 2017-02-19
    • 1970-01-01
    相关资源
    最近更新 更多