在本机重构wordpress插件开发系统

上月初笔记本的硬盘噼里啪啦的乱了,貌似是硬件问题,听着里面咯吱咯吱的叫,感觉心惊肉跳的。换了同型号的硬盘重装系统,幸亏有网络和移动硬盘备份重要文件,让工作可以继续,但手机程序、照片以及自己业余开发程序的环境就不复存在了。近段忙的不行,前天终于有时间有心情把这一切恢复起来。把相关步骤做个记录,聊以备忘。以后如果硬盘再坏了,照这个重新来一道就可以了(希望不会再次发生)。 整体的部署如下:

  1. 安装netbeans for php的集成开发环境;
  2. 在本机架构apache服务器和mysql服务器环境;
  3. 从http://heart5.com 的服务器空间把整站down下来,然后把mysql数据库压缩备份下来;
  4. 在本机架构wordpress博客站点并把down下来的网站数据和数据库数据恢复并做相应修改,注入;
  5. 在netbeans中新建project,源码就是本地服务器安装的wordpress程序代码;
  6. 安装svn工具,checkout出来wordpress.org插件目录中的源码,设定到netbeans开发环境中;
  7. okay。

一、netbeans已经是6.9版本了,php专用版只有35M,安装之,和以前版本的差别不是很大,release中说是多了对某些服务的支持,使用过程中再慢慢体验吧。netbeans本来是java开发平台,原来使用体验不错,就沿用了for php的专用版本,也不期待对php的支持能好到哪里去,能用就好。

二、在本地架构主机和数据库服务自然使用xampp套件,到主网站看了下,已经升级到1.7.3版本了。下了个lite版本,zip压缩,有60.9M大,支持apache和mysql够了。解开使用前,需要运行setup_xampp.bat进行系统设定,基本一路y就可以了。平常使用的话就运行xampp-control.exe,手动启动apache和mysql服务就可以了。可以在浏览器中键入http://localhost/xampp 进行测试,安装并设定成功的话浏览器会显示xampp的欢迎信息。

三、考虑到博客上曾经上传了图片存放,再加上一些其他个人文件,因此找胡戈戈回复了ftp密码后对全站进行下载,结果花了我五个小时时间,大呼上当。究其原因,首先是原来设定的每周数据库备份占了100多M,其次是wordpress的目录太深,ftp时非常好时间。其实正确的方案是在本机重新安装wordpress3.0版本就可,至于个性化的图片和文件顶多半个小时就恢复完了。进入cpanel对数据库进行了备份下载。后来发现的诡异事件是自从我用cpanel对数据库进行了操作后,网站居然不可访问了,提示error establishing database connection,后来Google之,根据别人经验对config文件进行了相应修改才恢复正常。难道原来的配置文件是错误的,那为什么原来可以正常访问呢?猜测可能是服务器端缓存的原因。

四、wordpress程序文件和个人个性化文件很好搞,直接拷贝到xampp下的htdocs目录下就行了。有点技术含量的是对本机的mysql进行相应的设定。登录http://localhost/xampp ,进入phpadmin图形化数据库管理界面,构建一个数据库用于存储博客数据,然后再用mysql命令行工具新增一个用户并赋予它访问新构建数据库的权限。方便起见,建议无论是数据库名称还是用户名称和密码都和外购服务器空间上的保持一致,避免更改config文件。同样是在phpadmin图形化数据库管理界面中选择新建的数据库,把从外购服务器备份下来的数据库文件导入,然后修改option子表的home和siteurl的值为http://localhost 。一切okay了,你可以在浏览器中登录http://localhost 访问,应该会正常显示博客页面,和外购服务器上的一模一样。注,为避免混淆,建议在管理后台修改博客中文名称,加上“本地”二字,避免调试中可能产生的混淆。

五、启动netbeans,新建项目,命名为wordpress,设定服务器地址为localhost,并选中源码改动时自动拷贝至服务器,源码目录一般在我的文档下的netbeansproject下。从xampp的htdocs目录下把文件全部拷贝过来。以后启动netbeans进行程序开发就行了,所做调整都会自动反应在本地服务器上,可以通过浏览器访问localhost查看效果。

