轮回

2007年12月31日

时间是一个圆环,圆弧上每个立足点都包含了一些似曾相识的东西,同时也会有一些从未见过的什物……每当走过时间上的同一个标记,眼前的景象让人感到熟悉的同时却面目全非——我们总是在拿自己已经拥有的去跟时间交换我们所期望的,而交换总是不等价的,有人得到了更多,有人却越来越贫乏,这致使周围总是充满炫耀和抱怨的声音。又一次站在了时间的节点上,很多事情超出了想象但却是意料之中。

直到刚才,各个方面传来的消息都不乐观,其实很多事情最终都得到了解决,但却未必是以符合自己思维的方式实现的。有些遥远的坐标居然在一次次无谓地谈论中悄然而至,2008这个字眼最早出现于7年前那场令国人振奋的宣读场景中。我仍清楚地记得:当时坐在自己的床头上沉湎于那台多能奔腾带来的游戏快感,谁知后来那机器、那房间都不再属于我自己,反而是当时还未普及的网络成为我日后生活不可或缺的部分,所以说时间所能带来的改变要远远超乎我们的想象。

4月和9月两次迎接了老栋;5月去安亭见志洋;7、8月间陪雨水MM;10月接待立志;每次都是充满激情的带领别人浏览这座城市,之后便再不会有什么新意,只因在目前的视觉上只能看到这个层次。也忘不了几年前的那个夜晚,面对着繁华的霓虹和浦江中虚幻的倒影,激昂澎湃后恋恋不舍的离去。

总是强调有些东西本来是我的,但那种没经历住磨练的理想,最终只成为记忆中一个美丽的幻影……

Experience ,

理解wordpress的插件机制

2007年11月22日

Wordpress的插件机制使得开发者可以方便地向系统添加自己需要的功能,而这是使得Wordpress得以在全世界流行的重要原因。插件机制的实现主要依靠wp-includes目录下的plugin.php文件,该文件中包含了与插件机制相关的几个函数。

基本原理:和任何官方文档一样,wordpress对插件原理的说明还是显得太过学术。因此用通俗的语言来说就是:在wordpress内核运行时设立了一些标记(tag),当遇到这些标记时,wordpess会自动调用挂载到(hook to)这个标记上的所有函数,该功能是通过数组来实现的,其过程可以直观的表示如下:

这样,用户可以通过plugin API方便的将自定义的功能添加到系统相应的位置。值得注意的是:wordpress定义了两种类型的插件API,行为(actions)和过滤器(filters)。这两种类型的API从代码上看没有任何区别,主要的不同反映在实际应用中。行为(actions)即是在内核执行到某个标记点时所要执行的一系列函数;而过滤器则是内核执行到此标记时,将一些数据(通常是文本)传递给相应的函数,这些函数在数据库和浏览器之间对数据进行相应的修改,因此起到了“过滤器”的作用。

下面对plugin.php中的相关函数作下解释(为了方便理解,没有选择该文件默认的排列顺序):

1.merge_filters

/*************************/

function merge_filters($tag) {
global $wp_filter, $merged_filters;

if ( isset($wp_filter['all']) && is_array($wp_filter['all']) ) //由于PHP中的arrray_merge函数要求参数必须是数组,因而要作此判定
$wp_filter[$tag] = array_merge($wp_filter['all'], (array) $wp_filter[$tag]);

if ( isset($wp_filter[$tag]) ){
reset($wp_filter[$tag]);
uksort($wp_filter[$tag], “strnatcasecmp”);
}
$merged_filters[ $tag ] = true; //将$merged_filters[ $tag ] 置为true,表明已经将需要执行的通用函数合并到了该标记($tag)下的$wp_filter队列中
}

解释:这里首先要知道wordpress为了实现插件机制所定义的两个全局数组$wp_filter和$merged_filters,$wp_filter的作用是通过数组来保存某个标记下挂载的函数队列,而$merged_filters的作用则主要体现在本函数中。在wordpress中有一些通用函数是需要被所有过滤器所调用的,merge_filters函数的作用就是将这些函数合并到所有标记所对应的函数队列中,并以$wp_filter数组下的键名”all”来记录。

