Edit report at https://bugs.php.net/bug.php?id=61790&edit=1

 ID:                 61790
 Comment by:         ni...@php.net
 Reported by:        thegreatall at gmail dot com
 Summary:            Feature Request for create_closure() function
 Status:             Open
 Type:               Feature/Change Request
 Package:            *Programming Data Structures
 Operating System:   N/A
 PHP Version:        Irrelevant
 Block user comment: N
 Private report:     N

 New Comment:

I'm not sure I understand your issue. create_function() is just a wrapper 
around eval(). The evils of eval() are also the evils of create_function().

And, as you showed, this is trivial to implement in userland.

I really wouldn't like PHP to add further functions encouraging bad coding 
style.


Previous Comments:
------------------------------------------------------------------------
[2012-04-20 15:55:53] thegreatall at gmail dot com

Description:
------------
As I am sure many of you know of the create_function() function, but this 
actually creates a named function in the global scope. This can be undesirable 
if a user is creating an unknown number of functions because it fills memory 
with named execution points but once the variable looses it's references it 
should be cleaned up by the garbage collector.

I am asking for a create_closure() function to do the same thing that 
create_function does, but return a closure instead of a string containing the 
name to a newly created named function.

You can simulate a function like this using eval, but we all know the evils of 
eval.

An example of why someone would like to do this:
A developer creates a framework which handles classes to records in the 
database. When records get updated/created/pulled it has a "hooks" on the 
record 
level that allows custom "hooks" to be installed on the record and executed on 
the specific records. The code for the hook is not accessible/modifiable by the 
user only the developers that have database access, but each user may install 
that hook on a specific record. So if we had a hook that IMs users when 
specific 
records are modified in the database and 5000 users want this hook installed on 
that record it installs 5000 hooks on this record and creates 5000 named 
functions but each function would only be executed once and can/should be 
cleaned by the garbage collector. (I know there is a more optimal way to 
achieve 
this specific example, but if I need to change the list of arguments it has to 
recompile the function creating a new named function. This is not an issue with 
closures because they are not named functions and the garbage collector cleans 
them up after they are de-referenced.

Test script:
---------------
<?php
// Example 1
function create_fn($i){
        return eval('return function ($g){
                echo "'.$i.' - $g\n";
        };');
}
for($i=0;$i<100000;$i++){
        $fn = create_fn($i);
        if($i % 10000 == 0)
                $fn(memory_get_usage(true));
}


<?php
// Example 2
function create_fn($i){
        return function ($g) use ($i){
                echo "$i - $g\n";
        };
}
for($i=0;$i<100000;$i++){
        $fn = create_fn($i);
        if($i % 10000 == 0)
                $fn(memory_get_usage(true));
}


<?php
// Example 1
function create_fn($i){
        return create_function('$g', 'echo "'.$i.' - $g\n";');
}
for($i=0;$i<100000;$i++){
        $fn = create_fn($i);
        if($i % 10000 == 0)
                $fn(memory_get_usage(true));
}

Expected result:
----------------
Result 1: (slower than 2, does NOT snowball memory)
count - memory
-----------------------
0 - 262144
10000 - 4194304
20000 - 4194304
30000 - 4194304
40000 - 4194304
50000 - 4194304
60000 - 4194304
70000 - 4194304
80000 - 4194304
90000 - 4194304

Result 2: (really fast consumes very little memory)
count - memory
-----------------------
0 - 262144
10000 - 262144
20000 - 262144
30000 - 262144
40000 - 262144
50000 - 262144
60000 - 262144
70000 - 262144
80000 - 262144
90000 - 262144


Result 3:
count - memory (slow and consumes tons of memory and snowballs memory)
-----------------------
0 - 262144
10000 - 8126464
20000 - 16515072
30000 - 24641536
40000 - 31981568
50000 - 39583744
60000 - 47185920
70000 - 54525952
80000 - 62128128
90000 - 69730304



------------------------------------------------------------------------



-- 
Edit this bug report at https://bugs.php.net/bug.php?id=61790&edit=1

Reply via email to