Code-Golf:一行 PHP 语法

发布于 2024-09-05 00:46:30 字数 991 浏览 7 评论 0原文

解释

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

Explanation

PHP has some holes in its' syntax and occasionally in development a programmer will step in them. This can lead to much frustration as these syntax holes seem to exist for no reason. For example, one can't easily create an array and access an arbitrary element of that array on the same line (func1()[100] is not valid PHP syntax). The workaround for this issue is to use a temporary variable and break the statement into two lines, but sometimes that can lead to very verbose, clunky code.

Challenge

I know of a few of these holes (I'm sure there are more). It is quite hard to even come up with a solution, let alone in a code-golf style. Winner is the person with in the least characters total for all four Syntax Holes.

Rules

  1. Statement must be one line in this form: $output = ...;, where ... doesn't contain any ;'s.
  2. Only use standard library functions (no custom functions or eval allowed)
  3. Statement works identically to the assumed functional of the non-working syntax (even in cases that it fails).
  4. Statement must run without syntax error of any kind with E_STRICT | E_ALL.

Syntax Holes

  1. $output = func_return_array()[$key]; - accessing an arbitrary offset (string or integer) of the returned array of a function
  2. $output = new {$class_base.$class_suffix}(); - arbitrary string concatenation being used to create a new class
  3. $output = {$func_base.$func_suffix}(); - arbitrary string concatenation being called as function
  4. $output = func_return_closure()(); - call a closure being returned from another function

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

情话难免假 2024-09-12 00:46:31

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

The only solution I see involves a temporary variable, so there is some (minimal) namespace pollution. Any way of tightening the temporary variable code would shorten all 4 of these:

<?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);

Output:

1: hello
2: object(Thing)#1 (0) {
}
3: array(1) {
  [0]=>
  string(5) "hello"
}
4: string(17) "This is a closure"
辞旧 2024-09-12 00:46:31

我的解决方案比肖恩的稍长,但我想我还是会放弃它。即使在错误情况下,它的工作方式也应与原始语法相同。我基本上是利用三元语法来允许两行合二为一。我还将临时变量更改为 ${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);

?>

My solution is slightly longer than Shauns' but I thought I'd throw it up anyway. It should work identically to the original syntax, even in error cases. I'm basically exploiting the ternary syntax to allow two lines in one. I also changed the temporary variable to ${0} instead of ${''} since it save a character and variables that begin with numbers are not valid.

The below statements,

line1;
$output = line2;

Is identical to the following statement for every possible case.

$output = (line1)&&0?:(line2);

My solution:

<?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);

?>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文