{ return strlen($str); } public static function instance() { return new self(); } public function strlenFunction() { return 'strlen'; } } function func() { return array('func'); } function test() { return 'test'; } testStrict(checkFunc('strlen')('four'), 4, 'func()()'); testStrict($checkFunc('strlen')('four'), 4, '$func()()'); testStrict(Test::checkFunc('strlen')('four'), 4, 'Class::method()()'); testStrict(Test::checkFunc(array('Test', 'strlen'))('four'), 4, 'Class::method(array(...))()'); testStrict(${$checkFunc}('strlen')('four'), 4, '$$func()()'); testStrict(Test::${$checkFunc}('strlen')('four'), 4, 'Class::$$method()()'); testStrict(Test::instance()->strlenFunction()('four'), 4, 'complex resolution'); testStrict(func()[0]()[0](), array('func'), 'func()[0]()[0]() (depends on arrayAccess)'); testStrict(test()()(), 'test', 'func()()()'); ?> </pre>
<pre> Subj: Ternary Operator without middle part Example: expr1 ?: expr2; <hr /> Output: <?php require_once './testUtils.php'; function incr() { static $a = 0; return ++$a; } testStrict(7 ?: 8, 7, 'expr ?: expr'); testStrict(incr() ?: 7, 1, 'func() ?: expr'); ?> </pre>
<pre> Subj: Lambda functions and Closures Example: function() {}, function() use() {} <hr /> Output: <?php require_once './testUtils.php'; $lambdas = array(); $lambdas[0] = function () { return 'nothing'; }; $lambdas[1] = function ($arg) { return $arg; }; $prefix = 'foo'; $lambdas[2] = function ($arg) use($prefix) { return $prefix . '_' . $arg; }; $unusedActually = 0; $lambdas[3] = function ($arg) use(&$prefix, $unusedActually) { $prefix = $arg; }; testStrict($lambdas[0](), 'nothing', 'without args'); testStrict($lambdas[1]('foo'), 'foo', 'with arg'); testStrict($lambdas[2]('foo'), 'foo_foo', 'with use()'); $lambdas[3]('bar'); testStrict($prefix, 'bar', 'with use(&)'); ?> </pre>
global $array; return $array; } } $obj = new Test(); $objName = 'obj'; $get = 'get'; $get_static = 'get_static'; $Test = 'Test'; testStrict(get()[0], 'hi', 'func()[]'); testStrict(Test::get_static()[0], 'hi', 'Class::method()[]'); testStrict($Test::$get_static()[0], 'hi', '$class::$method()[] (depends on varClassStatic)'); testStrict($get()[1], 7, '$func()[]'); testStrict(${$get}()[1], 7, '$$func()[]'); testStrict($obj->get()[1], 7, '$obj->method()[]'); testStrict(${$objName}->{${$get}}()[1], 7, '$$obj->$$method()[]'); class Very { public static function long() { return new self(); } public function call() { global $array; return $array; } } testStrict(Very::long()->call()[0], 'hi', 'complex resolution'); ?> </pre>
Example: $class::const, $class::$property, $class::method() <hr /> Output: <?php require_once './testUtils.php'; class Foo { const constant = 'hi'; static $property = 'hi'; static function method($nix = '') { return 'hi'; } } $class = 'Foo'; $stringWithClass = 'class'; $method = 'method'; $stringWithProperty = 'property'; testStrict($class::constant, 'hi', '$class::constant'); testStrict($class::method(), 'hi', '$class::method()'); testStrict($class::method(2), 'hi', '$class::method(arg)'); testStrict($class::$method(), 'hi', '$class::$method()'); testStrict($class::${${${$method}}}(), 'hi', '$class::$$$$method()'); testStrict($class::$property, 'hi', '$class::$property'); testStrict($class::$inexistantProperty, null, '$class::$inexistantProperty'); testStrict($class::${$stringWithProperty}, 'hi', '$class::$$property'); // Todo: trigger_error: // Access to undeclared static property: Foo::$inexistantProperty in ... on line ... testStrict(${$stringWithClass}::$property, 'hi', '$$class::$property'); ?> </pre>