【问题标题】:Code-Golf: one line PHP syntaxCode-Golf:一行 PHP 语法
【发布时间】:2011-03-01 23:52:22
【问题描述】:

说明

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

挑战

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

规则

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

语法漏洞

  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()(); - 调用从另一个函数返回的闭包

【问题讨论】:

  • 数组解引用(您的 1. 语法漏洞)已由 Felipe Pena 提交到主干。
  • @Artefacto 这真是个好消息!我听到的最后耳语是它被忽略了。你有那个链接吗?
  • 我认为这个练习毫无意义。更少的字符不同于更清晰/更高效。
  • 只适用于 PHP?这不是代码高尔夫的真正精神,它通常与语言无关。

标签: php arrays function syntax code-golf


【解决方案1】:

我看到的唯一解决方案涉及临时变量,因此存在一些(最小的)命名空间污染。任何收紧临时变量代码的方法都会缩短所有这 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"

【讨论】:

  • 以这种方式进行变量赋值非常有趣。以前从未见过这种语法。
【解决方案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);

?>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-02-11
    • 2011-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-25
    • 2010-11-23
    • 1970-01-01
    相关资源
    最近更新 更多