六、原来用的是官方的svn命令行工具,这次尝新,安装了图形化界面的tortoisesvn使用。进入netbeansproject下的wordpress的statpresscn插件目录下,把内容全部删除,退回上一级目录,用鼠标选中statpresscn目录,右键弹出菜单中选择checkout,在弹出的窗口中输入http://svn.wp-plugins.org/statpresscn/trunk (一定记得最后的那个trunk,否则它会给checkout整个svn repository),checkout下来。你会看到statpresscn目录的图标自动被tortoisesvn接管了,如果里面的源码文件有改动,图标会做相应显示,想把修改后的文件提交至服务器,右键选择相应svn命令就行了。 至此,本机的wordpress插件开发系统已经构建完毕,可以正常运转了。这两个月有不少朋友对statpresscn提了很好的建议,终于可以逐步实现它们了。

StatPressCN,1.6.9.7版本

下载升级:

  • 请到wordpress官方插件网址下载最新版本,ftp到服务器上去;
  • 或者,如果您的wordpress是2.7版本以上的,那就耐心等段时间(大约几个小时吧),管理后台会自动提示升级的;
  • 提示:升级至本版本不会影响数据库中的数据记录。

升级需做:

  • 无。

功能开发:

  1. 侧栏小工具“最热博文”中可设定时间范围了,比如最近7天的热文、最近三个月的热文等;
  2. 在管理面板上显示统计信息;
  3. 过滤掉user heart5的访问记录,方便测试;
  4. 不定期优化统计数据库(1000次访问执行一次);
  5. 所有的统计子页面都添加效率执行检测模板,在页脚。

def规则:

  1. 增加了两个Google的新规则。

代码改进:

  1. 更新了部分本地化语言。

开发笔记

Maxim提了几个建议,一个是在“详情”中显示的页面包括首页是不应该的,这个数据和widget中最热博文不一致,其次是希望在“最热博文”中可增加时间范围选择。第一个问题me系统思考了下,还是坚持目前的做法。因为在这里是对所有链接请求的统计,比如tag、分类等,和页面是同等地位,但是在博文中则仅仅针对帖子文章,这两个不是一码事。在“最热博文”中增加时间选项倒很实用,me已经实现了这个功能,现在您可以自由设定时间,显示“最近三个月的最热贴”等。解决这个问题的时候me发现widget的所有信息是以数组的形式存放在option表中的。

看到akismet中有个随机执行comments数据库清理优化的代码,觉得很好。既不用每次都运行,消耗系统资源,又能在一定时间内实现代码的执行。运用了mt_rand函数产生随机数,然后设定一个幸运数,符合的时候就执行一次。呵呵,照抄过来,用在了statpress统计数据库的清理优化。再一个想学习的地方是akismet在管理面板中显示的统计信息,比如过滤了多少垃圾评论等。检查代码原来是使用了add_action(“activity_box_end“,’heart5_dashboard_4_spc’);直接借鉴过来就好了。StatPressCN在这里显示的信息是StatPressCN widget中的信息,不过关于版权标记和页底效率监测则需要过滤掉,需要判断是在哪里调用的。如果是管理界面就不显示,正常的来访则显示。

PHP、MYSQL编程笔记

开发StatPressCN过程中恶补PHP和MYSQL知识,水平不行,只好边干边学,呵呵。对一些基础不高深的东东简单梳理下,免得忘了下次重来。

一、MYSQL

  1. 用MYSQL语句直接修改数据。update `db_name` set `urlrequested` = replace(`urlrequested`,’\”,”) where `urlrequested` like “%\'”,把以’结尾的链接请求末尾的’去掉。replace可以保证key的连续性,如果先删除后添加就没有这个好处了。
  2. 插入记录。INSERT INTO users(name, age) VALUES(‘姚明’, 25), (‘比尔.盖茨’, 50), (‘火星人’, 600);如果values中为空,则添加默认值为基础的记录。
  3. 更新记录。需要配合where条件判断。UPDATE users SET age = 30 WHERE id = 12;以上语句都很危险,如果where没有设置的话会更新所有的数据记录,所以在进行类似操作的时候一定要先备份,再审慎
  4. 删除数据有两个命令delete和TRUNCATE。DELETE FROM users WHERE name = ‘Mike’ ORDER BY id DESC LIMIT 6;如果有自动增加的字段,用没有where的delete和truncate都会让这个字段从0开始,如果不想这样,可以用带where 1的语句,不过那样的执行效率很多,因为需要遍历整个数据库的所有记录;删除数据时如果使用形如like ‘$tmpstr%’的语句,一定要判断下$tmpstr是否为空,否则很危险,可能删除掉所有数据,后果严重的很。
  5. 正则表达式在where语句中也可使用,好爽,这下me对正则表达式的学习可以用了。官方文档参见这里。

