PHP Classes

File: pClosure_test.php

Recommend this page to a friend!
  Classes of Sam S   pClosure   pClosure_test.php   Download  
File: pClosure_test.php
Role: Example script
Content type: text/plain
Description: A series of example uses.
Class: pClosure
Create closure functions for any PHP 5 version
Author: By
Last change:
Date: 15 years ago
Size: 4,806 bytes
 

Contents

Class file image Download
<?php

require_once 'pClosure.php';

//you have to go back 4 levels to actually get to where the code was that caused the error :(
//set_error_handler(pClosure::createFunction('$errno, $errstr, $errfile, $errline', '$debug = debug_backtrace(); print "\n\nError triggered on line {$debug[3][\'line\']}";'));

class A implements Countable, pClosureContext
{
    const
INTEGER_TEST = 256;
   
    private
$methods = array(), $int = 23;
   
    public function
__call($name, array $args)
    {
       
//execute the closure's code with the context of this instance
       
if (isset($this->methods[$name]) && $this->methods[$name] instanceof pClosure)
        {
            return
$this->methods[$name]->apply($this, $args);
        }
    }
   
    public function
callClosure(pClosure $__closure__, array $__args__)
    {
       
$__returnValue__ = null;
       
       
extract($__args__, EXTR_OVERWRITE | EXTR_REFS);
       
        try{
           
//evaluate the code in this context
           
$__returnValue__ = eval(preg_replace(pClosure::FUNC_GET_ARGS, '\\1$__args__;', $__closure__->code) . ' return null;');
        }
        catch (
Exception $e)
        {
           
$etype = get_class($e);
           
//throw a new Exception, that contains backtrace info
           
throw new $etype(
                       
$e->getMessage() .
                           
" and defined in '{$__closure__->trace[0]['file']}' on line {$__closure__->trace[0]['line']} : runtime-created closure",
                       
$e->getCode()
            );
        }
       
        return
$__returnValue__;
    }
   
    public function
__get ($name)
    {
        return
$this->methods[$name];
    }
   
    public function
__set ($name, $value)
    {
       
//use this to add closures to be executed in __call
       
$this->methods[$name] = $value;
    }
   
   
//implements Countable
   
public function count ()
    {
        return
12;
    }
}

$instanceOfA = new A;

//add a method to the object to be executed in scope
$instanceOfA->test = new pClosure('', 'if (isset($secondaryProperty)) print $secondaryProperty; print "Access the private variable \$this->int = {$this->int}";');

echo
"\n\nThe output of \$instanceOfA->test(): ", $instanceOfA->test();

$instanceOfA->test->secondaryProperty = 'NOTICE: the $secondaryProperty is now in the scope. ';

//create a closure that will take the object as an additional parameter
$test1 = pClosure::createClosure('', 'echo "\n\nThe output of \$x->test() which is an additional param of the closure: ", $x->test();',
                            array(
'x' => $instanceOfA));

$test2 = pClosure::createClosure('string &$string', '$string = "new value";');

$test3 = pClosure::createClosure('stdClass $a', 'echo "\n\nclass name of \$a in \$test3 = ", get_class($a);');

//$instanceOfA will pass checks for Countable, A, and object
$test4 = pClosure::createClosure('object $a', 'echo "\n\ntypeof \$a in \$test4 = ", gettype($a);');

$alsoPassedByReference = 34;

$returnVal = null;

//this closure takes two additional arguments (alsoPassedByReference and top) which will be extracted into the function context
$test5 = pClosure::createClosure('$d', '$alsoPassedByReference = 56; echo "\n\ntypeof \$d in \$test5 = ", gettype($d); $top = "\$test5 called";',
                            array(
'alsoPassedByReference' => &$alsoPassedByReference, 'top' => &$returnVal));

//
$test6 = pClosure::createClosure('$a = 0xFF, array $b=array(), stdClass $e = null', 'echo "\n\n\$a = $a ", "typeof \$e = ", gettype($e);');

//$instanceOfA will pass checks for Countable, A, and object
$test7 = pClosure::createClosure('Countable $a', 'echo "\n\n\$a in \$test7 implements Countable: ", count($a);');

$test8 = pClosure::createClosure('$a = A::INTEGER_TEST', 'echo "\n\n\$a in \$test8 = ", $a;');

$test8();

$test6();

$test1();

$test4($instanceOfA);

$test7($instanceOfA);

print
"\n\n\$alsoPassedByReference before pass by reference as additional parameter: {$alsoPassedByReference}";

$test5(new stdClass);

print
"\n\n\$returnVal after pass by reference: {$returnVal}";

print
"\n\n\$alsoPassedByReference after pass by reference as additional parameter: {$alsoPassedByReference}";

$test3(new stdClass);

$val = "ret";

print
"\n\n\$val before pass by reference: {$val}";

$test2($val);

print
"\n\n\$val after pass by reference: {$val}";

$val = 1;

print
"\n\n\$val set to an integer: {$val}";

print
"\n\nThis next call will trigger an exception because \$test2's first argument must be a string: ";

try{
   
$test2($val);
}
catch(
InvalidArgumentException $e)
{
    echo
"\n\nException triggered because integer was passed for parameter that requires string";
}

print
"\n\nThis next call will trigger an error because \$test5's first argument is required: ";

$test5();

print
"\n\n\$val after pass by reference: {$val}";

print
"\n\nThis next call will trigger a fatal error because \$test2's first argument must be passed by reference: \n";

$test2("");

?>