我在网上看到一篇文章
终于找到了答案
<?php
/**
* @copyright © 2006, Schmalls / Joshua Thompson, All Rights Reserved
* @license http://www.opensource.org/licenses/bsd-license.php New BSD
* @author Joshua Thompson <[email protected]>
* @version 1.0.0
* @link http://www.countercubed.com
*/
/**
* This class holds the prototype capabilities
*
* Extending this class makes it prototype capable
*/
class Prototype
{
/**
* Holds prototype functions
*
* @var array
*/
private $_functions = array();
/**
* Default constructor
*
* This is here so that php doesn't complain about the prototype function
*/
public function __construct()
{
}
/**
* Sets the prototype functions or variables
*
* @param string $name
* @param mixed $value
*/
public function __set( $name, $value )
{
if ( function_exists( $value ) ) :
$this->_functions[$name] = $value;
else :
$this->$name = $value;
endif;
}
/**
* Gets static prototype variables if they exist
*
* @param string $name
* @return mixed
*/
public function __get( $name )
{
if ( isset( $this->prototype()->$name ) ) :
return $this->prototype()->$name;
else :
trigger_error( 'Undefined property: ' . __CLASS__ . '::' . $name, E_USER_NOTICE );
endif;
}
/**
* Calls a static prototype function
*
* @param string $name
* @param array $arguments
* @return mixed
*/
public function __call( $name, $arguments )
{
if ( isset( $this->_functions[$name] ) ) :
return call_user_func_array( $this->_functions[$name], $arguments );
elseif ( $this->prototype()->isCallable( $name ) ) :
return call_user_func_array( array( $this->prototype(), $name ), $arguments );
else :
trigger_error( 'Call to undefined method ' . __CLASS__ . '::' . $name . '()', E_USER_ERROR );
endif;
}
/**
* Returns the static prototype holder
*
* @return Prototype
*/
public static function prototype()
{
static $prototype = null;
if ( $prototype === null ) :
$prototype = new Prototype();
endif;
return $prototype;
}
/**
* Needed for the static calling functionality
*
* @return boolean
*/
public function isCallable( $name )
{
return ( isset( $this->_functions[$name] ) );
}
}
// make some prototype classes
class Test1 extends Prototype
{
}
class Test2 extends Prototype
{
}
class Test3 extends Test1
{
}
// lets create some test static functions
Test1::prototype()->fun1 = create_function( '$arg1', '
echo \'Static Test1::fun1 \' . $arg1 . "\n";
');
Test2::prototype()->fun2 = create_function( '$arg1', '
echo \'Static Test2::fun2 \' . $arg1 . "\n";
');
// now instantiate the objects
$test1 = new Test1();
$test2 = new Test2();
// and make some more functions
$test1->fun3 = create_function( '$arg2', '
echo \'Test1::fun3 \' . $arg2 . "\n";
');
$test2->fun4 = create_function( '$arg2', '
echo \'Test2::fun4 \' . $arg2 . "\n";
');
// output: Static Test1::fun1 bob
$test1->fun1( 'bob' );
// create another function
Test1::prototype()->fun2 = create_function( '$arg1', '
echo \'Static Test1::fun2 \' . $arg1 . "\n";
');
// output: Static Test1::fun2 bobby
$test1->fun2( 'bobby' );
// output: Static Test2::fun2 robert
$test2->fun2( 'robert' );
// output: Test1::fun3 robby
$test1->fun3( 'robby' );
// output: Test2::fun4 rob
$test2->fun4( 'rob' );
// another instance still has the static functions
$test1_2 = new Test1();
// output: Static Test1::fun1 bob
$test1_2->fun1( 'bob' );
$test3 = new Test3();
// this will give an error because prototype functions do not extend down to a child class
$test3->fun1( 'roberto' );
?>
终于找到了答案
<?php
/**
* @copyright © 2006, Schmalls / Joshua Thompson, All Rights Reserved
* @license http://www.opensource.org/licenses/bsd-license.php New BSD
* @author Joshua Thompson <[email protected]>
* @version 1.0.0
* @link http://www.countercubed.com
*/
/**
* This class holds the prototype capabilities
*
* Extending this class makes it prototype capable
*/
class Prototype
{
/**
* Holds prototype functions
*
* @var array
*/
private $_functions = array();
/**
* Default constructor
*
* This is here so that php doesn't complain about the prototype function
*/
public function __construct()
{
}
/**
* Sets the prototype functions or variables
*
* @param string $name
* @param mixed $value
*/
public function __set( $name, $value )
{
if ( function_exists( $value ) ) :
$this->_functions[$name] = $value;
else :
$this->$name = $value;
endif;
}
/**
* Gets static prototype variables if they exist
*
* @param string $name
* @return mixed
*/
public function __get( $name )
{
if ( isset( $this->prototype()->$name ) ) :
return $this->prototype()->$name;
else :
trigger_error( 'Undefined property: ' . __CLASS__ . '::' . $name, E_USER_NOTICE );
endif;
}
/**
* Calls a static prototype function
*
* @param string $name
* @param array $arguments
* @return mixed
*/
public function __call( $name, $arguments )
{
if ( isset( $this->_functions[$name] ) ) :
return call_user_func_array( $this->_functions[$name], $arguments );
elseif ( $this->prototype()->isCallable( $name ) ) :
return call_user_func_array( array( $this->prototype(), $name ), $arguments );
else :
trigger_error( 'Call to undefined method ' . __CLASS__ . '::' . $name . '()', E_USER_ERROR );
endif;
}
/**
* Returns the static prototype holder
*
* @return Prototype
*/
public static function prototype()
{
static $prototype = null;
if ( $prototype === null ) :
$prototype = new Prototype();
endif;
return $prototype;
}
/**
* Needed for the static calling functionality
*
* @return boolean
*/
public function isCallable( $name )
{
return ( isset( $this->_functions[$name] ) );
}
}
// make some prototype classes
class Test1 extends Prototype
{
}
class Test2 extends Prototype
{
}
class Test3 extends Test1
{
}
// lets create some test static functions
Test1::prototype()->fun1 = create_function( '$arg1', '
echo \'Static Test1::fun1 \' . $arg1 . "\n";
');
Test2::prototype()->fun2 = create_function( '$arg1', '
echo \'Static Test2::fun2 \' . $arg1 . "\n";
');
// now instantiate the objects
$test1 = new Test1();
$test2 = new Test2();
// and make some more functions
$test1->fun3 = create_function( '$arg2', '
echo \'Test1::fun3 \' . $arg2 . "\n";
');
$test2->fun4 = create_function( '$arg2', '
echo \'Test2::fun4 \' . $arg2 . "\n";
');
// output: Static Test1::fun1 bob
$test1->fun1( 'bob' );
// create another function
Test1::prototype()->fun2 = create_function( '$arg1', '
echo \'Static Test1::fun2 \' . $arg1 . "\n";
');
// output: Static Test1::fun2 bobby
$test1->fun2( 'bobby' );
// output: Static Test2::fun2 robert
$test2->fun2( 'robert' );
// output: Test1::fun3 robby
$test1->fun3( 'robby' );
// output: Test2::fun4 rob
$test2->fun4( 'rob' );
// another instance still has the static functions
$test1_2 = new Test1();
// output: Static Test1::fun1 bob
$test1_2->fun1( 'bob' );
$test3 = new Test3();
// this will give an error because prototype functions do not extend down to a child class
$test3->fun1( 'roberto' );
?>
http://personal.schmalls.com/2006/11/06/prototype-based-programming-in-php/
如果这样我们可以像javascript那样动态语言了
写直php来淋漓畅快
2、而模拟javascript里的prototype就没有必要了。js不提供继承,所以只能用prototype给对象附加方法。php已经提供了继承因此也就没有必要模拟prototype了
比如我已经有一个数据库对像
$db;这个数据库对像已经query了我们一般这样while($db->arraylist[$i]) //这是数据库取出了全部行数据
{
$db->arraylist['list'][$i]['title']=substr($db->arraylist[$i]['title'],20);
$i++;
}
模板这样子$tpl->assign("newslist",$db->arraylist);
大概这样子/////////////////////
Test2::prototype()->fun2 = create_function( '$arg1', '
echo \'Static Test2::fun2 \' . $arg1 . "\n";
');我们把它换成我们数据库的
$db::prototype()->fetchAll=ereate_funciton('$arg1','
$this->arraylist['list'][]=$this->fetchRow;//要处理程序在这里加入
/*注意这里程序会随着不同数据做出不同的处理,外加入url 截取,计算等*/
');这样我们直接可以用$db->fetchAll了
在另一个页面我们再重写下
$db::prototype()->fetchAll=ereate_funciton('$arg1','
$this->arraylist['list'][]=$this->fetchRow;//要处理程序在这里加入
/*注意这里程序会随着不同数据做出不同的处理,外加入url 截取,计算等*/
');
这些程序是不是只用$db->fetchAll就取出了我想要的数据
相反,ereate_funciton 定义的函数并不参与php代码加载时的预编译。因此执行ereate_funciton定义的函数时,php还需启动语法分析器做预编译,这样一来效率就要有所下降了
这个$str是不是可以是字符串。
我可以可动态加入要处理的php程序了。
比如
if(DEBUG){
$str=" print_r(\$_POST);";
}
我可以调试输出提交怎么样
在一个项目中我们专们有一个放调试文件当我设置项目为调试模式时候我们是不是可以
动态包含进来。正式发布时候我们把DEBUG设置为false那么自动不会包括进调试程序。这个$str字符串可以任意添加程序代码。 让我想到了设计模式中的
Decorator模式
$str中的程序可以动态设置执行先后顺序,添加功能
Observer模式
$str 可以动态添加观察者
就是javascript那个动态加入onload函数一样
附送上
javascript addloadEvent函数
----------------------------------
function addloadEvent(func)
{
var oldonload=window.onload;
if(typeof window.onload!='function')
{
window.onload=func;
}else
{
window.onload=function(){
oldonload();
func();
}
}
}
但如果需要附加的方法比较多,就不如直接继承了.继承与create_function的差异唠叨老大也说了,一个会预编译,一个不会,那么效率肯定是不会相同的.