Code-Golf: однострочный синтаксис PHP

объяснение

PHP имеет некоторые дыры в своем «синтаксисе», а иногда и в разработке, в который будет входить программист. Это может привести к большому разочарованию, поскольку эти синтаксические отверстия, по-видимому, существуют без причины. Например, невозможно создать массив и получить доступ к произвольному элементу этого массива в одной строке ( func1()[100] недопустим синтаксис PHP). Обходной путь для этой проблемы заключается в использовании временной переменной и разбиении оператора на две строки, но иногда это может привести к очень многословному, неуклюжим коду.

Вызов

Я знаю несколько из этих отверстий (я уверен, что их больше). Трудно даже придумать решение, не говоря уже о стиле кода. Победителем является человек с наименьшим количеством символов для всех четырех синтаксических отверстий.

правила

  1. Выражение должно быть одной строкой в ​​этой форме: $output = ...; , где ... не содержит никаких ; «S.
  2. Используйте только стандартные библиотечные функции (не разрешены никакие пользовательские функции или eval )
  3. Заявление работает одинаково с предполагаемым функционалом нерабочего синтаксиса (даже в случае его отказа).
  4. Заявление должно выполняться без синтаксической ошибки любого типа с помощью E_STRICT | E_ALL E_STRICT | E_ALL .

Синтаксические отверстия

  1. $output = func_return_array()[$key]; – доступ к произвольному смещению ( string или integer ) возвращенного массива функции
  2. $output = new {$class_base.$class_suffix}(); – произвольная конкатенация строк используется для создания нового класса
  3. $output = {$func_base.$func_suffix}(); – произвольная конкатенация строк, вызываемая как функция
  4. $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); ?>