Archive for the ‘PHP’ Category

Microsoft Access 转 MySQL软件

星期六, 十月 4th, 2008

以前刚开始学网页脚本的时候,先学的是ASP,ASP一般配合Access数据库使用。直到后来一个高手推荐我学PHP,才屁颠屁颠地学了点PHP,又用上了MySQL。Access和MySQL数据库各有特色,Access的特点是小巧玲珑,而且由一个文件构成、数据库备份之类的只要复制一下文件就好,挺方便的;所以我刚开始用MySQL的时候不解,为什么要做成这种后台形式呢?无论安装PHP程序还是备份数据,多麻烦?不过MySQL的特点也是显而易见的,高效、稳定。

以前偶尔会做一些小玩意,比如我曾经从网上下载了一个电话号码定位的数据库,里面大概有 130XXXX – 139XXXX 的号码段对应的城市,这个数据库是Microsoft Access格式的,而我当时用的是PHP+MySQL,所以得转为sql格式放入MySQL中。一开始用的是PHP脚本法,即写一个PHP脚本,通过ODBC从Access中读取出来,再插入MySQL。不过那个速度是相当的慢。本来也想找一个软件来完成这项工作,但上网找了一下,似乎有一个这样的软件,不过是收费的,还是算了。

最近又在搞一个小玩意,《成语词典》,我从CSDN下载的源文件,原本是ASP+Access格式的,我又得把它转为MySQL,数据大概有13000条,我查了一下家里放着的那一本《学生常用成语词典》,不过才8000+条成语而已,可见这个数据还是比较全面的。

还好这次找到了一个Access To MySQL这个软件。这个软件是丹麦一家公司Bullzip开发的免费的软件。立即下载来试用了一下。感觉不错。首先要安装一个ODBC的软件(如果有安装IIS似乎会一起装,没有的话上MySQL官方网站下载)。

打开程序,选中要导出的MDB文件,

再填写MySQL服务器信息及要导入到的数据库名,

可以选择要导入的表和列

再设定“覆盖原表及数据”,“转存数据”,“转存索引”等设置,点击开始,即可开始转换过程。

我的大概13000条,4MB的数据也仅仅转换了30S左右,如果用PHP脚本写的话不知道要到猴年马月。

美中不足的是,这个软件对字符集的支持并不好,它不支持设定字符集,我第一次的时候导入以后数据全部是问号,因为它创建的表的字符集都是默认的拉丁_瑞典语字符集,而MDB文件的字符集是GB2312,后来我只好自己先创建好表,设定好字符集,再用导入数据的模式进行操作,操作完后一切正常。

再花了一个下午写了这个《成语词典》,欢迎大家使用。

PHP-Javascript“返回上一页”无缓存问题

星期三, 八月 27th, 2008

很多用PHP写脚本的朋友都会遇到这样的问题,比如一个注册页面(不使用任何AJAX),需要填写账号密码等信息,填写完后需要到服务端验证,如果验证不通过,就要让用户重新填写资料,这对很多用户来说这是一大煎熬,有可能就因此放弃了注册。遇到这种问题,一般有这几种解决方法:

1.仍然调用刚才的页面,输出错误提示,并把<input>中 value的值改为刚才用户输入的值。这应该是最好的方法,但缺点是要在这个页面的<input>的VALUE进行处理,比较麻烦。

2.还有很多懒人像我一样,遇到验证不通过,直接输出一个出错提示页面,并在页面中加入JavaScript的代码:

  1. <a href="javascript:window.history.back();">返回</a>
  2. <a href="javascript:window.history.go(-1);">返回</a>

这个代码是返回上一页的代码,返回后,除了密码类型的所有数据均会保留在网页中,这算是比较友好了。

但有很多朋友反应使用JS的返回后,网页上并没有数据的缓存,有时候却又有,真让人捉摸不定。前几天我在开发的时候也碰到了这个问题,上网Google许久未果,只好又从自己的代码分析入手。这时候,一句 session_start(); 引起了我的注意。session_start(); 是开启 $_SESSION 会话的函数,开启SESSION后,似乎是每次访问一个网页都要重新调用一次网页。我把这句话去掉以后,问题就解决了。如果遇到网页数据不能缓存的,不妨去掉SESSION试试 :)

PHPxref使用指南

星期五, 八月 22nd, 2008

PHPXref是一个十分优秀的PHP开发工具,它能将某一个程序(如Wordpress)中所有的函数、变量、常量等分类记录,生成一个HTML网页列表,你可以轻松地在这个列表中找到某个函数在什么位置被定义,在什么位置被引用。这一点无论是对于一个Wordpress插件开发者,还是想学习研究Wordpress的人都是十分有用的。

PHPXref官方有个已经制作好的Wordpress的分析文档:http://phpxref.com/xref/wordpress/,此外,PHPXref还制作了多种PHP程序的分析文档,有兴趣的可以Google站内搜索一下。

PHPXref的主要功能包括

1.文件管理。无论要找什么文件,用它能很快地搜索到,如果你的文件中有符合语法规则的注释,PHPXref还能将它列在文件名的旁边,更容易了解这个文件的功能用途,也不用为了找一个文件翻遍整个文件夹,打开每个文件查找注释了。

