Login   Register  
PHP Classes
elePHPant
Icontem

File: pClosure_test.php

Recommend this page to a friend!
Stumble It! Stumble It! Bookmark in del.icio.us Bookmark in del.icio.us
  Classes of Sam Shull  >  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: 5 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 implements CountablepClosureContext
{
    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("");

?>