二、PHP

  1. 分开字符串。$p = explode(“=”,$url);
  2. 打印出数组中的所有元素。print_r($p);
  3. 计算数组中的元素个数。count($p);
  4. 数组运算,类似于java中集合的概念,很方便。生成一个空数组:$bloglist = Array();向数组中增加一个或几个元素(从末尾):array_push($bloglist,$matches[1]);添加到数组头部之前则是array_unshift($bloglist,$matches[1]) ;从数组尾部删除一个元素用array_pop(),从头部删除一个元素则用array_shift();让数组中元素唯一(即无重复元素,类似于结合set的概念):$bloglist = array_unique($bloglist);迭代输出每个元素可以在foreach中使用as:foreach($bloglist as $blog);判断某元素是否在数组中:in_array($lookingFor, $bloglist),返回布尔值真假;数组中每个元素都有个默认的key,可以这样输出看看:while (list($key,$value) = each($bloglist)) {echo “$key : $value<br>”;};还可以合并多个数组$bloglistall = array_merge($bloglist1, $bloglist2);得到两个数组的交集可用array_intersection($bloglist1, $bloglist2);差集可用array_diff($bloglist1, $bloglist2);如需要合集则先array_merge(),然后再用一次array_unique();对数组进行排序则用sort($bloglistall),默认是英文字母顺序;数组的key必须是唯一的,并且key可以设定为字符串,默认是整数。关于数组,更详细的阐释是Array的官方说明(e文版)。
  5. 奇妙的类型自动转换。print(“8&heart5″+20);输出结果为28。
  6. 字符串函数:strlen,得到字符串长度;substr($v,start_pos,length),截取指定长度的字符串,不指定长度则自动取到末尾;strripos($v,”postname”),是否包含指定子字符串,返回所处位置或;sscanf,扫描规律字符串得到相应变量;printf,格式化输出字符串;str_replace,替换子字符串;strstr,找到特定子字符串出现的位置;rtrim会删除末尾的空格和换行等字符,包括空格、\t、\n、\r、\0、\x0b;explode会自动处理行尾的空字符。
  7. 正则表达式。ereg(‘^/[0-9]{4}/[0-9]{2}/{0,1}$’,$out_url);匹配/2008/10
  8. 时间函数。println(strtotime(“now”));输出1224902867,然后用date函数格式化println(date(“c”,$d1));输出2008-10-24T18:03:42+08:00,println(date(“r”,$d1));输出Fri, 24 Oct 2008 18:03:42 +0800,如果用gmdate则输出格林威治标准时,println(gmdate(“r”,$d1));输出Fri, 24 Oct 2008 10:03:42 +0000;其中时区信息是通过date_default_timezone_set(‘prc’);设定的,prc指中国大陆,也可以是其他,有效值列表见这里;另外strtotime还可以对时间做修正,比如strtotime(“3 October 2005”)和strtotime(“1 days”,strtotime(“2 October 2005”))输出的结果都是一样的,可以用的修正符号有“+1 week 3 days 7 hours 5 seconds”,可以用+-号。
  9. file打开某个文件并把每行读入数组;fopen打开一个文件返回句柄,可以设定打开方式为读或者写,打开后内容置空;fwrite则写入内容,成功则返回true,否则是false;操作完毕后需要fclose关闭句柄。

三、WordPress

  1. get_option直接得到选项值,不用每次用mysql语句查询。
  2. get_permalink($id)得到帖子的固定链接地址,注意是包含域名的绝对路径,如果需要相对路径,则需要str_replace(get_bloginfo(“url”),””,get_permalink($id));
  3. update_option如果该项不存在会自动建立。技巧:如果不能确定某个选项是否存在,则可以先update后再delete。
  4. 数组可以一次性存入option中,存储形如a:2:{s:5:”title”;s:8:”my titile”;s:4:”body”;s:12:”Home is warm”;},a指的数组,2是元素个数,title是key名称,5是字符串长度,my titile是title的值,后面body同。
  5. 要调用插件或主题中的函数必须进入wp的主题运作机制,直接调用是无效的,出于安全考虑,同时也是因为无法得到相关环境设定和变量。官方提供的方式是模板,比如您可以自己定义一个page的新模板,然后创建page是选择新模板就可以了。模板标头有特殊要求,见这里
  6. php代码执行其实是以用户权限进行的,因为可以获取文件的在服务器上的本地地址并进行读写操作。

四、HTML

  1. 因为php可以控制输出逻辑,因此可以尽量使用html代码而不是通过php的echo或print输出,这样页面逻辑更清晰,也容易调试。
  2. 表格需要设定宽度后,表格单元中的左对齐右对齐才能起作用。
  3. input type=checkbox name=’statpress_showhotdepth’ value=’checked’ xxx