2.函数、变量、常量、类管理。Wordpress内置了多种功能强大的函数、类,无论是字符处理还是远程URL读取等都有现成的函数,但我们往往不知道这个函数能在Wordpress里面找到,现在容易多了,搜索一下就找到了,如果在开发过程中遇到某个Wordpress函数,不知道它是干什么用的,这时候就得找到这个函数在哪里定义的,可是Wordpress里面上百个文件上哪找去?还是用PHPXref好了。

3.文件包含管理。Wordpress中需要很多 include,require包含别的文件,但偶尔也会遇到重复包含导致出错,虽然require_once可以解决,但我们也最好要了解某个脚本包含了哪些文件,要调用这个文件时也心中有数。PHPXref提供了每个文件的包含文件列表和被包含的文件。

4.源代码高亮。这个功能也是比较实用的,但在实际测试中偶尔会出错。

5.出色的关联功能。在浏览源代码时,将鼠标指到某个函数名,就会在鼠标旁边出现函数的定义页面,以及被使用次数,此外,还对使用较多的变量名,也是可以直接有个页面显示所有的关于这个变量的使用情况。

既然PHPxref那么强大,该如何使用呢?

1.首先,从SF下载最新的程序,现在的版本是0.7,下载那个win32的版本就好了。下载后解压出来。

2.phpxref目录下有一个 source 的文件夹,这是存放源代码的文件夹,把另外下载的Wordpress源代码放到这里来,请注意,不要把 wordpress/这整个目录放进来,而是里面的文件放进来就行了,确保以 source/index.php,source/wp-content/ ..这样的格式就行。

3.运行可执行文件phpxref.exe ,将进行生成文档的工作,这个过程大约需要1分钟左右,由于需要高频率读取硬盘和大量计算消耗CPU资源,请暂停其他工作。

4.提示成功后,output 这个目录下就是所有的文档了,建议在本地上用XAMPP进行调试,把整个output 文件夹搬到 xampp的 htdocs 的目录下,再把名字改为好记的 phpxref ,这样,就可以通过 http://localhost/phpxref/ 访问了。效果和 http://phpxref.com/xref/wordpress/ 的是一模一样,当然,速度快了很多。

PHPXref还提供了在Linux下生成文档的版本,但我很少用Ubuntu,也没有去Ubuntu下测试了,我想更多数人需要的还是Win系统下的,如果有需要,把Win下生成的文档可以搬到服务器上去供大家访问,还可以在页面下面放点Google Adsense广告赚点外快。但PHPxref生成的文档实在太大了,一个1.2MB的Wordpress(压缩包),解压后再生成文档,居然要80多MB的位置!压缩完后也需要接近20MB,所以我打消了把它放在自己服务器上的愿望(说不定制作重复的镜像还会被搜索引擎处罚)。

除了用PHPXref来生成已有的Wordpress或其他PHP示范程序(如Discuz)进行学习外,用PHPXref来生成自己制作的PHP程序,进行检验错误或者是整理代码资源也很有用。我从学PHP至今大概写过5个比较大型的程序(我认为算比较大型了,但没有一个是成型的商业产品),几乎也是写了5次的邮件地址验证函数,用户名验证函数,密码验证函数,MySQL类…看来还得用PHPXref来整理资源了。

在使用PHPxref之前,我还读过awflasher.com提供的简介,特此感谢。

创建你的电子邮件联系页面

星期六, 八月 16th, 2008

无论是一个网站还是一个博客,站长与网友的互动,不但需要有一个QQ、Email,更需要一个在线的即时Email联系表单。在Wordpress博客中有很多插件能够实现这种功能。但如果发送一个邮件都得调用WP程序的话,速度慢、安全系数不高,不如单独创建一个联系页面。

创建一个feedback.php 页面

  1. <?php
  2.  
  3. $email = $_REQUEST['email'] ;//留言者的Email
  4. $message = strip_tags($_REQUEST['message']);//留言信息,去除HTML标记
  5. if(!empty($message)){
  6.     mail( "username@example.com", "Feedback Form Blog", $message.'From:'.$email , "From: username@example.com");//调用系统函数 mail() 发送邮件。
  7.     //第一个参数是接收者,第二个参数是标题,这里设置了固定的标题,第三个是留言信息,第四个实际上设置了发送者的邮箱,为了防止被邮件系统误判为垃圾邮件,且安全起见,最好不要用用户直接输入的邮箱。
  8.     header('Location:http://photozero.net/thankyou.html');//留言完转到感谢页面
  9. }
  10.  
  11. ?>
  12.  
  13. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  14. <html xmlns="http://www.w3.org/1999/xhtml">
  15. <head>
  16. <meta http-equiv="Content-type" content="text/html;charset=utf-8" />
  17. <title>Feedback</title>
  18. </head>
  19. <body>
  20. <!-- 创建一个提交信息的表单 -->
  21. <form method="post" action="feedback.php">
  22.     您的邮箱: <input name="email" type="text" /><br />
  23.     意见或建议:<br />
  24.     <textarea name="message" rows="15" cols="40"></textarea><br />
  25.     <input type="submit" value="提交" />
  26. </form>
  27. </body>
  28. </html>

