可以,
我不是百分之百的你想做的,但我有个主意。
也许你的意思是这样的:
class View {
public $hooks = array('getsomeVar');
public $hooks_functions = array();
public $attributes = array();
public function __set($k,$v) {
$this->attributes[$k] = $v;
}
public function __get($k) {
if (isset($this->attributes[$k])){
$hooks = $this->get_functions_by_hook('get' . $k);
if (!empty($hooks)){
foreach ($hooks as $klass=>$methods) {
if (class_exists($klass)){
$class = new $klass();
foreach ($methods as $method) {
if (method_exists($class,$method)){
$this->attributes[$k] = $class->$method($this->attributes[$k]);
}
}
}
}
}
return $this->attributes[$k];
} else {
throw new Exception($k . " is not a view variable");
}
}
public function register_filter($name,$class,$method) {
if (in_array($name,$this->hooks)){
$this->hooks_functions[$name][$class][] = $method;
} else {
throw new Exception($name . ' is not a valid hook');
}
}
public function get_functions_by_hook($name) {
if (array_key_exists($name,$this->hooks_functions)){
return $this->hooks_functions[$name];
}
return array();
}
}
class MyPlugin {
public function fix_string($str) {
return str_replace("ruby",'php',$str);
}
}
$v = new View();
$v->someVar = 'ruby is great';
$v->register_filter('getsomeVar','MyPlugin','fix_string');
echo $v->someVar;
或者你可以使用这种方法,它更像事件。同样是示例代码,但是您应该能够对其进行解压。
class EventDispatcher {
public static $listeners = array();
public static function registerListener(&$instance) {
if (!in_array($isntance,self::$listeners)){
array_push(self::$listeners,$instance);
}
}
public static function dispatchEvent($name,&$value) {
foreach (self::$listeners as $listener) {
if (method_exists($listener,'interests')){
$funcs = $listener->interests();
if (array_key_exists($name,$funcs)){
foreach ($funcs as $f) {
$value = $listener->$f($value);
}
}
}
}
}
}
class Plugin {
public static function registerPlugin($class_name) {
if (class_exists($class_name)){
EventDispatcher::registerListener(new $class_name());
}
}
}
class Model {
public function __construct() {
EventDispatcher::registerListener($this);
}
public function special($value) {
echo "I got called too!\n\n";
return $value;
}
public function interests() {
return array(
"getsomeVar" => "special",
);
}
}
class View {
public $attributes = array();
public function __set($k,$v) {
$this->attributes[$k] = $v;
}
public function __get($k) {
if (isset($this->attributes[$k])){
EventDispatcher::dispatchEvent('get' . $k,$this->attributes[$k]);
return $this->attributes[$k];
} else {
throw new Exception($k . " is not a view variable");
}
}
}
class MyPlugin {
public function fix_string($str) {
return str_replace("ruby",'php',$str);
}
public function interests() {
return array(
"getsomeVar" => "fix_string",
);
}
}
Plugin::registerPlugin('MyPlugin');
$model = new Model();
$v = new View();
$v->someVar = 'ruby is great';
echo $v->someVar;
这只是一些示例代码,我完全不是这样做的,但似乎这就是您所说的。
干杯,
杰森
补遗:
大部分内容都是关于wp代码库的。
wp访问全局范围中设置的变量,这些变量的修改如下:
function add_filter($tag, $function_to_add, $priority = 10, $accepted_args = 1) {
global $wp_filter, $merged_filters;
$idx = _wp_filter_build_unique_id($tag, $function_to_add, $priority);
$wp_filter[$tag][$priority][$idx] = array('function' => $function_to_add, 'accepted_args' => $accepted_args);
unset( $merged_filters[ $tag ] );
return true;
}
它还有其他一些功能,如,有滤波器等。
function apply_filters($tag, $value) {
global $wp_filter, $merged_filters, $wp_current_filter;
$args = array();
$wp_current_filter[] = $tag;
// Do 'all' actions first
if ( isset($wp_filter['all']) ) {
$args = func_get_args();
_wp_call_all_hook($args);
}
if ( !isset($wp_filter[$tag]) ) {
array_pop($wp_current_filter);
return $value;
}
// Sort
if ( !isset( $merged_filters[ $tag ] ) ) {
ksort($wp_filter[$tag]);
$merged_filters[ $tag ] = true;
}
reset( $wp_filter[ $tag ] );
if ( empty($args) )
$args = func_get_args();
do {
foreach( (array) current($wp_filter[$tag]) as $the_ )
if ( !is_null($the_['function']) ){
$args[1] = $value;
$value = call_user_func_array($the_['function'], array_slice($args, 1, (int) $the_['accepted_args']));
}
} while ( next($wp_filter[$tag]) !== false );
array_pop( $wp_current_filter );
return $value;
}
这不是一个事件驱动的系统,而是一个方法查找表,它只是一个查找要调用的用户定义函数的巨大散列。
应用过滤器,当代码被呈现时,所有类似插件的函数都被称为过程性函数,下面是一个例子
if ( $prefixed ) {
$value = apply_filters("pre_$field", $value);
$value = apply_filters("${field_no_prefix}_save_pre", $value);
} else {
$value = apply_filters("pre_post_$field", $value);
$value = apply_filters("${field}_pre", $value);
}
或者对于操作,在实际的模板视图中,如下所示:
<p class="submit"><input type="submit" class="button" name="submit" value="<?php esc_attr_e('Add Category'); ?>" /></p>
<?php do_action('edit_link_category_form', $category); ?>
</form>