У меня была прекрасная идея использовать пользовательский обработчик ошибок, который привел меня вниз кроличья нора.
Следующий код дает (с и без пользовательского обработчика ошибок): Фатальная ошибка: Только переменные могут быть переданы ссылкой
function foo(){
$b=array_pop(array("a","b","c"));
return $b;
}
print_r(foo());
Следующий код дает (только с пользовательским обработчиком ошибок): (2048) Только переменные должны быть переданы ссылкой
function foo(){
$a=explode( '/' , 'a/b/c');
$c=array_pop(array_slice($a,-2,1));
return $c;
}
print_r(foo());
Второй волнует меня, так как у меня есть много 'компактного' кода. Так, я любая канава прекрасная идея использовать пользовательский обработчик ошибок (для улучшения моего модуля входа) или разворачиваю весь свой код.
Кто-либо с лучшими идеями? Кроме того, WTF?
ОБНОВЛЕНИЕ:
Благодаря ответам я узнал что-то о том, как php делает обработку ошибок. Беспорядок E_ALL не включая E_STRICT (php 5) не прохладен.
Вдобавок ко всему этому, создавая Ваш собственный обработчик ошибок включает E_STRICT по умолчанию, и это - то, где проблемы запускаются.
Мораль истории должна использовать Ваш собственный обработчик ошибок, чтобы поймать их ВСЕХ и использовать ошибочные константы (E_STRICT, E_USER_WARNING, E_USER_ERROR, и т.д.), чтобы сделать Вашу фильтрацию.
Что касается 'проблемы повреждения памяти' со ссылками на переменную и определенными функциями, что я могу сказать? Вдвойне некрутой. Я буду (который не означает, что Вы должны) игнорировать E_STRICT в моем обработчике ошибок, и жизнь продолжается.
Это проблема повреждения памяти (по словам команды разработчиков PHP). Просто вбросьте задание:
function foo(){
$b = array_pop($arr = array("a","b","c"));
return $b;
}
print_r(foo());
:
function foo(){
$a = explode( '/' , 'a/b/c');
$c = array_pop($arr = array_slice($a,-2,1));
return $c;
}
print_r(foo());
Второе производит E_STRICT. Вы можете обрабатывать это по-разному в своем обработчике ошибок, если хотите (если вы не хотите изменять эти функции).
array_pop ()
изменяет переданное ему значение, из-за которого возникает ошибка. Функция не может быть изменена. Другими словами, вам нужно сначала назначить массив переменной (ссылка: manual ), а затем запустить array_pop ()
.
Вам нужен следующий код:
function foo(){
$a = array("a","b","c");
$b = array_pop($a);
return $b;
}
Изменить: Обе упомянутые вами функции имеют одинаковую проблему. Назначьте массив переменной и передайте переменную в array_pop ()
.
Попробуйте следующее:
function foo(){
$a = array("a","b","c");
$b = array_pop($a);
return $b;
}
array_pop () пытается изменить то значение, которое передается как параметр. Теперь во втором примере это значение, возвращаемое функцией array_slice (). С точки зрения движка, это «временное значение», и такое значение не может передаваться по ссылке. вам нужна временная переменная:
function foo(){
$a=explode( '/' , 'a/b/c');
$b=array_slice($a,-2,1);
$c=array_pop($b);
return $c;
}
print_r(foo());
Затем ссылку на $ b можно передать в array_pop (). См. http://php.net/references для получения дополнительной информации о ссылках.
Вот что я получаю при попытке вашего второго фрагмента кода php в php-cli после установки error_reporting на E_ALL | E_STRICT
gparis@techosaure:~/workspace/universcine.com$ php -a
Interactive shell
php > function foo(){
php { $a=explode( '/' , 'a/b/c');
php { $c=array_pop(array_slice($a,-2,1));
php { return $c;
php { }
php > print_r(foo());
PHP Strict standards: Only variables should be passed by reference in php shell code on line 3
PHP Stack trace:
PHP 1. {main}() php shell code:0
PHP 2. foo() php shell code:1
Как видите, здесь только строгие стандарты. И вы можете легко позволить своему пользовательскому обработчику ошибок игнорировать их (в зависимости от полученного значения: например, здесь 2048).
Начиная с php 5.3, E_ALL не включает E_STRICT, посмотрите на это:
php > foreach(array("E_ALL", "E_DEPRECATED", "E_STRICT", "E_NOTICE", "E_PARSE", "E_WARNING") as $const) echo $const . " :\t" . constant($const) ."\t". decbin(constant($const)). "\n";
E_ALL : 30719 111011111111111
E_DEPRECATED : 8192 10000000000000
E_STRICT : 2048 100000000000
E_NOTICE : 8 1000
E_PARSE : 4 100
E_WARNING : 2 10
Начиная с php 5.4, E_ALL
включает E_STRICT
:
E_ALL : 32767 111111111111111
E_DEPRECATED : 8192 10000000000000
E_STRICT : 2048 100000000000
E_NOTICE : 8 1000
E_PARSE : 4 100
E_WARNING : 2 10