需要有几个需要注意的地方。
1.mail() 函数。不是所有的空间都可以使用mail()函数的,要取决于所在的服务器是否有正确设置了sendmail,否则即使使用了mail()函数也是无法发信的。创建这个页面后最好自己试一下能否使用。一般来说,国外比较大的空间,如我用的Dreamhost,mail函数都配置得挺好的,可以直接用。而国内很多空间的服务水平很差,很多函数、PHP库都没有设置、启用。我曾经用过的某个国内空间就是这样,(甚至连 iconv 这个很重要的函数都不支持,PHP版本居然还是 4.2.5的,我问他们技术支持,让他们升级PHP版本,他们却无动于衷)如果mail() 函数无法使用,则可能需要使用一些第三方的MAIL库或MAIL类,我也没试过,下回找一个

2.编码。国内很多邮箱是采用了GB2312等编码,建议在mail()函数的第四个参数(邮件的HEADER)设置一下,如这个代码来取代mail函数

  1. function mailer($to,$subject,$content,$header = ""){
  2.     $header .= "Content-type: text/plain; charset=utf-8 \r\n";//设置邮件编码
  3.     $header .= "Content-Transfer-Encoding: 8bit\r\n";
  4.     $subject = "=?UTF-8?B?".base64_encode($subject)."?="; //对标题进行编码,
  5.     @mail($to,$subject,$content,$header);
  6. }
  7. mailer( "username@example.com", strip_tags($_REQUEST['title']), $message.'From:'.$email , "From: username@example.com");

其他CSS之类的自己随便做一下就好了,挺简单的吧:)

如何获取Alexa排名数据

星期一, 七月 28th, 2008

上回说到Alexa的排名数据来源于Alexa工具条,所以排名数据并不十分准确,特别是对于中文网站来说,国内装Alexa工具条的多是被某些网站“误导”的用户以及一些网站站长,所以很多人也对Alexa数据不以为然。在目前情况下,Alexa的排名还是和Google PR一样被广告商们看重的数据和作为衡量网站广告投放价值的依据。

这里讲讲如何获取Alexa的数据排名。最简单的莫过于装上Alexa提供的工具条了,Alexa提供了Firefox和IE的版本,但纯粹为了看一个网站的排名而安装这个插件显得有点浪费资源。我在Firefox浏览器用的是SearchStatus这个插件,这个插件同时显示了Google PR和Alexa排名,占用位置也不大,用起来比较方便。

