объяснение
PHP имеет некоторые дыры в своем «синтаксисе», а иногда и в разработке, в который будет входить программист. Это может привести к большому разочарованию, поскольку эти синтаксические отверстия, по-видимому, существуют без причины. Например, невозможно создать массив и получить доступ к произвольному элементу этого массива в одной строке ( func1()[100]
недопустим синтаксис PHP). Обходной путь для этой проблемы заключается в использовании временной переменной и разбиении оператора на две строки, но иногда это может привести к очень многословному, неуклюжим коду.
Вызов
Я знаю несколько из этих отверстий (я уверен, что их больше). Трудно даже придумать решение, не говоря уже о стиле кода. Победителем является человек с наименьшим количеством символов для всех четырех синтаксических отверстий.
правила
$output = ...;
, где ...
не содержит никаких ;
«S. eval
) E_STRICT | E_ALL
E_STRICT | E_ALL
. Синтаксические отверстия
$output = func_return_array()[$key];
– доступ к произвольному смещению ( string
или integer
) возвращенного массива функции $output = new {$class_base.$class_suffix}();
– произвольная конкатенация строк используется для создания нового класса $output = {$func_base.$func_suffix}();
– произвольная конкатенация строк, вызываемая как функция $output = func_return_closure()();
– вызвать замыкание, возвращаемое из другой функции Единственное решение, которое я вижу, связано с временной переменной, поэтому существует некоторое (минимальное) загрязнение пространства имен. Любой способ затягивания временного кода переменной сократит все 4 из них:
<?php error_reporting(E_ALL | E_STRICT); // 1 function func_return_array() { return array(0 => 'hello'); } $key = 0; $output = ${!${''}=func_return_array()}[$key]; echo '1: ' . $output . "\n"; // 2 class Thing {} $class_base = 'Thi'; $class_suffix = 'ng'; $output = new ${!${''}=$class_base.$class_suffix}(); echo '2: '; var_dump($output); // 3 $func_base = 'func_'; $func_suffix = 'return_array'; $output = ${!${''}=$func_base.$func_suffix}(); echo '3: '; var_dump($output); // 4 function func_return_closure() { return function() { return 'This is a closure'; }; } $output = ${!${''}=func_return_closure()}(); echo '4: '; var_dump($output);
Вывод:
1: hello 2: object(Thing)#1 (0) { } 3: array(1) { [0]=> string(5) "hello" } 4: string(17) "This is a closure"
Мое решение немного длиннее, чем Шонс, но я думал, что все равно его брошу. Он должен работать идентично исходному синтаксису, даже в случае ошибок. Я в основном использую тройственный синтаксис, чтобы разрешить две строки в одном. Я также изменил временную переменную на ${0}
вместо ${''}
так как она сохраняет символ, а переменные, начинающиеся с цифр, недопустимы.
Нижеследующие утверждения,
line1; $output = line2;
Для каждого возможного случая идентичен следующему утверждению.
$output = (line1)&&0?:(line2);
Мое решение:
<?php error_reporting(E_ALL | E_STRICT); // 1 function func_return_array() { return array(0 => 'hello'); } $key = 0; $output = (${0}=func_return_array())&&0?:${0}[$key]; echo '1: ' . $output . "\n"; // 2 class Thing {} $class_base = 'Thi'; $class_suffix = 'ng'; $output = (${0}=$class_base.$class_suffix)&&0?:new ${0}; echo '2: '; var_dump($output); // 3 $func_base = 'func_'; $func_suffix = 'return_array'; $output = (${0}=$func_base.$func_suffix)&&0?:${0}(); echo '3: '; var_dump($output); // 4 function func_return_closure() { return function() { return 'This is a closure'; }; } $output = call_user_func(func_return_closure()); //more straight forward //$output = (${0}=func_return_closure())&&0?:${0}(); echo '4: '; var_dump($output); ?>