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
$output = ...;
, where ...
doesn't contain any ;
's.eval
allowed)E_STRICT | E_ALL
.Syntax Holes
$output = func_return_array()[$key];
- accessing an arbitrary offset (string
or integer
) of the returned array of a function$output = new {$class_base.$class_suffix}();
- arbitrary string concatenation being used to create a new class$output = {$func_base.$func_suffix}();
- arbitrary string concatenation being called as function$output = func_return_closure()();
- call a closure being returned from another functionThe 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"
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);
?>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With