2.add_filter

/*************************/

function add_filter($tag, $function_to_add, $priority = 10, $accepted_args = 1) {
global $wp_filter, $merged_filters;

$wp_filter[$tag][$priority][_wp_filter_build_unique_id($tag, $function_to_add, $priority)] = array(‘function’ => $function_to_add, ‘accepted_args’ => $accepted_args);
unset( $merged_filters[ $tag ] );
return true;
}

解释:该函数的目的是将用户自定义函数$function_to_add,添加到$tag对应的过滤器队列中,并记录相应的优先级$priority和自定义函数的参数个数$accepted_args。

3.apply_filters

/*************************/

function apply_filters($tag, $string) {
global $wp_filter, $merged_filters;

if ( !isset( $merged_filters[ $tag ] ) ) //判断$tag所对应的过滤器是否已合并到$wp_filter中
merge_filters($tag);

if ( !isset($wp_filter[$tag]) ) //这步主要出于容错考虑,如:万一插件作者笔误,系统中无此过滤器,那么直接返回$string,不会造成系统错误
return $string;

reset( $wp_filter[ $tag ] );

$args = func_get_args();

do{
foreach( (array) current($wp_filter[$tag]) as $the_ ) //通过循环调用执行每个过滤器队列中的函数,匹配相应的函数参数
if ( !is_null($the_['function']) ){
$args[1] = $string;
$string = call_user_func_array($the_['function'], array_slice($args, 1, (int) $the_['accepted_args']));
}

} while ( next($wp_filter[$tag]) );

return $string;
}

解释:该函数将字符$string应用到过滤器标记$tag处,此外,该函数可以接受额外的参数。

4.remove_filter

/*************************/

function remove_filter($tag, $function_to_remove, $priority = 10, $accepted_args = 1) {
global $wp_filter, $merged_filters;

unset($GLOBALS['wp_filter'][$tag][$priority][_wp_filter_build_unique_id($tag, $function_to_remove, $priority)]);
unset( $merged_filters[ $tag ] );

return true;
}

解释:这个函数相当简单,就是将某个函数从过滤器中移除,记得同时要将$merged_filters数组中对应的$tag键销毁。

5.add_action

/*************************/

function add_action($tag, $function_to_add, $priority = 10, $accepted_args = 1) {
add_filter($tag, $function_to_add, $priority, $accepted_args);
}

解释:向特定的行为添加自定义函数,前面说过,代码上看跟向过滤器添加是完全一样,区别在于应用。

6.do_action

/*************************/

function do_action($tag, $arg = ”) {
 global $wp_filter, $wp_actions;

 if ( is_array($wp_actions) )
  $wp_actions[] = $tag; 
 else
  $wp_actions = array($tag);

 $args = array();
 if ( is_array($arg) && 1 == count($arg) && is_object($arg[0]) ) //此步判断是将do_action函数的参数$arg加入参数数组$args中
  $args[] =& $arg[0];
 else
  $args[] = $arg;
 for ( $a = 2; $a < func_num_args(); $a++ ) //若do_action函数还有额外的参数,则继续加入到参数数组$args中
  $args[] = func_get_arg($a);

 merge_filters($tag); //将$tag所对应的过滤器合并到$wp_filter中

 if ( !isset($wp_filter[$tag]) )
  return;

 do{
  foreach( (array) current($wp_filter[$tag]) as $the_ ) //通过循环调用执行每个行为队列中的函数,匹配相应的函数参数
   if ( !is_null($the_['function']) )
    call_user_func_array($the_['function'], array_slice($args, 0, (int) $the_['accepted_args']));

 } while ( next($wp_filter[$tag]) );

}

解释:这个函数跟前面的apply_filters类似,执行某行为标记$tag下的函数队列。