五、CSS

  1. 样式表嵌入标签的方法。<table class=’mytable’>……</table>,这种情况下mytable应该在外链的css或者当前页面自定义的css中已经定义过;或者直接写style:<table style=”outline:dotted 1px green;”>……</table>
  2. 在形如#sidebar h2{……}中,仅对那些class是sidebar中出现的h2才起作用。

web开发环境的搭建(for php)

为了方便程序开发,必须要搭建一个开发环境。需要一个http服务器、支持mysql和php,这样才能在本机上运行wordpress。在网上找到了xampp,用了一段时间,感觉不错。稍微记一下,聊以备忘。

下载apache friends – xampp

安装:下载安装版本一路next就行了,或者下载zip版本自己解压后运行xampp_setup.bat。

使用

用管理面板启动Apache和mysql即可。需要注意的是请修改xampp安装目录下的apache\conf\httpd.conf,把#LoadModule rewrite_module modules/mod_rewrite.so语句中的#去掉,否则不支持wordpress中的permalink。

至于mysql的优化,建议找专门的文章学学,me简单调整了下my.cnf中的参数,效果很一般,运行起来还是慢的要死,看来这是个专业活。

PHP、MYSQL和WordPress编程散记

为了解决StatPress存在的中文乱码问题并清除无效spider信息,me下功夫K了不少php、mysql以及WordPress的编程信息。怕下次再重新学习一道,记录一下知识点,聊以备忘。

一、PHP

  1. 连接字符串使用.,比如$nome.”|”.urldecode($tab[1])。
  2. 调用变量用$,函数则直接调用。
  3. 字符串处理的一些常用函数。strpos寻找字符串中某字符最先出现处,strrpos寻找字符串中某字符最后出现处,这两个函数都反馈整数值,如果没有找到则返回false;strrchar则返回字符最后出现处至结尾的子字符串,strstr则返回搜索字符串最后出现处至末尾的子字符串;substr取部分字符串,string substr(string string, int start, int [length]);start和length如果是负数则从末尾算起;ereg用正则表达式对字符串进行比较或返回拆分后的数组,eregi同ereg,只是大小写无关,ereg_replace和eregi_replace按照一定的规则进行替换;str_replace替换特定的子字符串,str_replace(“%body%”, “black”, “<body text=%body%>”);
  4. 处理url的函数有urlencode和urldecode,前者把”为什么”转为%CE%AA%CA%B2%C3%B4,后者再把它转回来。编码是为了适应浏览器对url的处理规则, 对字符串多解码一次也没什么影响,还是原样。还有个函数是parse_url,返回数组,可以通过component调用处理结果,支持的component有scheme、host、port、user、pass、query、fragment。
  5. iconv可以把字符串在不同的字符集间进行转换,比如iconv(“gb2312″,”utf-8”,$str)。
  6. gb2312的字符encode后占两位,也就是有两个%,而utf-8则是三位,每个字有三个%,示例:为什么如何使utf-8则encode后为%E4%B8%BA%E4%BB%80%E4%B9%88,共9位,如果是gb2312则为%CE%AA%CA%B2%C3%B4,只有6位。
  7. if中的条件判断语句不能用=而是==,否则就直接赋值了,比如$nome == “Baidu”。
  8. explode函数把由特定间隔符分割的字符串拆解成数组,比如$str = “wd=home”,$array = explode(“=”,$str)后得到array,其中array[0]=wd,array[1]=home。
  9. count则统计数组中元素的个数,count($array)的话就是2。
  10. 调试函数在,怎么忽然就该页为空了(在浏览器中啥都不显示),试了几次都不行。想想刚才都做了什么,也就是更改了页面的charset,从gb2312到utf-8,另外就是增加了两行代码。把代码删除,问题依旧;把charset改回去,还是不行。于是就怀疑是不是服务器不稳定,坏了。重新启动,问题居然依旧。这时候才想到去查服务器的log。一看不打紧,全是500,呵呵,标准的服务器内部错误,并且提示PHP Parse error: syntax error, unexpected T_STRING 在某个文件中云云。Google了下,还是没啥概念。在搜索结果中转来转去,忽然有点感觉了,还是代码出了问题,php无法解析导致的。再次检查,晕,还真是,后面加的两行代码导致的。调用函数居然没有用括号括住参数,具体如此println iconv(“gb2312″,”utf-8”,$stem);呵呵晕死。加上应该的括号后变成了这样println(iconv(“gb2312″,”utf-8”,$stem));搞定!
  11. date是用来输出时间日期为特定形式的函数,具体的时间日期值通过mktime获得。date_default_timezone_set(‘Asia/Shanghai’);居然只支持Shanghai、Chongqing等,但没有北京。$startday = mktime(0,0,0,2,30,2008);居然也有效,不过生成的日期是2008年3月1日,自动处理了。(strtotime(“now”)-$startday)/86400;获得从某特定日期到现在的所过天数。


