php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #37016 lambda functions unusable in create_function()
Submitted: 2006-04-08 05:35 UTC Modified: 2008-11-02 12:34 UTC
Votes:7
Avg. Score:4.0 ± 1.4
Reproduced:5 of 5 (100.0%)
Same Version:2 (40.0%)
Same OS:3 (60.0%)
From: a at b dot c dot de Assigned: derick (profile)
Status: Wont fix Package: Scripting Engine problem
PHP Version: 5.1.2 OS: Windows XP
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: a at b dot c dot de
New email:
PHP Version: OS:

 

 [2006-04-08 05:35 UTC] a at b dot c dot de
Description:
------------
When inserting (the name of) a lambda function provided by create_function into a string that will be used to create a second lambda function, the second function fails to parse. The parse error message makes what appears to be a spurious complaint about the code; only Test 5's error message makes sense (plus, it seems there is no "callable" version of a lambda function's name).

(Cf. bug #10721 - parser chokes on lambda function names in eval'd code)


Reproduce code:
---------------
I made five distinct tests to bracket the issue:
TEST 1:
// Creating a function that calls an ordinary function (explict name)
function always_true(){return true;}
$afun = create_function('', 'return !always_true();');
echo "Calling $afun() " . ($afun() ? "returns true\n" : "returns false\n");

TEST 2:
// Creating a function that calls an ordinary function (variable name)
function always_true(){return true;}
$b1 = 'always_true';
$bfun = create_function('','return !'.$b1.'();');
echo "Calling $bfun() " . ($bfun() ? "returns true\n" : "returns false\n");

TEST 3:
// Creating a function that calls an anonymous function (explicit name);
$c1 = create_function('','return true;');
$cfun = create_function('','return !'.chr(0).'lambda_3();');
echo "Calling $cfun() " . ($cfun() ? "returns true\n" : "returns false\n");

TEST 4:
// Creating a function that calls an anonymous function (variable name)
$d1 = create_function('','return true;');
$dfun = create_function('','return !'.$d1.'();');
echo "Calling $dfun() " . ($dfun() ? "returns true\n" : "returns false\n");

TEST 5:
// Using is_callable to get a callable version of anonymous function name
$e1 = create_function('', 'return true;');
if(!is_callable($e1,false,$callable_e1)) die("Couldn't call anonymous function.");
echo "Using $callable_e1 as name of anonymous function\n";
$efun = create_function('','return !'.$callable_e1.'();');
echo "Calling $efun() " . ($efun() ? "returns true\n" : "returns false\n");



Expected result:
----------------
TEST 1:
Calling  lambda_1() returns false

TEST 2:
Calling  lambda_1() returns false

TEST 3:
Calling  lambda_2() returns false

TEST 4:
Calling  lambda_2() returns false

TEST 5:
Using  lambda_1 as name of anonymous function  [?]
Calling  lambda_2() returns false


Actual result:
--------------
Actual Results:
TEST 1:
Calling  lambda_1() returns false

TEST 2:
Calling  lambda_1() returns false

TEST 3:
Parse error: parse error, unexpected '}' in test.php : runtime-created function on line 1
Fatal error: Function name must be a string in test.php on line 4

TEST 4:
Parse error: parse error, unexpected '}' in test.php : runtime-created function on line 1
Fatal error: Function name must be a string in test.php on line 4

TEST 5:
Using  as name of anonymous function
Parse error: parse error, unexpected ')' in test.php : runtime-created function on line 1
Fatal error: Function name must be a string in test.php on line 6


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2006-04-08 11:51 UTC] derick@php.net
I can reproduce this... let's see if I can come up with a fix.
 [2007-01-18 13:57 UTC] a dot steenveld at id dot umcn dot nl
hmmm.... I've not done enough reseachr in the bugreports. Well, I did, but too late. :(

While looking for a similar problem I found a likely cause for this problem, found a workaround for my problem, and suggested a change and filed a bug report.

See report #40160, hope you can use it.
 [2007-09-09 04:45 UTC] a at b dot c dot de
_Would it be sufficient if:_ instead of prefixing the lambda function with a NUL it were to be prefixed by '__'? Since PHP has (always?) claimed symbols starting with those characters for magical purposes anyone who is already declaring functions with names like "__lambda_1" is already effectively on notice that their code might break (moreso than someone who, in PHP 4, say, declared a function named "clone").

As it stands, higher-order functions are pretty much unworkable: attempts to construct new functions from existing ones are hamstrung by the fact that the existing functions may themselves be lambda functions and therefore unmentionable in the new function's body.


Currently the only valid workaround would appear to be something like (to use the notation of the original examples)

$dfun = create_function('','$d1=chr(0)."'.substr($d1,1).'"; return !$d1();');

Which of course needs to be further modified to deal with the cases where $d1 is not the name of a lambda function.
 [2008-11-02 12:34 UTC] jani@php.net
Same reasons as for #40160. Also, there are more useful closures 
coming in PHP 5.3. See also: http://wiki.php.net/rfc/closures
 
PHP Copyright © 2001-2020 The PHP Group
All rights reserved.
Last updated: Mon Jul 13 09:01:23 2020 UTC