7.remove_action

/*************************/

function remove_action($tag, $function_to_remove, $priority = 10, $accepted_args = 1) {
remove_filter($tag, $function_to_remove, $priority, $accepted_args);
}

解释:将某函数从其所属行为的函数队列中清除。

参考资料:
自己动手写 WordPress 插件:使用 API
wordpress中文开发文档

Knowledge

轨道交通第一辑

2007年10月28日

昨天下午,轨道交通全程记录:东川路(5号线)—莘庄(1,5号线)—外环路(1号线)—上海南站(1,3号线)—中山公园(3,2号线)—世纪大道(2,4号线)—万体馆(4,1号线)—徐家汇。

最爱1号线:

   

时尚2号线:

    

繁忙3号线:

   

漂亮4号线:

   

可爱5号线:

    

片花:

   

更多内容轨道交通相册

Experience

关于wordpress的小tips

2007年10月13日

wordpress有时会出现由于服务器设置造成的小问题,需要对其中的某些文件进行修改:

  • wordpress无法正确读取来访者(评论)IP
  • 由于服务器的某些缓存技术,有些系统无法被正确读取来访者的IP,评论的IP均显示为服务器本身的地址,解决方法是将下列文件:
    \wp-includes\comment.php
    \wp-content\plugins\akismet\akismet.php
    \mint\config\auto.php
    \mint\pepper\shauninman\default\class.php

    中的变量_SERVER['REMOTE_ADDR']替换为_SERVER['HTTP_X_FORWARDED_FOR']

  • wordpress中文版无法正常显示
  • 在使用Php5.x的版本中,中文版的wordpress会无法正常加载中文包,直接调用函数显示的地方如存档、评论等的中文名字会变英文,后台也全部是英文,解决方法是将下面文件:
    \wp-includes\gettext.php
    中的代码

    1. if ($magic == ($MAGIC1 & 0xFFFFFFFF) || $magic == ($MAGIC3 & 0xFFFFFFFF)) { // to make sure it works for 64-bit platforms
    2.       $this->BYTEORDER = 0;
    3.     } elseif ($magic == ($MAGIC2 & 0xFFFFFFFF))

    修改为

    1. if ($magic == $MAGIC1) { 
    2. $this->BYTEORDER = 0;
    3. } elseif ($magic == $MAGIC2) {

    Knowledge

    互联网服务的横向扩展

    2007年9月26日

    互联网本身是一部编年史,从最早的电子邮件到今天的个人博客,新服务总是随着技术的发展不断涌现。纵贯其发展历程,每个阶段都有着代表性的服务(这里的服务指典型的、广为使用的互联网应用):

    有趣的是,如果对同一个服务作横向的比较就会发现,新服务带来的不都是对原有服务功能的覆盖,也会促进原有服务功能的扩展和丰富。比如电子邮件在最初只具备通讯功能,但随着博客、图片社区的出现,它就可以用来更新日志、发布图片;跟在线日程表结合还具有事项提醒等功能。即时通讯本来的功能是朋友间的交流,但随着协议和API的开放,也可以用来进行信息的双向推送……这些新的应用都不是基于技术的更新,所以说创新不仅仅可以寄希望于新的服务,同样可以依托现有模式的扩展,这就是为什么在WEB2.0时代服务理念得到了空前的重视。

    现在的情况是,针对某一类服务模式的仿造太过直接而缺乏特色的扩展。上次在教育人博客上看到每篇日志都被加了Digg按钮,仿佛在提醒访问者该网站已经融入了Digg模式,这是一个典型滥用的例子,如果在后台设置一个计数字段来统计每篇日志的点击从而向读者排序推荐就好了,完全照搬只会让人觉得不伦不类。

    任何现实层面解决不了的问题都可以归结为信仰和意识的原因,需要从哲学层面来理解,对于互联网的意识也需要从其本身的哲学来领会,也许长期以来我们过多地关注了认识论而忽视了本体论。

    未分类