二、MYSQL
(一)不知道PHP的函数是否可以直接用在SQL语句中,只好把要处理的记录全查出来后根据id一条条进行处理,示例代码如下:
$qry = $wpdb->get_results(“SELECT id, urlrequested FROM $table_name WHERE (urlrequested is not null) and (urlrequested != ”)”);
print “…”.count($qry).” select-ed; “;
foreach ($qry as $rk) {
$tmpstr = urldecode($rk->urlrequested);
$q=”UPDATE $table_name SET urlrequested = ‘$tmpstr’ WHERE id=”.$rk->id;
$wpdb->query($q);
}
print “”.__(‘done’,’statpress’).”
>”;
me非常担心这样的语句如果不能按照本意进行,会毁掉所有记录的那一栏数据:
update $table_name set urlrequested = urldecode(urlrequested);
(二)在本地安装的php、mysql和wordpress组合中导入网站导出的数据(为后缀名为sql的文本文件),命令语句:

mysql -uroot dataname < dataname_wp_20080427_287.sql

(三)创建数据库并授权以及添加用户。

用root登陆后 create database db_name;

grant all on db_name.* to db_user@host identified by ‘password’;

(四)update语句影响的set数目。为了使statpress在update时能精确显示信息,me增加了setcount参数进行统计,点击statpressUpdate时结果如下:

Updating OSes: 2006 sets are set to blank. 2006 sets are updated. done
Updating Browsers: 2009 sets are set to blank. 2009 sets are updated. done
Updating Spiders: 0 sets are set to blank. 0 sets are updated. done
Updating Feeds: 0 sets is set to blank. All is done.
Updating Search engines: 458 sets is set to blank!
2284 are select-ed, 458 are updated!

可以看出,在每个项目中被置空的数据记录居然数量不一样(OS中是2006个,Browser中则是2009个)。按道理像这样的语句 UPDATE $table_name SET spider = ”; 应该是更新数据库中的所有记录数才对啊。Google了半天,总算搞清楚了原因。那就是MYSQL在更新数据时如果该数据和将被更新的数据一致的话则不会发生作用,这样的话上面语句仅仅更新了那些不是”的记录。仔细想想,这种处理确实有理,可以提高sql语句运行效率,在数据库很大的时候当然会显得非常有必要。

(五)清除某些插件的残留物。插件启用后有些时候感觉不好用,总是要放弃的,但有些不友好的会留下一些东西,像创建的数据库啊以及在options中的记录等。用下面语句清除:feed_statistics、wp-poll、tantan的ga。

$str = ”;
foreach($wpdb->get_col(“show tables like ‘%wp_feed_%'”) as $db_name){
$str .= $db_name.”|”;
$wpdb->query(“drop table $db_name”);
}
$str .= $wpdb->query(“delete from wp_options where option_name like ‘%poll_%'”).”|”;
$str .= $wpdb->query(“delete from wp_options where option_name like ‘%feed_statistics_%'”).”|”;
$str .= $wpdb->query(“delete from wp_options where option_name like ‘%tantan_ga%'”).”|”;

三、WordPress
(一)、查看StatPress统计的记录,居然有这样访问的:
/2006/05/23/javascript:void($(‘akst_form’).style.display=’none’);
是不是有人想黑me啊。

又发现了怪怪的urlrequest,这次是¤§??? and 1=1,me把它敲入地址栏后就转换成了 http://heart5.com/%A1%E8%A1%EC???%20and%201=1,页面结果是Error 404,Not Found。

(二)、rss类的url跟随wordpress的permalink设置情况变化:如果是默认的?p=123则get_bloginfo(‘rss2_url’)得到形如http://host/?feed=rss2;如果permalink设置为/%year%/%month%/,则get_bloginfo(‘rss2_url’)得到形如http://host/feed/rss2。statpress对这种情况没有做特殊处理。此种关联也提醒我们不要随便改变wordpress的permalink,因为会影响很多事情。

(三)、在wordpress中所有插件中的函数可以互相调用,并且还可以用在模板中。强,不过,避免函数名称冲突就显得非常非常重要了。