массовая передача по ссылке для функции смены строк? - PullRequest
2 голосов
/ 17 октября 2011

Для строковых функций я часто занимаюсь такими вещами:

$string = trim($string);

Мне бы хотелось, чтобы у меня были функции, позволяющие передавать строку по ссылке, поэтому вместо этого я могу сделать function($string);.

Я думал о написании оболочек для всех строковых функций, которые я хочу использовать, и префикс его специальным символом, например так:

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

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

Но мне интересно, есть ли способ проще, чем написать обертку для каждой функции? (Кто-то уже написал эту библиотеку?)

1 Ответ

2 голосов
/ 17 октября 2011

Для функций, которые могут принимать только один аргумент (строку), например 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);

Iбудет делать это:

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
...