[2008-07-23 08:11:44] 基于Picasa、PHP、AJAX的图片REST架构的简单实现(3)
//NOTOC
前情提要:[blog:98|基于Picasa、PHP、AJAX的图片REST架构的简单实现(1)]
[blog:99|基于Picasa、PHP、AJAX的图片REST架构的简单实现(2)]
之前我们从远端获得了图片信息,但是这些和REST还是不沾边的。访问同一个URL,要想获得不同的信息,以目前的软硬件条件,最好的实现方法还是对HTTP Headers进行处理。所以这次的话题是——
====Step.2 服务器端接受不同的HTTP Headers返回不同的信息====
既然是服务器端,我们仍然采用PHP实现。
PHP对于Header信息的处理是很丰富的,常见的Header都已经存放在预定义变量$_SERVER中了。如果你对什么是Header还没有概念,可以在Firefox中安装一个[https://addons.mozilla.org/en-US/firefox/addon/3829|Live HTTP Headers]自行体验一下。
现在问题是:如此之多的Header,到底选择哪个或者哪几个来进行分析?用户的客户端语言,浏览器,IP等等,都是可以进行发挥的。这里为了简单说明问题,选择REQUEST_METHOD,HTTP_REFERER以及HTTP_X_REQUESTED_WITH来进行演示。
简单说明这三个参数:
*REQUEST_METHOD是页面的请求方法,也是目前REST实现的核心。
*HTTP_REFERER包含了用户的访问来源,一般是用户前一个访问的URL
*HTTP_X_REQUESTED_WITH则代表这是一个Xmlhttprequest请求,可以简单的看成是Ajax请求。
以下就是个人的随意发挥了,我所约定的有效服务器反馈包括:
*因为不涉及更新等操作,页面的请求方法只限于GET
*如果HTTP_REFERER存在,即说明用户在网页中或者通过链接点击访问照片,服务器返回照片的缩略图。
*如果HTTP_REFERER不存在,说明用户直接通过URL访问图片,服务器返回照片的全图。
*如果HTTP_X_REQUESTED_WITH存在,则说明用户在通过Ajax访问图片,这时返回一个Json格式的照片信息
形象一点用实例说明的话:
[http://allo.ave7.net/lab/photo_rest/photo/picasa/allovince/5213571636180988625/5213571644436936978|点击链接]会看到照片的缩略图,将这张照片的地址粘贴到浏览器地址栏直接访问的话,会看到照片的大图。而在[lab:/photo_rest/demo2.html|Demo]中,点击下面的按钮,则可以看到发送Ajax请求到同一个地址时的反馈。
最后还是附上服务器端的代码
require_once 'XML/Unserializer.php';
$Unserializer = &new XML_Unserializer();
$options = array('parseAttributes' => true);
$Unserializer->setOptions($options);
if($userid && $albumid && $photoid) {
$xml = "http://picasaweb.google.com/data/feed/api/user/".$_GET['userid']."/albumid/".$_GET['albumid']."/photoid/".$_GET['photoid'];
$status = $Unserializer->unserialize($xml,true);
//XML文件解析出错, 报错并退出
if (PEAR::isError($status)) {
die($status->getMessage());
exit;
}
//如果是一个AJAX访问,返回JSON描述
elseif($_SERVER['REQUEST_METHOD'] == 'GET' && $_SERVER['HTTP_X_REQUESTED_WITH']){
$pic = $Unserializer->getUnserializedData();
$part = explode('.',$pic['media:group']['media:content']['url']);
$json = json_encode(array(
'title' => $pic['media:group']['media:description']['_content'] ? $pic['media:group']['media:description']['_content'] : $pic['title']['_content'],
'date' => gmdate("F d Y H:i:s",strtotime($pic['updated'])),
'ext' => $part[count($part) -1],
'full' => $pic['media:group']['media:content']['url']
));
echo "($json)";
}
//HTTP_REFERER有无的区分
elseif($_SERVER['REQUEST_METHOD'] == 'GET' && $_SERVER['HTTP_REFERER']) {
$pic = $Unserializer->getUnserializedData();
header("Content-Type: image/jpeg");
curl_exec(curl_init($pic['icon']));
}
elseif($_SERVER['REQUEST_METHOD'] == 'GET' && !$_SERVER['HTTP_REFERER']) {
$pic = $Unserializer->getUnserializedData();
header("Content-Type: ".$pic['media:group']['media:content']['type']);
curl_exec(curl_init($pic['media:group']['media:content']['url']));
}
}
Read More
[2008-07-18 05:05:19] PHP Wiki语法解析类
//NOTOC
出于很多考虑,终于还是扔掉了[http://pear.php.net/|Pear]的[http://pear.php.net/package/Text_Wiki/redirected|Text_wiki]改用自己写的Wiki语法解析,专用于本[blog:av_framework|Framework]。比起Text_wiki来改善,或者说是按自己的习惯改变了很多方面:
#语法上综合了[http://wikipedia.org/|wikipedia]和[http://c2.com/cgi/wiki?PukiWiki|puki wiki]。
#支持html标记插入。
#生成的代码通过W3C Strict验证。
#即使不做解析,也是一篇表意良好,格式工整的text文档,而不像很多乍看上去如天书一般的Wiki语法
#解析速度比Text_wiki快
#加入了很多方便的特殊标记。
目前只是发布前的演示,正式版将附加在Framework中发布,有兴趣的同学可以索取源代码。那么,实验开始:
===Title Test===
Wiki代码:
=h1= ==h2== ===h3=== ====h4==== =====h5===== ======h6====== =======h7=======转换结果: =h1= ==h2== ===h3=== ====h4==== =====h5===== ======h6====== =======h7======= ---- ===Table Test=== Wiki代码:
! 1 ! 2 ! 3 ! 4 ! 5 ! ! 1 | 2 | 3 | 4 | 5 | ! 1 2 !| 3 | 4 | 5 | ! 1 2 || 3 | 4 | 5 | ! 1 | 2 3 || 4 | 5 | ! 1 | 2 | 3 4 || 5 | ! 1 | 2 | 3 | 4 5 || ! 1 2 3 !!| 4 | 5 | ! 1 | 2 3 4 ||| 5 | ! 1 | 2 | 3 4 5 ||| ! 1 2 3 4 !!!| 5 | ! 1 | 2 3 4 5 |||| ! 1 2 3 4 5 ||||| ! ---------- ! ----------- ! ---------- ! !left | right| middle |转换结果: ! 1 ! 2 ! 3 ! 4 ! 5 ! ! 1 | 2 | 3 | 4 | 5 | ! 1 2 !| 3 | 4 | 5 | ! 1 2 || 3 | 4 | 5 | ! 1 | 2 3 || 4 | 5 | ! 1 | 2 | 3 4 || 5 | ! 1 | 2 | 3 | 4 5 || ! 1 2 3 !!| 4 | 5 | ! 1 | 2 3 4 ||| 5 | ! 1 | 2 | 3 4 5 ||| ! 1 2 3 4 !!!| 5 | ! 1 | 2 3 4 5 |||| ! 1 2 3 4 5 ||||| ! ---------- ! ----------- ! ---------- ! !left | right| middle | ---- ===Paragraph Test=== Wiki代码:
//Remark will not be parse This is a normal paragraph. This is another normal paragraph. This is a paragraph with newline of br mark. This is a paragraph with newline of br mark. This is a paragraph with newline of br mark.转换结果: //Remark will not be parse This is a normal paragraph. This is another normal paragraph. This is a paragraph with newline of br mark. This is a paragraph with newline of br mark. This is a paragraph with newline of br mark. ---- ===Blockquote Test=== Wiki代码:
> Blockquote Level1 >> Blockquote Level2 >> Blockquote Level2 >>> Blockquote Level3转换结果: > Blockquote Level1 >> Blockquote Level2 >> Blockquote Level2 >>> Blockquote Level3 >>> Blockquote Level3 ---- ===List Test=== Wiki代码:
* ul list level1 ** ul list level2 ** ul list level2 *** ul list level3 **** ul list level4 **** ul list level4 * ul list level1 ** ul list level2 * ul list level1 # ol list level1 ## ol list level2 ## ol list level2 ### ol list level3 #### ol list level4 #### ol list level4 # ol list level1 ## ol list level2 # ol list level1转换结果: * ul list level1 ** ul list level2 ** ul list level2 *** ul list level3 **** ul list level4 **** ul list level4 * ul list level1 ** ul list level2 * ul list level1 # ol list level1 ## ol list level2 ## ol list level2 ### ol list level3 #### ol list level4 #### ol list level4 # ol list level1 ## ol list level2 # ol list level1 ---- ===Advance Test=== Wiki代码:
Wiki Parser can identify a url [http://allo.ave7.net/] or an image [http://www.ave7.net/logo.gif] with [http://allo.ave7.net/|account]. You can also use <i><b>Html Marks</b></i> inline. How forcibly specify this is a url [link:http://www.ave7.net/logo.gif] or an image [img:http://allo.ave7.net/photo/picasa/allovince/5220926002522558673/5220926248939178194|photo].转换结果: Wiki Parser can identify a url [http://allo.ave7.net/] or an image [http://www.ave7.net/logo.gif] with [http://allo.ave7.net/|account]. You can also use Html Marks inline. How forcibly specify this is a url [link:http://www.ave7.net/logo.gif] or an image [img:http://allo.ave7.net/photo/picasa/allovince/5220926002522558673/5220926248939178194|photo]. Read More
[2008-06-27 07:39:08] 基于Picasa、PHP、AJAX的图片REST架构的简单实现(2)
//NOTOC
前情提要:[blog:98|基于Picasa、PHP、AJAX的图片REST架构的简单实现(1)]
在前面展示的[lab:/photo_rest/demo3.html|DEMO]中,迫不及待的同学或许已经打开图片链接看过了,但很遗憾,这张图片并不存在于ave7.net的服务器上。我们首先要了解的是标题中的第一个主角Picasa。
来自Google的Picasa无疑是目前互联网最富有代表性的网络相册之一,而我选择Picasa而不是其他风头更劲的Flickr等等的原因有三:
#Google的服务很稳定
#API有很大发挥的余地
#强劲的客户端支持
Picasa的API文档在[http://code.google.com/apis/picasaweb/overview.html|这里],有兴趣的同学可以自行慢慢研究,关于本文所涉及的内容,我们只需要知道两点:
*Picasa的API是以RSS形式发布的
*在Picasa中准确定位一张图片需要三个参数:用户名、相册id、相片id
所以在上面的URL中,我们引入这三个参数,经由解析Picasa的API,就可以得到这张图片的所有信息:缩略图、原图、拍摄地点、标签……不一而足。而上述URL,则是我们提到的服务器端的请求分析器,用PHP来实现。
====Step.1 服务器端解析Picasa API并显示缩略图====
为了更好完成这个目标,这里涉及的知识有
#借助Apache的[http://httpd.apache.org/docs/2.2/rewrite/|URL Mod_Rewrite]模块来规整URL;
#利用PHP的[http://php.net/manual/en/book.curl.php|Curl]函数组来获取远端文件;
#用PHP的[http://pear.php.net/|PEAR]库中的[http://pear.php.net/package/XML_Serializer|XML_Serializer]来解析XML文件;
当然本文的重点不是详细讲解以上这些技术,编码上的细节问题会一笔带过,文章的核心始终是框架的搭建。
假设服务器PHP文件名为_loadpic.php,在mod_rewrite模块开启后,同目录下建立一个.htaccess文件,内容为
RewriteEngine On RewriteRule ^photo\/picasa\/(\w+)\/(\d+)\/(\d+) _loadpic.php?userid=$1&albumid=$2&photoid=$3_loadpic.php文件的内容为
//引入XML_Serializer
require_once 'XML/Unserializer.php';
$Unserializer = &new XML_Unserializer();
$Unserializer->setOptions(array('parseAttributes' => true));
if($userid && $albumid && $photoid) {
$xml = "http://picasaweb.google.com/data/feed/api/user/".$_GET['userid']."/albumid/".$_GET['albumid']."/photoid/".$_GET['photoid'];
$status = $Unserializer->unserialize($xml,true);
//XML文件解析出错, 报错并退出
if (PEAR::isError($status)) {
die($status->getMessage());
exit;
}
$pic = $Unserializer->getUnserializedData();
header("Content-Type: image/jpeg");
//Curl获得远端文件,Curl模块需要在PHP.ini的单独开启。
curl_exec(curl_init($pic['icon']));
}
}
而通过以上处理,我们达到了初步的目标:通过用户名、相册id、相片id三个参数定位一张照片,访问并解析Picasa API并获得我们需要的图片,然后显示出来。
[lab:/photo_rest/demo1.html|这里]是我们初步实现的结果。
Read More
