From:             
Operating system: N/A
PHP version:      Irrelevant
Package:          *Programming Data Structures
Bug Type:         Feature/Change Request
Bug description:Feature Request for create_closure() function

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 bug report at https://bugs.php.net/bug.php?id=61790&edit=1
-- 
Try a snapshot (PHP 5.4):            
https://bugs.php.net/fix.php?id=61790&r=trysnapshot54
Try a snapshot (PHP 5.3):            
https://bugs.php.net/fix.php?id=61790&r=trysnapshot53
Try a snapshot (trunk):              
https://bugs.php.net/fix.php?id=61790&r=trysnapshottrunk
Fixed in SVN:                        
https://bugs.php.net/fix.php?id=61790&r=fixed
Fixed in SVN and need be documented: 
https://bugs.php.net/fix.php?id=61790&r=needdocs
Fixed in release:                    
https://bugs.php.net/fix.php?id=61790&r=alreadyfixed
Need backtrace:                      
https://bugs.php.net/fix.php?id=61790&r=needtrace
Need Reproduce Script:               
https://bugs.php.net/fix.php?id=61790&r=needscript
Try newer version:                   
https://bugs.php.net/fix.php?id=61790&r=oldversion
Not developer issue:                 
https://bugs.php.net/fix.php?id=61790&r=support
Expected behavior:                   
https://bugs.php.net/fix.php?id=61790&r=notwrong
Not enough info:                     
https://bugs.php.net/fix.php?id=61790&r=notenoughinfo
Submitted twice:                     
https://bugs.php.net/fix.php?id=61790&r=submittedtwice
register_globals:                    
https://bugs.php.net/fix.php?id=61790&r=globals
PHP 4 support discontinued:          
https://bugs.php.net/fix.php?id=61790&r=php4
Daylight Savings:                    https://bugs.php.net/fix.php?id=61790&r=dst
IIS Stability:                       
https://bugs.php.net/fix.php?id=61790&r=isapi
Install GNU Sed:                     
https://bugs.php.net/fix.php?id=61790&r=gnused
Floating point limitations:          
https://bugs.php.net/fix.php?id=61790&r=float
No Zend Extensions:                  
https://bugs.php.net/fix.php?id=61790&r=nozend
MySQL Configuration Error:           
https://bugs.php.net/fix.php?id=61790&r=mysqlcfg

Reply via email to