[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
Now Loading...