PHP Doku:: Erzeugen einer anonymen / temporären (Lambda-Stil) Funktion - function.create-function.html

Verlauf / Chronik / History: (1) anzeigen

Sie sind hier:
Doku-StartseitePHP-HandbuchFunktionsreferenzVariablen- und typbezogene ErweiterungenFunction HandlingFunction handling Funktionencreate_function

Ein Service von Reinhard Neidl - Webprogrammierung.

Function handling Funktionen

<<call_user_func

forward_static_call_array>>

create_function

(PHP 4 >= 4.0.1, PHP 5)

create_function Erzeugen einer anonymen / temporären (Lambda-Stil) Funktion

Beschreibung:

string create_function ( string $args , string $code )

Erzeugt eine anonyme Funktion an Hand der übergebenen Parameter und gibt einen eindeutigen Namen für diese zurück. Normalerweise sind die args als mit "'" begrenzte Strings zu übergeben. Dies gilt auch für code. Dadurch werden die Variablen vor dem Parsen geschützt. Falls sie """ verwenden, müssen sie die Variablen-Namen "escapen", wie z.B. \$avar.

Dieser Befehl kann z.B. verwendet werden, um eine Funktion an Hand von Informationen zu erzeugen, die erst zur Laufzeit vorliegen.

Beispiel #1 Erzeugen einer anonymen / temporären Funktion per create_function():

$newfunc = create_function('$a,$b','return "ln($a) + ln($b) = ".log($a * $b);');
echo "Neue Temp-Funktion: $newfunc\n";
echo $newfunc(2,M_E)."\n";
// Ausgabe:
// Neue Temp-Funktion: lambda_1
// ln(2) + ln(2.718281828459) = 1.6931471805599
Sie können auch eine allgemeine Handhabungs-Funktion erstellen, die einen mehr oder weniger große Anzahl an Operationen mit einer Liste von Parametern durchführt.

Beispiel #2 Beispiel zum o.a. Verwendungszweck:

function process($var1, $var2, $farr) {
    for ($f=0; $f < count($farr); $f++)
        echo $farr[$f]($var1,$var2)."\n";
}

// Erzeugung eines Bündels an mathematischen Funktionen
$f1 = 'if ($a >=0) {return "b*a^2 = ".$b*sqrt($a);} else {return false;}';
$f2 = "return \"min(b^2+a, a^2,b) = \".min(\$a*\$a+\$b,\$b*\$b+\$a);";
$f3 = 'if ($a > 0 && $b != 0) {return "ln(a)/b = ".log($a)/$b;} else {return false;}';
$farr = array(
    create_function('$x,$y', 'return "als trig: ".(sin($x) + $x*cos($y));'),
    create_function('$x,$y', 'return "als Hypotenuse: ".sqrt($x*$x + $y*$y);'),
    create_function('$a,$b', $f1),
    create_function('$a,$b', $f2),
    create_function('$a,$b', $f3)
    );

echo "\nGebrauch des ersten Arrays der anonymen Funktionen\n";
echo "Parameter: 2.3445, M_PI\n";
process(2.3445, M_PI, $farr);

// Erzeugung eines Bündels an String-Behandlungs-Routinen
$garr = array(
    create_function('$b, $a','if (strncmp ($a, $b, 3) == 0) return "** \"$a\" '.
        'und \"$b\"\n** Sieht für mich gleich aus! (ansehen der ersten 3 Zeichen)";'),
    create_function('$a, $b','; return "CRCs: ".crc32($a)." , ".crc32(b);'),
    create_function('$a, $b','; return "ähnlich(a, b) = ".similar_text($a, $b, &$p)."($p%)";')
    );
echo "\nGebrauch des zweiten Arrays der anonymen Funktionen\n";
process("Twas brilling and the slithy toves", "Twas the night", $garr);
wenn sie nun den o.a Code ausführen lassen, wird folgendes ausgegeben :
Gebrauch des ersten Arrays der anonymen Funktionen
Parameter: 2.3445, M_PI
als trig: -1.6291725057799
als Hypotenuse: 3.9199852871011
b*a^2 = 4.8103313314525
min(b^2+a, a^2,b) = 8.6382729035898
ln(a/b) = 0.27122299212594

Gebrauch des zweiten Arrays der anonymen Funktionen
** "Twas the night" und "Twas brilling and the slithy toves"
** Sieht für mich gleich aus! (ansehen der ersten 3 Zeichen)
CRCs: -725381282 , 1908338681
ähnlich(a,b) = 11(45.833333333333%)
	    
Möglicherweise liegt der häufigste Anwendungsfall für Funktionen im Lambda-Stil (anonym) bei den Callback-Funktionen, also z.B. beim Gebrauch von array_walk() oder usort().

Beispiel #3 Gebrauch der anonymen Funktionen als Callback-Funktion:

$av = array("der ","ein ","dieser ","jener ");
array_walk($av, create_function('&$v,$k','$v = $v."Zug";'));
print_r($av);  // mit PHP3 benutzen sie bitte var_dump()
// Ausgaben:
// Array
// (
//     [0] => der Zug
//     [1] => ein Zug
//     [2] => dieser Zug
//     [3] => jener Zug
// )

// Ein Array aus Strings nach Länge geordnet
$sv = array("kurz","länger","noch länger","dieser ist am längsten");
print_r($sv);
// Ausgaben:
// Array
// (
//     [0] => kurz
//     [1] => länger
//     [2] => noch länger
//     [3] => dieser ist am längsten
// )

// Sortierung von lang nach kurz
usort($sv, create_function('$a,$b','return strlen($b) - strlen($a);'));
print_r($sv);
// Ausgabe:
// Array
// (
//     [0] => dieser ist am längsten
//     [1] => noch länger
//     [2] => länger
//     [3] => kurz
// )


33 BenutzerBeiträge:
- Beiträge aktualisieren...
sezer
3.01.2011 10:25
This function creates lambda_xx function at global namespace (\) even if you are in a specific namespace.

Namespace aa;
create_function() > function is in still global space

So your function should also include all other functions and constants as aa\xxx() and there is no way to create in current namespace as of 5.3.3
phenno7 [a_t] yahoo dot com
15.09.2010 22:53
The function takes as arguments the tree array, the category id on which i want the retrieval, and the depth level for which i would like the subcategories ids returned.

this saves me a LOT of time on large adjacency list trees.

<?php
$ctg_tree
= array(
'1'=>array('parent_id'=>0,
          
'children'=>array(
         
'2'=>array('parent_id'=>1,
                     
'children'=>array(
                     
'3'=>array('parent_id'=>2))),
          
'4'=>array('parent_id'=>1,
                     
'children'=>array(
                     
'5'=>array('parent_id'=>4),
                     
'6'=>array('parent_id'=>4))))));

function
getSubCategories($ctg_tree, $id, $level = null) {
                               
       
$getBranchIds =
create_function(
'$tree, $ctg_id, $level = null, $arr = null,'.
' $push = false, $getBranchIds','
            if(!$arr) {
                $arr = array();
            }
            if(intval($level) && $push){
                $level--;
            }

            foreach($tree as $key=>$ctg) {
                if($push) {
                    $arr[] = $key;
                }
                if($ctg_id == $key) {
                    $start = true;
                    $push = true;
                }
if(count($ctg[\'children\']) && (intval($level) || $level === null)) {
$getBranchIds(
$ctg[\'children\'],$ctg_id,$level,&$arr,$push,$getBranchIds
);
                }
                if($start) return $arr;
            }

            return $arr;'
);

return
$getBranchIds(
$ctg_tree, $id, $level, null, false, $getBranchIds
);
    }

print_r(getSubCategories($ctg_tree, 4, 1));
?>

Array
(
    [0] => 5
    [1] => 6
)

print_r(getSubCategories($ctg_tree, 1, 1));

Array
(
    [0] => 2
    [1] => 4
)

<?php
print_r
(getSubCategories($ctg_tree, 1));
?>

Array
(
    [0] => 2
    [1] => 3
    [2] => 4
    [3] => 5
    [4] => 6
)
Its Will
1.09.2010 17:27
If you create a function that will only be used from an object context (i.e. you want a dynamic method that can then call methods from the original object, still maintaining access to the object's runtime values) then you can use the following functions I have created (ob_lambda_func and ob_lambda) to enable the dynamic function to easily call *public* methods on the object, in their runtime contexts:

<?php
/* the OB Lambda functions allow a lambda function to call a method from its callee's object */
if(!function_exists('ob_lambda_func')){
function
ob_lambda_func($method, $args) {
   if((
phpversion()+0)<5.1 || (substr(phpversion(),2)+0)<1.1)
       die(
"\nError: This script requires PHP v5.1.1+!\n");
  
$bt=debug_backtrace();
   foreach(
$bt as $xsp) {
       if(isset(
$xsp['object'])) {
           if(!
method_exists($xsp['object'], $method)) continue;
           return
call_user_func_array(array($xsp['object'], $method), $args);
       }
   }
   if(!
function_exists($method))
       die(
"\nOB: Internal Error! ($method)");
   return
call_user_func_array($method, $args);
}}
if(!
function_exists('ob_lambda')){
function
ob_lambda($method) {
   return
create_function('','$args=func_get_args(); return ob_lambda_func('.var_export($method, true).',$args);');
}}

/* Usage:
 *   For each callable method, store the results of ob_lambda('method_name')
 *   When a lambda function you call wants to access one of these methods,
 *    you need to pass it the result of ob_lambda for that method, the easiest
 *    way is to have one of the lambda functions arguments accept the result
 *       i.e.:  $myFunc=ob_lambda('myMethod');
 *              $lf1=create_function('$func', '$func( ... args ... )');
 *              $lf1($myFunc);
 *    because create_function prepends a \0 to the function name, it is difficult
 *    to pass the result of ob_lambda to the target function without using an argument
 */
/* here is an example -- lambda function Foo::test can call Foo::Bar and Foo::Baz, and these  */
class Foo {
    private
$bar, $baz, $test;
    private
$runtimeValue=0;
    function
__construct() {
       
$this->runtimeValue=rand();
       
$this->bar=ob_lambda('Bar');
       
$this->baz=ob_lambda('Baz');
       
$this->test=create_function(
           
'$bar, $baz',
           
'$bar("Hello, World!"); $baz();'
       
);
    }
    function
Test() {
       
$fn=$this->test;
       
$fn($this->bar, $this->baz);
    }
    function
Bar($a) {
        echo
"$a: Bar ($this->runtimeValue)\n";
    }
    function
Baz() {
        echo
"and another! Baz ($this->runtimeValue)\n";
    }
}

$foo=new Foo();
// Foo::Bar("Testing Other Method"); <-- this causes fatal error
//  (using $this when not in object context)
$foo->Test();

?>

This snippet (with test) shows how the lambda function $foo->test can call Foo::Bar and Foo::Baz without an explicit reference to the original object. The methods are run from their object context, and so can access the runtime-modified variable $foo->runtimeValue, which is set to a random number on construction.
The function definition for $foo->test is the following:
function ($bar, $baz) {
    $bar("Hello, World!");
    $baz;
}
As you can see, it is clean and simple, with no obvious artifacts from the use of OB Lambda

The expected output should be:
Hello, World!: Bar (440048505)
and another! Baz (440048505)

Or any other random number in place of 440048505
Make sure, before you change your code, that your target server has PHP 5.1.1+, or these functions won't work and will return an error!
Hope this helps anyone as much as it has me! :)
julius _email _me _at grantzau _dot _com
16.07.2010 18:59
To avoid memory problems, when creating a dynamic function within loops, register it as a global variable, and check if it has already been set;

<?php
global $my_func;
if (!isset(
$my_func))
{
   
$my_func = create_function($args, $code);
}

$my_func();
?>

That way you don't end up creating the same function twice (or a couple of million of times, as it happened to me...)
v dot churakov at i2d dot ru
20.02.2010 13:56
<?

function is_function( &$mixed )
{
    if (
is_object( $mixed ) ) {
        return (
$mixed instanceof Closure );
    } elseif(
is_string( $mixed ) ) {
        return
function_exists( $mixed );
    } else {
        return
false;
    }
}

function
myfunc(){}

$test = 123;
echo 
is_function( $test ); //will return false

$test = 'isset';
echo 
is_function( $test ); //will return false... it's not work with reserved :( ...

$test = 'myfunc';
echo 
is_function( $test ); //will return true

$test = create_function( '', 'echo 123;' );
echo 
is_function( $test ); //will return true

$test = function () { echo 123; };
echo 
is_function( $test ); //will return true

?>
edgar at goodforall dot eu
2.07.2009 16:45
Just a little toy I thought up, I would like to share. Creates an anonymous function, which let you use a class  as a function.

In php 5.3 there is support for real functors  (trough __invoke):

<?php
function createFunctor($className){
       
$content = "
                static \$class;
                if(!\$class){
                        \$class = new
$className;
                }
                return \$class->run(\$args);
        "
;
       
$f = create_function('$args', $content);
        return
$f;

}
class
test {
        public function
run($args){
                print
$args;
        }
}
$test = createFunctor('test');
$test('hello world');
?>
Stefan Scheld
23.09.2008 16:48
Workaround is as follows:

<?php
class Foo {
    function
setHandler($handlerName, $handlerCode) {
       
$this->handlerFunctions[$handlerName] = create_function('&$self, $dataArr', $handlerCode);
// NOTE: $this not allowed here, using $self as replacement
   
}

    function
executeHandler($handlerName, $dataArr) {
        if(
$this->handlerFunctions[$handlerName]) {
               
$this->handlerFunctions[$handlerName](&$this, $dataArr);
            }
     }

    function
getConstantInfo($what) {
        return(
$what);
    }
}

$bla = new Foo;

$bla->setHandler("load", 'echo($self->getConstantInfo("name")."\n");');
$bla->executeHandler("load", array("foo" => "bar"));
?>
neo at nowhere dot com
28.08.2008 10:56
In response to kkaiser at revolution-records dot net's note, even tho PHP will allow you to use
<?
$myfunc
= create_function('$this', $code);
?>
You can NOT use a reference to "$this" inside of the anonymous function, as PHP will complain that you are using a reference to "$this" in a non-object context.

Currently, I have not found a work-around for this...
Alan FUNG
7.08.2008 9:24
$f = create_function('','echo "function defined by create_function";');
$f();

result:
function defined by create_function

You may define no return in function body while you are using create_function.
Rene Saarsoo
6.02.2008 11:31
Here has been some discussion about the "memory leak" create_function() can create.

What create_function() actually does, is creating an ordinary function with name chr(0).lambda_n where n is some number:

<?php
$f
= create_function('', 'return 1;');

function
lambda_1() { return 2; }

$g = "lambda_1";
echo
$g(); // outputs: 2

$h = chr(0)."lambda_1";
echo
$h(); // outputs: 1
?>
colin dot mckinnon at gmail dot com
20.08.2007 14:51
In response to koyama at hoge dot org (14-Dec-2000):

This does NOT create a new method - try adding this at the end:

<?php
if (function_exists($h->lamda)) {
   print
"Its a function\n";
} else {
   print
"No it isnt";
}
?>

It creates a function which $h->lamda points to.

Under PHP4 you could simply add an argument $this which meant it *behaved* like a method (though it existed in global scope) but with PHP5, you can't have a variable named $this in a function (which is rather irksome).

(and methinks the ant-bot challenge is taking the mickey - min(three, four)?  !).
TSE-WebDesign
18.08.2007 18:55
Here's how to call a runtime-created function from another runtime-created function:
<?php
        $get_func
= create_function('$func', 'return substr($func,1);');
       
$get_value = create_function('$index','return pow($index,$index);');
       
$another_func = create_function('$a', '$func="\x00"."'.$get_func($get_value).'";return $func($a);');
        echo
$another_func(2); # result is 4
?>
kkaiser at revolution-records dot net
13.04.2007 22:10
In the process of migrating a PHP4 codebase to PHP5, I ran into a peculiar problem. In the library, every class was derived from a generic class called 'class_container'. 'class_container' contained an array called runtime_functions and a method called class_function that was as follows:

<?php
function class_function($name,$params,$code) {

 
$this->runtime_functions[$name] = create_function($params,$code);

}
?>

In a subclass of class_container, there was a function that utilized class_function() to store some custom lambda functions that were self-referential:

<?php
function myfunc($name,$code) {

 
$this->class_function($name,'$theobj','$this=&$theobj;'.$code);

}
?>

In PHP4, this worked just fine. The idea was to write blocks of code at the subclass level, such as "echo $this->id;", then simply $MYOBJ->myfunc("go","echo $this->id;"); and later call it like $MYOBJ->runtime_functions["go"]();

It essentially worked exactly like binding anonymous functions to objects in Javascript.

Note how the "$this" keyword had to be manually redefined for the $code block to work.

In PHP5, however, you can't redeclare $this without getting a fatal error, so the code had to be updated to:

<?php
function myfunc($name,$code) {

 
$this->class_function($name,'$this',$code);

}
?>

Apparently create_function() allows you to set $this via a function argument, allowing you to bind anonymous functions to instantiated objects. Thought it might be useful to somebody.
a dot steenveld at id dot umcn dot nl
18.01.2007 15:18
It is possible to use this call to implement continuations but you need a small workaround for a nagging feature of create_function(). The result of this function does start with a null character which might result in loosing the name of your function altogether!. (See also bug report #40160)

Here is a bit of code to play with. The result should be 'f(2, 2) = 6'
<?php
/* continuations in php.
   vim:nu

   Code inspired by http://www.ps.uni-sb.de/~duchier/python/continuations.html
*/

function writeln($s) { echo "$s\n"; }

function
lambda0 ($args, $code)
    { return
substr(create_function ($args, $code), 1);
    }
function
L ($l)
    { if (
strncmp($l, 'lambda_', 7) === 0) return "\0$l";
      else return
$l;
    }
   
function
mul ($x, $y, $c) { $f = L($c); $f($x*$y); }
function
add ($x, $y, $c) { $f = L($c); $f($x+$y); }
function
mal ($x, $y, $c) { mul(2, $x, lambda0 ('$v', "add(\$v, $y, $c);")); }

function
f($x, $y)
    {
mal($x, $y, lambda0 ('$v', "writeln(\"f($x, $y) = \$v\");"));
    }   

   
f(2, 2);
?>
Dan D
24.10.2006 4:22
Beware when using anonymous functions in PHP as you would in languages like Python, Ruby, Lisp or Javascript.  As was stated previously, the allocated memory is never released; they are not objects in PHP -- they are just dynamically named global functions -- so they don't have scope and are not subject to garbage collection.

So, if you're developing anything remotely reusable (OO or otherwise), I would avoid them like the plague.  They're slow, inefficient and there's no telling if your implementation will end up in a large loop.  Mine ended up in an iteration over ~1 million records and quickly exhasted my 500MB-per-process limit.
Phlyst
6.10.2006 14:10
In reply to info at adaniels dot nl:

You may not be able to use __FUNCTION__ in a lambda (thanks for pointing it out; I was having that problem just now), but you can use $GLOBALS to work around it if you're assigning the function to a variable. I reimplemented array_walk_recursive() in PHP4 like this:

<?php
$array_walk_recursive
= create_function('&$array, $callback',
   
'foreach($array as $element) {
        if(is_array($element)) {
            $funky = $GLOBALS["array_walk_recursive"];
            $funky($element, $callback);
        }
        else {
            $callback($element);
        }
    }'
);
?>
Josh J
27.09.2006 21:45
In regards to the recursion issue by info at adaniels dot nl

Anon function recursion by referencing the function variable in the correct scope.
<?php
$fn2
= create_function('$a', 'echo $a; if ($a < 10) call_user_func($GLOBALS["fn2"], ++$a);');
$fn2(1);
?>
info at adaniels dot nl
11.05.2006 0:42
Note that using __FUNCTION__ in a an anonymous function, will always result '__lambda_func'.

<?php
    $fn
= create_function('', 'echo __FUNCTION__;');
   
$fn();
   
// Result: __lambda_func
   
echo $fn;
   
// Result: ºlambda_2 (the actual first character cannot be displayed)
?>

This means that a anonymous function can't be used recursively. The following code (recursively counting to 10) results in an error:
<?php
    $fn2
= create_function('$a', 'echo $a; if ($a < 10) call_user_func(__FUNCTION__, $a++);');
   
$fn2(1);
   
// Warning: call_user_func(__lambda_func) [function.call-user-func]: First argument is expected to be a valid callback in T:/test/test.php(21) : runtime-created function on line 1
?>
josh at janrain dot com
3.03.2006 19:21
Beware! This is merely a convenience function that generates a unique name for a regular function. It is *not* a closure or even an anonymous function. It is just a regular function that gets named for you.
Joshua E Cook
20.01.2006 1:43
Functions created by create_function() cannot return a value by reference.  The function below creates a function that can.  The arguments are the same as create_function().  Note that these arguments are passed, unmodified, to eval(), so be sure that data passed in is sanitized.

<?php
/**
 * create_ref_function
 * Create an anonymous (lambda-style) function
 * which returns a reference
 * see http://php.net/create_function
 */
function
create_ref_function( $args, $code )
{
    static
$n = 0;

   
$functionName = sprintf('ref_lambda_%d',++$n);
   
   
$declaration = sprintf('function &%s(%s) {%s}',$functionName,$args,$body);
   
    eval(
$declaration);
   
    return
$functionName;
}
?>
boards at gmail dot com
31.12.2005 20:18
If you were checking to see if a function is made properly, this would be a better way of checking:

<?php
$fnc
= @create_function('$arg1,$arg2,$arg3', 'return true;');
# make that function whatever you want
if (empty($fnc)) {
  die(
'Could not create function $fnc.');
}

# although, the follow will NOT work
if (empty(create_function('$arg', 'return $arg;'))) {
  die(
'Could not create anonymous function.');
}
# you would get an error regarding not being able to use a
# return value in writeable context (i.e. a return value is
# a const in C, and the function empty() doesn't use a
# const void* parameter
?>
david [at] davelee.com.au
13.04.2005 11:15
<?php
# dynamically create html helper functions which take the args
# $string_contents, $optional_hash_of_options
# and return the contents wrapped in a tag
   
$html_funcs = Array(
   
'table',
   
'tr',
   
'th',
   
'td',
   
'div',
   
'span',
   
'pre',
   
'strong',
   
'em'
);
$args = '$html, $options=Array()';
$code = '
  $o = "";
  foreach ($options as $a => $b) {
    $o .= " $a=\"$b\"";
  }
  return "<$tag$o>$html</$tag>";
'
;
foreach (
$html_funcs as $key => $tag) {
    ${
$tag} = create_function($args, "\$tag = '$tag'; $code");
}

# usage example:

print $table(
 
$tr($th('heading').$td('this is the cell content')),
  Array(
'style'=>'border: 1px solid silver;')
);
?>
endofyourself at yahoo dot com
7.10.2004 9:17
You really should avoid using this as well as you should avoid using eval(). Not only will there be a performance decrease but can it lead to obfuscation and bad coding habits. There is almost always an alternative solution to self modifying code.
MagicalTux at FF.ST
9.03.2004 19:25
neo at gothic-chat d0t de wrote :
Beware of memory-leaks, the garbage-collection seems to 'oversee' dynamically created functions!

Not really...

In fact, PHP can not "unassign" functions. So if you create a function, it won't be deleted until the end of the script, even if you unset the variable containing its name.

If you need to change a part of a function everytime you run a loop, think of a way to make a more general function or try using eval :) (functions are made to be re-used. If you need to run your own piece of code once, eval is much better).
neo at gothic-chat d0t de
21.01.2004 5:54
Beware of memory-leaks, the garbage-collection seems to 'oversee' dynamically created functions!

I used a function like this to replace special characters in links with their htmlentities:
<?php
$text
= preg_replace_callback (
   
"/(<(frame src|a href|form action)=\")([^\"]+)(\"[^>]*>)/i",
   
create_function (
       
'$matches',
       
'return $matches[1] . htmlentities ($matches[3]) . $matches[4];'
   
),
   
$text);
?>

After 1000 calls, the process used about 5MB more than before. In my situation this boosted up the memory-size of one PHP-process up to over 100MB!

In such cases, better store the function in a global variable.
nospam at fiderallalla dot de
8.08.2003 15:39
Sometimes it may be useful to create functions in a dynamic environment
(f. e. in a daemon-like php script).

Normally declaring a function must be done once, which results in the problem,
that in this special case modifying a function wouldn't have an effect until the script is reloaded.

Maybe this code snipplet is useful 4 u.

File: "functions.inc"

<?php
function test($str) {
    echo
$str;
}
?>

Dynamic FunctionHandler:

<?php
$FileName
= "functions.inc";
$FileHandle = fopen($FileName,"r");
$FileContent = fread($FileHandle,filesize($FileName));
fclose($FileHandle);

preg_match_all("#function\ ?([a-zA-Z0-9-_]*)\ ?\((.*?)\)\ ?\{(.*?)\}#mixse",$FileContent,$Matches);
if (
is_array($Matches) && isset($Matches[0]) && count($Matches[0]) > ) {
     foreach (
$Matches[0] as $key=>$val ) {
        $
$Matches[1][$key] = create_function($Matches[2][$key],$Matches[3][$key]);
    }
}
?>

The Test:
<?php echo $test("test"); ?>
.. will echo "test";

Hans Kuhlen
DB on music_ml at yahoo dot com dot ar
2.04.2003 14:58
[EDIT by danbrown AT php DOT net: Combined user-corrected post with previous (incorrect) post.]

You can't refer to a class variable from an anonymous function inside a class method using $this.  Anonymous functions don't inherit the method scope.  You'll have to do this:

<?php
class AnyClass {
 
 var
$classVar = 'some regular expression pattern';

 function
classMethod() {

  
$_anonymFunc = create_function( '$arg1, $arg2', 'if ( eregi($arg2, $arg1) ) { return true; } else { return false; } ' );

  
$willWork = $_anonymFunc('some string', $classVar);
 
 }

}
?>
listes at brissambre dot org
14.08.2002 19:22
[Editor's note: Only regular variables are serialized (scalars, arrays, objects), and as lambda functions are not stored as any of those types, it is not saved during session serialization.]

Warning, it seems that you can't store such lambda functions in Sessions, because only the function's name will be stored, not the function itself.
So don't save the function but only it's code and call create_function each time the script is called.
ben-php at bacarisse dot btinternet dot co dot uk
26.07.2001 22:33
A nice technique for building complex search patterns on lists, files or whatever is to build function combining functions like this:

<?php
function _not_($f) {
  return
create_function('$x',
   
"return !$f(\$x);");
}

function
_and_($f, $g) {
  return
create_function('$x',
   
"return $f(\$x) && $g(\$x);");
}
?>

(similarly for _or_ and others...).  Once you've built your matching primitives you can then build more complex matches into your script.

Unfortunately, as explained in (closed) bug #10721, the function names returned by create_function have a null byte at the front and this causes a parse error.

You can fix the definition like this:

<?php
function _not_($f) {
 
$f = substr($f, 1);
  return
create_function('$x',
   
"return !call_user_func(chr(0).'$f', \$x)");
}
?>

The expression that re-builds the function name avoid the null being literally in the parsed string.  If there is a better fix, please let me know.
x-empt[a_t]ispep.cx
5.07.2001 20:41
Create_function enables the ability to change the scope of functions.  You might have a class where it needs to define a GLOBAL function.  This is possible, like:

<?php
       
class blah {
                function
blah() {
                       
$z=create_function('$arg1string','return "function-z-".$arg1string;');
                       
$GLOBALS['z']=$z;
                }
        }
       
$blah_object=new blah;

       
$result=$GLOBALS['z']('Argument 1 String');
        echo
$result;
?>

Making a function escape it's defined scope can be useful in many situations.
maxim at maxim dot cx
28.04.2001 0:26
for those who want to assign it's own name to a function consider this code:

<?php
$fname
= 'hello';

$func = sprintf('
    function %s($v="") {
        Return "$v<BR>";
    }
'
,
$fname
);

eval(
$func);
echo
$fname('Please print it.... please....');
?>

what it does is,
: Creats a function as a string;
: Replaces the function name with $fname value;
: Converts the string into a REAL php code with eval()
: Calls the function using the variable function as declared before ($fname);

Simple, isn't it?

Can work well as an abstraction layer for portability and/or compatibility purposes

Maxim Maletsky
maxim@maxim.cx // PHPBeginner.com
mrben at free dot fr
21.02.2001 5:33
Here is another tricky but usefull techynote, good for adding "plugin" to a existing class :

<?php

class Hoge {
    var
$lamda;
    var
$text;

    function
set($lamda)
    {
       
$this->lamda = $lamda;
    }

    function
callLamda()
    {
       
$func = $this->lamda;
        return
$func($this);
    }

    function
get()
    {
        return
$this->text;
    }
}

$newfunc = create_function('&$class', 'echo $class->get();' );

$h = new Hoge;
$h->text = "Hi there !";
$h->set($newfunc);
$h->callLamda();

?>
koyama at hoge dot org
14.12.2000 13:22
How do you use function which is created by create_function() as class method?

<?php
class Hoge {
  var
$lamda;
  function
set($lamda) {
   
$this->lamda = $lamda;
  }
  function
callLamda() {
   
$func = $this->lamda;
    return
$func();
  }
}

$newfunc = create_function('', 'echo "hoge<br>\n";');

$h = new Hoge;
$h->set( $newfunc );
$h->callLamda();
?>

It works fine. :-)



PHP Powered Diese Seite bei php.net
The PHP manual text and comments are covered by the Creative Commons Attribution 3.0 License © the PHP Documentation Group - Impressum - mail("TO:Reinhard Neidl",...)