本文着重要讲的是如何使用从Alexa的服务器下载数据,并进行分析后应用于WP插件或提供给访客(如 http://alexa.chinaz.com/这样的服务)。Alexa官方提供了收费的API接口,每千次查询$0.15(上回凭印象说是$0.1,更正一下),既然要收费,肯定没有多少人愿意花这钱了,特别在我们中国人看来更是难以理解,照理说用你Alexa的数据应该是相当给你面子,给你人气,你还要向我收费?还好早就有人破解了Alexa工具条(貌似很多国内网站强迫要求下载的Alexa工具条还经过改装,拥有木马功能了),并把它的服务器接口盗取出来分享给大家了。

接口一:

http://data.alexa.com/data/+wQ411en8000lA?cli=10&dat=snba&ver=7.0&cdt=alx_vw=20&wid=12206&act=00000000000&ss=1680×1050&bw=964&t=0&ttl=35371&vis=1&rq=4&url=http://www.baidu.com

接口二:

http://data.alexa.com/data/TCaX/0+qO000fV?cli=10&dat=snba&ver=7.0&cdt=alx_vw=20&wid=31472&act=00000000000&ss=1024×768&bw=639&t=0&ttl=4907&vis=1&rq=23&url=http://www.baidu.com

接口三:

http://data.alexa.com/data/ezdy01DOo100QI?cli=10&dat=snba&ver=7.0&cdt=alx_vw=20&wid=16865&act=00000000000&ss=1024×768&bw=775&t=0&ttl=1125&vis=1&rq=2&url=http://www.baidu.com

接口四:

http://data.alexa.com/data/+wQ411en8000lA?cli=10&dat=snba&ver=7.0&cdt=alx_vw=20&wid=12206&act=00000000000&ss=1680×1050&bw=964&t=0&ttl=35371&vis=1&rq=4&url=http://www.baidu.com

事实上,分析一下这些地址可以看到它已经将用户的浏览器信息,系统信息等发送给了服务端。

ezdy01DOo100QI是aid。
“cli=10&dat=snba&ver=7.0&cdt=alx_vw=20&”这部分是固定值。
wid是个随机数。
act数据包含了Alexa Toobar功能的被使用情况。
ss很明显是屏幕分辨率了。
bw是IE窗口的宽度。
t取值是0或1,和当前IE的window对象还有referrer有关。
ttl是当前页面打开速度,和Site Stats中的Speed有关。
vis表明IE是否显示工具条。
rq是对象计数器。

有了这些接口,我们就可以提供Alexa排名查询的服务了。

访问任意上述地址任意一个,查询baidu.com的信息,返回XML文件如下:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2.  
  3. <ALEXA VER="0.9" URL="baidu.com/" HOME="0" AID="=">
  4. <RLS PREFIX="http://" more="315">
  5. <RL HREF="www.3721.com/" TITLE="3 7 2 1"/>
  6. <RL HREF="search.21cn.com/" TITLE="21CN"/>
  7. <RL HREF="itsearch.ccidnet.com/" TITLE="itsearch.ccidnet.com/"/>
  8. <RL HREF="e.pku.edu.cn/" TITLE="e.pku.edu.cn/"/>
  9. <RL HREF="21cn.com/" TITLE="21cn.Com -"/>
  10. <RL HREF="163.com/" TITLE="163.com/"/>
  11. <RL HREF="search.163.com/" TITLE="search.163.com/"/>
  12. <RL HREF="dir.sohu.com/" TITLE="dir.sohu.com/"/>
  13. <RL HREF="cn.search.yahoo.com/" TITLE="cn.search.yahoo.com/"/>
  14. <RL HREF="yahoo.com/" TITLE="Yahoo!"/>
  15. </RLS>
  16. <SD TITLE="A" FLAGS="DMOZ">
  17. <TITLE TEXT="Baidu.com"/>
  18.  
  19. <ADDR STREET="The Ideal International Bldg, 12th floor" CITY="Beijing 100080,  " STATE="" ZIP="" COUNTRY="CHINA" />
  20. <CREATED DATE="11-Oct-1999" DAY="11" MONTH="10" YEAR="1999"/>
  21. <PHONE NUMBER="+86 1082607100"/>
  22.  
  23. <OWNER NAME="Baidu.com, sillyser"/>
  24. <EMAIL ADDR="baidu_dns_master@baidu.com"/>
  25. <LANG LEX="zh-CN"/>
  26. <LINKSIN NUM="58665"/>
  27. <SPEED TEXT="1062" PCT="82"/>
  28. <POPULARITY URL="baidu.com/" TEXT="11"/>
  29. <RANK DELTA="-2"/>
  30. <CHILD SRATING="0"/>
  31. <REACH RANK="13"/>
  32. </SD>
  33.  
  34. <KEYWORDS>
  35. <KEYWORD VAL="Chinese Simplified"/>
  36. </KEYWORDS><DMOZ>
  37.  
  38. <SITE BASE="baidu.com/" TITLE="Baidu.com" DESC="The leading Chinese language search engine, provides “simple and reliableâ€? search experience, strong in Chinese language and multi-media content including MP3 music and movies, the first to offer WAP and PDA-based mobile search in China.">
  39. <CATS>
  40. <CAT ID="Top/World/Chinese_Simplified/计算机/互联网络/搜寻/搜索引擎" TITLE="搜寻/搜索引擎" CID="1005774"/>
  41. </CATS>
  42. </SITE>
  43. </DMOZ>
  44. </ALEXA>

开头包括了一些反向链接的网站,中间是网站排名等信息,下面是网站介绍,网站管理员可以向Alexa添加这些信息。如果是比较不知名的小站,如我的http://photozero.net 信息就没有那么全了。

在前面的文章里提到了,调用Neekey API servicesAlexa rank显示图片还会提升Alexa排名,实际上指的就是在调用Alexa数据时,我们是模拟Alexa工具条进行查询的,所以你的博客的Alexa排名自然就提升上去了,不信您试试?我在Firefox里装上SearchStatus插件后,每天访问自己的博客一会儿,眼睁睁看着Alexa排名从300W排名开外冲到目前的110W。

PHP中获取文件排名的方法

  1. $content = file_get_contents('$alexaURL'); //自行将URL放入,如果服务器的file函数没有开启ALLOW_URL_OPEN 选项(如Dreamhost),应该用 fsockopen 等函数替代。
  2. $pattern = '/<POPULARITY URL="\s*(.+?)" TEXT="\s*(.+?)"\/>/'; //在XML中匹配的 <populartity />项里面的数据就是Alexa排名了
  3. preg_match($pattern, $content, $match); //进行匹配搜索
  4. echo $match[2]; //$match[2] 就是排名了。
  5. //如果需要其他信息就自己写个匹配模式,从里面提取出来就行了。当然用PHP提供的XML处理函数也是可以的。

除了在服务端调用进行输出外,做个AJAX调用的查询程序也不错,还节省了服务器资源。下次抽空做个放出来。

PHP创建(中/英文字)图片

星期天, 七月 27th, 2008

这个PHP代码是我做的一个程序的一部分,现在贴出来分享一下。这个代码的功能是创建一个图片,不但可以用自定义字体在图片上写英文,也可以写中文了!这个代码适用于验证码、给图片加水印等功能。

  1. <?php
  2. /*
  3. Photozero.net 改编自PHP参考文档
  4. */
  5.  
  6. //设置Header,如果输出图片不成功,请先暂时去掉这代码,查看错误信息
  7. header("Content-type: image/png");
  8. header("Cache-Control: no-cache");
  9.  
  10. $zh_text = '黑体';
  11. $en_text = 'Test';
  12. //要输出的字
  13.  
  14. $zh_font = 'simhei.ttf';
  15. $en_font = 'arial.ttf';
  16. //字库的文件名。建议中文字体和E文字体用不一样的,因为宋体、黑体字库里的英文实在不咋滴
  17. //这里用的都是TTF字体。懒得上网找就到 C:\WINDOWS\Fonts 下,Copy几个字体到程序目录下就好了
  18.  
  19. // 创建一个真彩的图片背景,参数是 X长 ,Y宽。
  20. $im = imagecreatetruecolor(400, 400);
  21. //或者可以调用已有的PNG图片等 : $im = imagecreatefrompng('background.png');
  22.  
  23. // 定义几个色彩
  24. $white = imagecolorallocate($im, 255, 255, 255);
  25. $grey = imagecolorallocate($im, 128, 128, 128);
  26. $black = imagecolorallocate($im, 0, 0, 0);
  27.  
  28. //填充背景为白色
  29. imagefill($im, 0, 0, $white);
  30. //将背景透明化
  31. imagecolortransparent($im,$white);
  32. //以上两行是创建透明图片的关键!
  33. //很多人反应, imagecreatetruecolor创建后的图片,背景颜色是黑的,无论怎么修改都不能变成白色的
  34. //我先将背景填充为白色,再做透明处理就可以了!在Firefox3和IE7下测试成功!
  35.  
  36. // 这是一个很简单的产生阴影的效果。
  37. //先在原本要输出的位置的偏左下角一点点输出灰色的字体,接着再用黑色字体写上去就有阴影效果了
  38. //下次再提供点别的花样~
  39. //imagettftext($im, 20, 0, 11, 21, $grey, $en_font, $en_text);
  40.  
  41. // 写入字体
  42. imagettftext($im, 12, 0, 100, 120, $black, $en_font, $en_text);
  43.  
  44. imagepng($im);
  45. imagedestroy($im);
  46. // 不用说了,输出图片,然后清除缓存
  47.  
  48.  
  49. //函数都是用PHP内置的,如果有不了解的请参考一下文档。
  50. ?>

整个代码的功能是比较单一的,但这是一个创建图片比较基本的框架。无论是做验证码还是要提供显示IP的服务,只要略微修改就很快能用了。就留着这代码备用吧,以后哪天说不定就用上了。

调用Google PageRank

星期五, 七月 25th, 2008

很多站长都关心自己小站的Google PageRank值,倒不一定是希望PR值高了好做广告之类的,但PR作为一种比较客观的评价网站重要程度的工具,谁都希望它越高越好。

这里浅谈一下调用Google PageRank的方法。前面先说访客查看PR的方法,后面介绍程序中调用PR的方法。

浏览器调用:

我用的是Firefox3浏览器,Google为FF浏览器制作了一个工具栏(也提供了含Google工具栏的FF版本),但从我个人的使用情况来看,装载了GG工具栏的FF在启动时反应超慢,如果以我的电脑配置,FF启动需要3秒钟的话,加上GG工具栏就要20秒以上!估计第一次启动时GG工具栏要从Google调用Gmail等各种服务的最新信息,花费了不少时间。(前年我第一次尝试FF的时候就是下载“带Google工具栏的Firefox”,结果启动花了将近半分钟,让我误认为FF就是这么差劲,后来才知道是GG工具栏那么差劲)

所以我不建议FF用户装上Google工具条,还是装上一个叫SearchStatu的FF插件,该插件不但提供了Google PR的调用,也提供了Alexa的排名查询,是每个站长必备的Firefox工具。如果是IE用户,那只能装上Google工具条了,似乎GG工具条在IE下表现还不错,至少不会占用太多启动时间。

站点查询:

国内外很多站长工具站都提供了Google PageRank的查询,其实他们的数据来源大多数是本文下面所说的从Google服务器调用PR数据的方法。像国内比较著名的有zQueryChinazWebmasterhomeAdmin5。他们除了提供网页查询以外,有些还提供了<img>图片的调用,可以在你的网页里以图片方式显示PR值,(但大多数强制要求你加上他们的链接,“否则就把你加入黑名单”之类的,个人认为这些站实在是小气至极),国外有些PR查询站点还提供API接口免费在程序中调用,如TRYNT(这站在国内访问很不稳),而国内连调用图片还要你留着链接,更没有哪个站愿意提供API接口了。

服务器调用:

Google可以算得上Web2.0的先驱了,他们的产品如Google Map,Google Search大多提供了API接口以供程序开发,但Google PageRank却没有提供API接口,于是国外的高手们便通过破解Google工具栏,得出了向Google服务器请求PR数据的接口。

这里是一个Pagerank查询的完整PHP代码pagerank.zip,其中包括了范例演示、PR图标等,可以立即应用于服务。需要注意的是,该程序中使用了或异运算,它的值超出了32位的范围,故不能在Linux系统中使用,而Win系统是正常的。(本想贴这个代码,但服务器却提示503错误,所以不能贴出来讲解了,pagerankcode.com提供了这个代码以及使用范例)

后记:写这篇文章其实是想在我的WP插件中应用PR值,但迟迟未找到合适的API接口,自己的空间都是Linux的,不能运行该代码,郁闷。另一个想法就是国内的网站很小气,提供点服务都要讲那么多条件,更可笑的是PR查询服务本是一个很公开的服务,他们却当作自己的摇钱树般抱着,不是很可笑吗?

Technorati API教程

星期三, 七月 23rd, 2008

最近在做一个WP插件,需要用到一些博客的排名等信息,ALEXA也提供,Technorati也有,但权衡一下,还是决定用Technorati的数据更好。Technorati是一家比较专注于WEB2.0的博客网站,它提供了博客搜索、博客排名、反向链接搜索、TAG归类搜索等服务。相比Alexa的工具条统计,它依据博客的反向链接等数据进行排名,数据更加客观。

选择Technorati更重要的是Technorati提供了完整的API接口以供应用,虽然ALEXA也提供了接口,却是要收费的,似乎是千次查询$0.1,这让大多数非商业应用的人无法接受。当然Alexa也有几个工具栏的接口被破解后可以盗用,不过个人认为Technorati的数据质量要好于Alexa,决定在插件中使用Technorati的数据。

使用Technorati,先要注册一个Technorati账户,接着访问http://technorati.com/developers/apikey.html,免费获取一个API KEY 如 dfe71294d89ebbca982c98ecd73c96d5 ,正常情况下,一个API KEY每天可以查询500次,这对于一个WP插件应该是足够应用了。


API KEY

如何应用?Technorati提供了包括博客信息,博客搜索,博客反向链接在内的多种搜索服务的接口,可以访问这里获得更多信息。


Technorati提供的接口类型

以我需要用到的博客信息为例

访问http://api.technorati.com/bloginfo?key=[apikey]&url=[blog url],其中[apikey]替换为API KEY,[blog url]就是要查询的博客URL,如 http://photozero.net (http:// 可省略),在PHP文件中用 file_get_contents() 或 fsockopen() 等方式访问,获取返回内容如:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <!-- generator="Technorati API version 1.0" -->
  3. <!DOCTYPE tapi PUBLIC "-//Technorati, Inc.//DTD TAPI 0.02//EN" "http://api.technorati.com/dtd/tapi-002.xml">
  4. <tapi version="1.0">
  5. <document>
  6. <result>
  7. <url>http://photozero.net</url>
  8. <weblog>
  9. <name>零号相册</name>
  10. <url>http://photozero.net</url>
  11.  
  12. <rssurl>http://photozero.net/feed/rss/</rssurl>
  13. <atomurl>http://photozero.net/feed/</atomurl>
  14. <inboundblogs>16</inboundblogs>
  15. <inboundlinks>23</inboundlinks>
  16. <lastupdate>2008-07-20 03:52:34 GMT</lastupdate>
  17. <rank>446726</rank>
  18.  
  19. <authors>
  20. </authors>
  21. </weblog>
  22. <inboundblogs>16</inboundblogs>
  23. <inboundlinks>23</inboundlinks>
  24. </result>
  25. </document>
  26. </tapi>

这里面包括了博客名,博客URL,博客排名,博客RSS地址,反向链接等多种信息,是不是很齐全?

再来一个博客TAG搜索的示范,显示你的博客里有哪些热门TAG,访问
http://api.technorati.com/blogposttags?key=[apikey]&url=[blog URL]
照例把[apikey]替换为API KEY,把[blog URL]替换为 http://photozero.net,就会返回我的博客中的TAG(分类也算在TAG里面了)

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <!-- generator="Technorati API version 1.0 /blogposttags" -->
  3. <!DOCTYPE tapi PUBLIC "-//Technorati, Inc.//DTD TAPI 0.02//EN" "http://api.technorati.com/dtd/tapi-002.xml">
  4. <tapi version="1.0">
  5. <document>
  6. <result>
  7. <querycount>20</querycount>
  8. </result>
  9. <item>
  10. <tag>Free Talk</tag>
  11. <posts>17</posts>
  12. </item>
  13. <item>
  14. <tag>wordpress</tag>
  15.  
  16. <posts>13</posts>
  17. </item>
  18. <item>
  19. <tag>Free_talk</tag>
  20. <posts>9</posts>
  21. </item>
  22. <item>
  23. <tag>Plugin</tag>
  24. <posts>7</posts>
  25. </item>
  26. <item>
  27. <tag>WAP</tag>
  28.  
  29. <posts>6</posts>
  30. </item>
  31. <item>
  32. <tag>PHP</tag>
  33. <posts>5</posts>
  34. </item>
  35. <item>
  36. <tag>Server</tag>
  37. <posts>4</posts>
  38. </item>
  39. <item>
  40. <tag>Mobile</tag>
  41.  
  42. <posts>3</posts>
  43. </item>
  44. <item>
  45. <tag>Baidu</tag>
  46. <posts>2</posts>
  47. </item>
  48. <item>
  49. <tag>Blog</tag>
  50. <posts>2</posts>
  51. </item>
  52. <item>
  53. <tag>Google</tag>
  54.  
  55. <posts>2</posts>
  56. </item>
  57. <item>
  58. <tag>Javascript</tag>
  59. <posts>2</posts>
  60. </item>
  61. <item>
  62. <tag>Yahoo</tag>
  63. <posts>2</posts>
  64. </item>
  65. <item>
  66. <tag>chinese</tag>
  67.  
  68. <posts>2</posts>
  69. </item>
  70. <item>
  71. <tag>DreamHost</tag>
  72. <posts>2</posts>
  73. </item>
  74. <item>
  75. <tag>web20</tag>
  76. <posts>1</posts>
  77. </item>
  78. <item>
  79. <tag>Ajax</tag>
  80.  
  81. <posts>1</posts>
  82. </item>
  83. <item>
  84. <tag>Apple</tag>
  85. <posts>1</posts>
  86. </item>
  87. <item>
  88. <tag>iPhone</tag>
  89. <posts>1</posts>
  90. </item>
  91. <item>
  92. <tag>IP</tag>
  93.  
  94. <posts>1</posts>
  95. </item>
  96. </document>
  97. </tapi>

好了,其他几种应用就不多介绍了,如果有需要应用相关服务的不妨一试。这里推荐一个老外Kailash Nadh写的Technorati API应用的PHP类——Duck Soup,到他主页下载这个库,里面包含了一个应用范本,用这个代码就可以轻松应用Technorati服务了,不用再自己弄一些fsockopen的下载类了。

PHP判断手机(cellphone,mobile,wap)访问函数

星期天, 七月 20th, 2008

前一段时间发布了一个判断搜索引擎Robot的函数 is_robot() ,而最近又发布了一个Go2Wap插件,用于手机访客访问WP时自动转跳到 /wap/ 页面,这个插件发布后,有朋友就向我报告一些Bug,这里结合我遇到的问题综合讲解一下。

先看一下这个判断函数:

  1. function is_wap(){
  2.     $ua = strtolower($_SERVER['HTTP_USER_AGENT']);
  3.     $uachar = "/(nokia|sony|ericsson|mot|samsung|sgh|lg|sie|philips|panasonic|alcatel|lenovo|cldc|midp|wap|mobile)/i";
  4.     if(($ua == '' || preg_match($uachar, $ua))&& !strpos(strtolower($_SERVER['REQUEST_URI']),'wap')){//如果在访问的URL中已经找到 wap字样,表明已经在访问WAP页面,无需跳转,下一版本增加 feed访问时也不跳转
  5.         return true;
  6.     }else{
  7.         return false;
  8.     }
  9. }

这个函数跟上次发布的is_robot()函数基本类似,$uachar里面的是各种手机常见的USER_AGENT:

  • nokia 诺基亚
  • sony,ericsson 索尼爱立信,爱立信
  • mot 摩托罗拉
  • samsung,sgh 三星
  • lg LG
  • sie 西门子
  • philips 飞利浦
  • panasonic 松下
  • alcatel 阿尔卡特
  • lenovo 联想
  • cldc,midp,wap,mobile 这主要针对国内一些MTK平台及早期的手机,这些手机支持CLDC和MIDP,WAP1.1/WAP2.0标准等,故可以认定为手机访客

由于我的水平有限,还没有搞定一些Windows Mobile及其他一些智能手机的USER_AGENT,但国内的主流还是诺基亚,索爱,摩托,三星等,个人觉得上面的这些关键字已经能判断 95%以上的手机了。

您肯定会对$ua == ”产生疑问,为什么USER_AGENT为空也算手机访问?这也是符合咱们特殊国情的,而且,整个插件起作用的也许恰恰就是这一句。当手机用户通过移动梦网访问网站时,中国移动出于某些经济利益的因素,会自动过滤掉访问非SP网站的USER_AGENT,也就是手机用户访问移动梦网首页,收费铃声下载等网页时会提交USER_AGENT,而访问其他网站时,USER_AGENT却是空的。不信您使用Firefox,装上User Agent Switcher,调一个空的USER_AGENT访问 www.google.cn 试试,同样也是转跳到Google的WAP页面,至于联通,我没试过,不过有网友反应也是同样的状况。

另有朋友反应”firefox下用的好好的,可是用IE浏览就自动跳的wap里面了,有人用遨游浏览时也告诉我会自动跳转“,由于他也没有贴出具体的USER_AGENT,我恳请所有遇到BUG的先向我报告一下您的USER_AGENT,如何报告?您只需做一个简单的动作:访问 http://photozero.net/ua.php 我会在数据库记录您的USER_AGENT(仅记录USER_AGENT,不记录其他IP之类的信息,隐私权我负)

在综合分析大家的数据后,我会做出改进,也恳请大家提出意见建议,谢谢。
*ps 本站所有原创、改编的PHP、JS等代码,您均可以自由使用于其他Wordpress插件,或其他任何PHP程序,转换成ASP,JSP也可以,请保留出处,谢谢!

IP转物理地址的原理

星期六, 七月 12th, 2008

我最近刚做了一个根据IP显示所属国家国旗的PHP程序,这里讲讲它的实现方法。

首先,IP对应的国家是比较好查的,ICANN及其它几个机构都有关于某个IP段所属国家和ISP信息,并且他们基本上都提供了免费查询。但难题在于每个洲的管理机构不同,且数据量庞大,不易收集。将IP对应到某个国家的某个ISP后还要了结到它是分配给哪个地区(城市)的,比如中国电信福建分公司的IP段会分给厦门、福州等城市,而相对于这个就是比较难找了,可能ISP会有数据库会提供查询,可能也查不到,这些数据的来源就靠平时的积累、用户的贡献了。

当然,现在许多出名的数据库经过几年的发展已经比较完整和详细了,像免费的纯真数据库都有十几万条了,如过向国外的商业网站购买企业级应用的数据库,它的准确度就有点惊人了。国外的 ip2location.com 提供的数据库就是如此,作为一个英文数据库,它除了对美国等地区的数据比较完整以外,甚至中国的数据的精确程度都不亚于国内的数据库。它还提供了IP对应的经纬度,如果搭配Google 提供的Google Earth 的API,就可以在网页上看到Google Earth了。

就保存的方法来看,一般有一个文件(如纯真的QQwry.dat)或数据库。在数据量庞大(如几十万条)的情况下,用文件保存明显优于数据库,这一点在后面会详解。无论采用哪种方式保存数据,它的一般格式为:

起点IP,终点IP,国家,地区
33996344,33996351,United Kingdom,XXX

某 些比较详细的数据库还有ISP,国家缩略名,对应邮编,甚至该地的经纬度!起点IP,终点IP不是我们常见的 XXX.XXX.XXX.XXX的形式,而是一个8-10位十进制数字构成的。这也是为了便于数据的搜索。该数据由IP转换而成,在PHP中有 ip2long() 函数可以转换,自己也可以写一个相同的函数

  1. function dottedquad2long($ip){
  2. $ip_arr = split('\.',$ip);
  3. $iplong = (16777216 * $ip_arr[0]) + (65536 * $ip_arr[1]) + (256 * $ip_arr[2]) + $ip_arr[3];
  4. return $iplong;
  5. }

在一个文件的数据库中,通常每个数据间用某种间隔符间隔,当要查找一个IP如64.233.189.104,先将该IP转化为十进制数字 1089060200 ,再在文件中多次利用二分法查找该IP对应的区间,约通过10-20次查找,就可以准确地找到对应的位置了。

另外一种利用数据库保存数据的方法相比于文件的查找,PHP做的工作比较简单,但交给MySQL做的任务就比较艰巨了。现在一般的小型的数据库(如我找到的只有国家信息的数据),都有十万余条。要在那么多的数据库中查找一个区间,使用的时间倒不如用文件查找来得快。
关于查找数据在数据库和文件分别所用的时间我在上一篇文章中有提到过,一般来说用文件保存的数据查找速度明显优于数据库。

接下来就是我的完整的IP查询的方法了

数据库信息
数据库 ip 中表 ipdata 里面有:

id
startipnum 起点IP数字 如:33996344
endipnum终点IP数字 如:33996351
areaslug 国家/地区缩写 如:GB
area 国家全名 如: United Kingdom

  1. <?php
  2.  
  3. //调用的图片类型,默认gif
  4. if($_GET['imgtype'] == 'png'){
  5.     $imgtype = 'png';
  6. }else{
  7.     $imgtype = 'gif';
  8. }
  9.  
  10. //分析请求(支持IP,主机查询)
  11. if(!$_GET['s']){
  12.     $ip = $_SERVER["REMOTE_ADDR"];//无请求,查询访问者的IP信息
  13. }else{
  14.     $s = trim(strtolower($_GET['s']));//转换为小写
  15.     if(ereg('[a-z]',$s) && substr($s ,-1,1) != 'x'){
  16.         $ip = gethostbyname($s);//如果是主机,则转换为对应IP
  17.     }else{
  18.         if(substr($s ,-1,1) == 'x'){
  19.             $ip = str_replace('x','0',$s);//为用户隐私考虑,允许最后一位用英文字符x取代。
  20.         }else{
  21.             $ip = $s;
  22.         }
  23.     }
  24. }
  25. $ip = long2ip(ip2long($ip));
  26. $sip = sprintf('%u',ip2long($ip));
  27. //再进一步分析整理出合法的IP地址,并转换为数字形式,便于在数据库中查找
  28. $sql = "SELECT * FROM `ipdata` WHERE $sip >= `startipnum` AND $sip <= `endipnum`";
  29. //组织SQL在数据库中查找IP对应的区间
  30. $link = mysql_connect("localhost", "root", "");
  31. mysql_select_db('ip', $link);
  32. $result = mysql_query($sql);
  33. while ($row = mysql_fetch_array($result)) {
  34.     $return = $row;
  35. }
  36. //进行查询,得出结果
  37. if(!$return['areaslug'] || $return['areaslug'] == '-h'){//没有结果或结果位置,返回问号的图标
  38.     header('Content-type: image/png');
  39.     readfile('icon/png/other.png');
  40. }else{//根据调用格式不同分别调用对应的图标
  41.     if($imgtype == 'png'){
  42.         header('Content-type: image/png');
  43.         readfile('icon/png/'.strtolower($return['areaslug']).'.png');
  44.     }else{
  45.         header('Content-type: image/gif');
  46.         readfile('icon/gif/'.strtolower($return['areaslug']).'.gif');
  47.     }
  48. }
  49.  
  50. ?>

具体的数据库文件和完整的PHP程序我会在稍后打包提供。