10

説明

PHPには構文にいくつかの穴があり、開発時にプログラマーがそれらに介入することがあります。これらの構文の穴は理由もなく存在するように見えるため、これは多くのフラストレーションにつながる可能性があります。たとえば、配列を簡単に作成して、同じ行にあるその配列の任意の要素にアクセスすることはできませfunc1()[100]ん(有効なPHP構文ではありません)。この問題の回避策は、一時変数を使用してステートメントを2行に分割することですが、非常に冗長で不格好なコードになる場合があります。

チャレンジ

私はこれらの穴のいくつかを知っています(もっとあると確信しています)。コードゴルフスタイルは言うまでもなく、解決策を思いつくことすら非常に困難です。勝者は、4つの構文ホールすべての合計文字数が最も少ない人です。

ルール

  1. ステートメントは、次の形式の1行である必要があります。$output = ...;ここで、...は含まれていません;
  2. 標準ライブラリ関数のみを使用してください(カスタム関数は使用できませんeval) 。
  3. ステートメントは、機能しない構文の想定される機能と同じように機能します(失敗した場合でも)。
  4. ステートメントは、。を使用して、いかなる種類の構文エラーも発生せずに実行する必要があります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

2 に答える 2

8

私が見る唯一の解決策は一時変数を含むので、いくつかの(最小限の)名前空間の汚染があります。一時変数コードを厳しくする方法は、これら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"
于 2010-06-10T06:13:31.060 に答える
2

私の解決策はショーンズより少し長いですが、とにかくそれを投げると思いました。エラーが発生した場合でも、元の構文と同じように機能するはずです。私は基本的に三元構文を利用して、1つに2行を許可しています。また、一時変数を${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);

?>
于 2010-06-15T02:53:15.250 に答える