back to devpro   download
<?php

/** PHP Emulated JavaScript prototype behavior
 * @author  Andrea Giammarchi
 * @site    webreflection.blogspot.com
 * @require runkit PECL extension
 * @license Mit Style
 */
 
 class prototype extends stdClass implements Iterator {

    protected   $_className = '',           // class that will use prototype
                $_methods   = array();      // methods list

    public  function    __construct(
        /* string */    $className,         // assign internal parameter
        /* mixed */     $callbackList = null// optional list of callbacks or prototype to clone
    ){
        if(!class_exists($this->_className = $className))
            throw new Exception('Unable to assign a prototype to class '.$className);
        if($callbackList)
            foreach($callbackList as $name => $callback)
                $this->$name = $callback;
    }

    public  function    __get(
        /* string */    $name               // which prototype method is required
    ){
        return  isset($this->_methods[$name]) ? $this->_methods[$name] : null;
    }

    public  function    __set(
        /* string */    $name,              // which prototype method is being assigned
        array $callback = array()           // method body, or method arguments plus body
    ){
        if(count($callback) < 2)
            array_unshift($callback, '');
        if(
            (
                isset($this->_methods[$name]) &&
                !runkit_method_redefine($this->_className, $name, $callback[0], $callback[1], RUNKIT_ACC_PUBLIC)
            ) ||
                !runkit_method_add($this->_className, $name, $callback[0], $callback[1], RUNKIT_ACC_PUBLIC)
        )
            throw new Exception('Unable to define prototype->'.$name);
        $this->_methods[$name] = $callback;
    }

    public  function    __unset(
        /* string */    $name               // which prototype is being removed
    ){
        if(!runkit_method_remove($this->_className, $name))
            throw new Exception('Unable to remove prototype->'.$name);
        unset($this->_methods[$name]);
    }

    /** Iterator stuff */
    public  function    current(){
        return  current($this->_methods);
    }
    public  function    key(){
        return  key($this->_methods);
    }
    public  function    next(){
        return  next($this->_methods);
    }
    public  function    rewind(){
        return  reset($this->_methods);
    }
    public  function    valid(){
        return  key($this->_methods) !== null;
    }
}

?>
back to devpro   download
Creative Commons License