Code-Golf:一行PHP语法

时间:2010-06-10 04:14:26

标签: php arrays function syntax code-golf

解释

PHP在其语法中有一些漏洞,偶尔在开发过程中,程序员会介入它们。这可能会导致很多挫折,因为这些语法漏洞似乎无缘无故地存在。例如,一个人不能轻易地创建一个数组并在同一行上访问该数组的任意元素(func1()[100]是无效的PHP语法)。此问题的解决方法是使用临时变量并将语句分成两行,但有时这会导致非常详细,笨重的代码。

挑战

我知道其中一些漏洞(我确信还有更多漏洞)。甚至很难提出解决方案,更不用说代码高尔夫风格了。获胜者是所有四个语法孔中总字符数最少的人。

规则

  1. 声明必须是此格式中的一行:$output = ...;,其中...不包含任何;
  2. 仅使用标准库函数(无自定义函数或允许eval
  3. 语句与非工作语法的假定功能相同(即使在失败的情况下)。
  4. 语句必须在E_STRICT | E_ALL
  5. 的任何类型的语法错误中运行

    语法孔

    1. $output = func_return_array()[$key]; - 访问函数返回数组的任意偏移量(stringinteger
    2. $output = new {$class_base.$class_suffix}(); - 用于创建新类的任意字符串连接
    3. $output = {$func_base.$func_suffix}(); - 任意字符串连接被称为函数
    4. $output = func_return_closure()(); - 调用从另一个函数返回的闭包

2 个答案:

答案 0 :(得分: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"

答案 1 :(得分:2)

我的解决方案比Shauns稍微长一点,但我想我还是会把它扔掉。它应该与原始语法完全相同,即使在错误情况下也是如此。我基本上利用三元语法允许两行合二为一。我还将临时变量更改为${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);

?>