@ZEAL Blog·厉
WWW Zeal Blog
We stand alone,
TOGETHER.
+ 0 - 0 | §unbuffered queries are active问题

使用 PDOStatement->execute() 执行查询时出现错误:

Message: SQLSTATE[HY000]: General error: 2014 Cannot execute queries while other unbuffered queries are active.  Consider using PDOStatement::fetchAll().  Alternatively, if your code is only ever going to run against mysql, you may enable query buffering by setting the PDO::MYSQL_ATTR_USE_BUFFERED_QUERY attribute.

经过测试发现是因为在前一次 execute 里面执行了多条SQL语句(即通过分号分隔连续执行了多次的select/insert/update)。

http://blog.stormwild.net/2009/04/21/cannot-execute-queries-while-other-unbuffered-queries-are-active/

看上去应该是 Pdo_Mysql 库本身存在的问题?没有找到比较好的解决方案。唯一比较笨的方法是:在执行了 multi-query 语句之后立即 closeConnection ,断开本次数据库连接。再下次查询之前先重新建立连接。这样 unbuffered queries 就被重置了。

标签 ( PHP ) :
+ 0 - 0 | §PHPExcel内存泄漏问题

使用 PHPExcel 来生成 excel 文档是比较消耗内存的,有时候可能会需要通过一个循环来把大数据切分成若干个小的 excel 文档保存来避免内存耗尽。

然而 PHPExcel 存在 circular references 的情况(貌似在最新的 1.6.5 版本中仍然没有去解决这个问题),如果在一次 http 请求过程中反复多次构建 PHPExcel 及 PHPExcel_Writer_Excel5 对象实例来完成多个 excel 文档生成操作的话,所有被构建的对象实例都无法在 http 请求结束之前及时释放,从而造成内存泄漏

解决办法是在 PHPExcel_Worksheet 类中增加方法:

 public function Destroy() {
     foreach($this->_cellCollection as $index => $dummy) {
         $this->_cellCollection[$index] = null;
     }
 }

并在 PHPExcel 类中增加方法:

 public function Destroy() {
     foreach($this->_workSheetCollection as $index => $dummy) {
         $this->_workSheetCollection[$index]->Destroy();
         $this->_workSheetCollection[$index] = null;
     }
 }

然后在需要资源回收的地方显式的调用 PHPExcel::Destroy() 来处理循环引用的问题。注意 __destruct() 方法是在对象被认为可以被释放的时候才会被调用,所以循环引用的处理不能放到 __destruct() 来进行。

标签 ( PHP ) :
+ 0 - 0 | §加权随机数生成
根据指定的概率范围按照权重进行随机选择。  查看全文
标签 ( PHP ) :
+ 1 - 0 | §PHP5+Apache2 worker MPM问题

据说PHP5不建议和Apache的 worker MPM 搭配使用,但之前就是拿 PHP 5.2.6 + Apache 2.2.4 worker MPM 来跑服务,效果貌似挺好。

后来重新编译了一次 PHP 之后 Apache 就报错了:Apache is running a threaded MPM, but your PHP Module is not compiled to be threadsafe. You need to recompile PHP. Pre-configuration failed!

网上通常说的使用 --with-experimental-zts 参数以及 --enable-maintainer-zts 参数统统试了一遍,结果编 PHP 的时候就通不过了。只有改成使用 prefork MPM。

困扰了N久,最后才发现是因为重编 PHP 的时候加了 --with-openssl 把openssl 模块加进去了的缘故,去掉这个模块就又可以正常与 worker MPM 搭配了。

标签 ( PHP ) :
+ 0 - 0 | §RSA加密证书格式转换
将 x.509 或 Modulus/Exponent 格式的 RSA key 转化为 可用于 PHP 的 OpenSSL 函数库读取的 PEM 格式。  查看全文
标签 ( PHP ) :
+ 0 - 0 | §Google PR查询接口checksum新算法

前些日子一篇N久之前的老文忽然成了被阅读的热点,检查之后才发现自己使用那段代码来做pr查询的页面已经不能正常得到URL的Page Rank值了,取而代之的是一大段“In your email, please send us the entire code displayed below”之类的Google terms_of_service错误提示信息。看来是原先的接口已经失效了。

但我装在Firefox工具栏的扩展插件SearchStatus仍然能够正常解析出每个受访页的PR值,找到 SearchStatus 的插件包解开来看源码,果然是使用了不一样的验证码生成算法,在原先的 checksum 生成之后,还需要再进行一次计算,两次演算之后得到的才是正确的ch参数。

于是拿现成的js代码改造一番之后,新的PHP版本的 Google PageRank 查询接口方法就出来了。经过本地测试之后,谁想传到服务器之后又出现了该死的 terms_of_service 错误提示。把checksum的计算过程一步步打出来,发现经过了几次右位移之后本地和服务器上的数字就不一样了。这才想到服务器是64位机,32位系统下位移之后应该被cut掉的bit在那里就活得好好的。加了个 trunkbitForce32bit 方法,对所有算术运算之后的数值进行高位屏蔽,算是搞定了64位系统下的多余位问题。结果拿到32位Linux环境下跑又不兼容了,原因是PHP在进行算术处理出现溢出时,会自动尝试将int转为float。当发生的是负数溢出时,这一操作在Windows下能正确保留精度,但在Linux下就有问题了。

下面这段代码:

$a = -4294967295;
echo dechex($a)."<br />\n";
if ( $a < 0 ) $a += 4294967296;
echo dechex($a)."<br />\n";

第一个echo在Windows下能够正确输出该负数低32位的补码,而在32位Linux机上输出的则是int类型所能表示的最大负数0x80000000了。只有通过取巧的方式给这个溢出的大负数加上一个超出整数范围的大整数来抵消掉溢出的部分,才能复原低32位应该有的样子。

使用这些非常规手段,终于炮制出这个更新版的兼容Linux32/Linux64/Windows的Google PR值查询接口的PHP脚本实现(含完整代码)

参考:
php异或运算的不可靠性
PHP vs. BIGINT vs. float conversion caveat
http://www.teamworksusa.com/RDS275/HydroWorks275/keygen.php

标签 ( PHP ) :
+ 3 - 1 | §PHPExcel常用方法汇总
PHPExcel 是相当强大的 MS Office Excel 文档生成类库,当需要输出比较复杂格式数据的时候,PHPExcel 是个不错的选择。不过其使用方法相对来说也就有些繁琐。列举以记之。  查看全文
标签 ( PHP ) :
+ 0 - 0 | §ZF的quoteInto引起MD5错误

在 Zend Framework 中, Db_Adapter 提供 quoteInto 方法用于查询变量嵌入的统一处理。但在该方法最终调用的底层方法 _quote 中,会用 is_numeric 先判断变量是否是数字,如果是的话就直接返回了,只有非数字型的内容才会被进行转义并加引号。

这样的处理带来的问题是,当你使用数据库自带的 MD5 函数对字符串(比如用户密码)进行 md5 加密时,如果恰好字符串是纯数字,又恰好是0打头的数字,比如“07902”,这时候 MD5(07902)MD5('07902') 返回的结果是不一样的,从而造成潜在的数据错误。

一般我都习惯于给所有的变量都加上引号,不知道 zf 是基于什么考虑对数字型变量进行单独处理。。

标签 ( PHP ) :
+ 0 - 0 | §ZF的TableRow级联删除
Zend Framework的Zend_Db_Table_Row支持关联表的级联操作,但在 cascade delete 的时候只能删除直接关联的表记录,如果存在多级关联的话,子表的关联表记录将一直存在。  查看全文
标签 ( PHP ) :
+ 0 - 0 | §fgetcsv引起basename异常

CentOS 服务器上的 LANG=en_US.UTF-8 ,当php脚本里面使用了 fgetcsv 对某个 GBK 编码的 csv 文件进行解析之后, basename 函数就再也无法正常工作了,每次调用返回的文件名始终为空字符串,该问题甚至会在整个 apache 的 httpd 线程生命周期内存在。 windows 下似乎不会出现这种情况。

解决方法:在用 fgetcsv 处理文件之前先设置 setlocale(LC_ALL,'zh_CN.GBK'); 或者通过 iconv / mb_convert_encoding 等方式将整个 GBK 编码的文件先转化为 utf-8 编码。

理论上来说 fgetcsv 应该只是一个字符串解析的过程,即便输入字符串的编码格式出现问题,最多也就是解析返回的数组乱掉而已,怎么会影响到 basename 函数的正常运作并在线程周期内持续作怪?从 php 的源代码来看似乎也没什么特别的操作,依然困惑中。

标签 ( PHP ) :
+ 0 - 0 | §Zeal OpenID Server打包下载

本来PHP Standalone OpenID Server 的代码改装出来的 Zeal OpenID Server 纯属好玩,最近发现对 OpenID 感兴趣的朋友日渐增多,发信留言询问相关的东西。所以干脆把整个汉化修改之后的 Zeal OpenID Server 整站源码打了个包,喜欢研究的朋友自己 down 一个下来瞧瞧吧。

如果使用过程中有什么问题,最好自己去搞定,俺不负责技术解答,嘿嘿 :)

gz 压缩包: 446,651 字节 openid.zeali.net.tar.gz     zip 压缩包: 505,148 字节 openid.zeali.net.zip

Just Copy the whole folder to your server .

create a database ,
import tables information of file zeal_openid_server.sql

change config.php to fit your requirements.

default settings in config.php:

administrator user : admin
administrator pass : 123456

db host : localhost
db name : zeal_openid_server
db user : openuser
db pass : 123456

标签 ( PHP ) :
+ 1 - 1 | §Links 2006-08-28: 设计模式
  • Five common PHP design patterns
    设计模式这东西就像孙子兵法,高度的概括性和广泛的适用性是它们的特点。但运用之后的结果究竟是快马一鞭抑或南辕北辙就不能一概而论了。
    对于没有足够实战经验积累的人来说,读再多次可能也只是把几个经典名词烂熟于胸而已;拿来忽悠老板或者面试官固然很有份量,真要到理论付诸实践的时候往往就会大帽子乱扣,整出个四不像来。相反很多人只是根据项目的需求去设计各种各样最恰当的系统,但从来没想过这倒是该叫什么模式。运用之妙,存乎一心。就看你是在理解的基础上去总结,还是用条条框框来给自己下套了。
  • JavaScript Code Improver
    JavaScript代码格式化工具。
  • 和谐社会需要恶搞
    “什么才是和谐社会,那就是保护一切人的应有的权利!”
标签 ( PHP ) :
+ 0 - 1 | §del.icio.us API加了https

  这几天一直没办法通过 del.icio.us 的 API 接口抓到当天的网摘信息,开始还以为自己没摘录过东西(最近确实懒了很多),后来觉得不对劲,猜测应该是 del.icio.us 修改了 API 接口,但一直忙着其他琐事也就没顾上去美味网站上查个究竟。

  今天凑巧从 Jeremy Zawodny's blog 上看到了原因,原来 API 改成了 https,地址也从 http://del.icio.us/api/ 变到了 https://api.del.icio.us/v1/ 。这样一来想要通过 PHP 的 fsockopen 来访问 API 的话就必须实现 ssl 协议通讯,费事不少。好在可以用 curl 来作为替代的简单解决方案。Edward Eliot 提供的这个PhpDelicious类正是使用curl来处理了新的API接口。

+ 1 - 0 | §[转]callback函数使用方法

在PHP中有些诸如 call_user_function()usort() 的函数接受用户自定义的函数作为一个参数。Callback 函数不仅可以是一个简单的函数,它还可以是一个对象的方法,包括静态类的方法。

一个 PHP 函数用函数名字符串来传递。您可以传递任何内建的或者用户自定义的函数,除了 array()echo()empty()eval()exit()isset()list()print()unset()

一个对象的方法以数组的形式来传递,数组的 0 下标指明对象名,下标 1 指明方法名。

对于没有实例化为对象的静态类,要传递其方法,将数组 0 下标指明的对象名换成该类的名称即可。

Callback 函数实例

<?php
// An example callback function
function my_callback_function() {
   echo 'hello world!';
}

// An example callback method
class MyClass {
   function myCallbackMethod() {
       echo 'Hello World!';
   }
}

// Type 1: Simple callback
call_user_func('my_callback_function');

// Type 2: Static class method call
call_user_func(array('MyClass', 'myCallbackMethod'));

// Type 3: Object method call
$obj = new MyClass();
call_user_func(array($obj, 'myCallbackMethod'));
?> 

http://www.phpe.net/manual/language.pseudo-types.php
http://cn.php.net/manual/en/language.pseudo-types.php

标签 ( PHP ) :
+ 1 - 0 | §Links 2006-04-12: PHP Scalability
标签 ( PHP ) :
+ 0 - 1 | §Links 2006-04-07: Code Igniter
  • Code Igniter
      an Open Source Web Application Framework that makes writing kick-ass PHP programs simple as apple pie。 这是 CodeIgniter 对自己的一个描述。看看别人是如何评价的:CodeIgniter: the PHP answer?
      确实, Rails 的横空出世带给 PHP 巨大的震动。大家突然发现一个好的框架可以成就一个语言;而再美妙的语言如果缺乏一套强大易用的框架来支撑,多少会显得中气不足。于是,各式各样的 framework 应运而生, Zend 也急吼吼的占了个坑先。然而就目前来看,真正愿意去使用“别人”设计的 PHP framework 的开发者并不算多。更多时候我们宁愿按照自己实际应用的特点来实现一套自己的 framework -- 这样做至少不用去阅读一大堆的文档来熟悉理解别人的设计思路。
      最近不断有朋友问我关于 framework 的问题,或者让我推荐一款框架。但实际上,虽然我自己也很希望能挑出一个比较满意的框架来支撑日常 web 应用的开发,可挑来挑去挑花了眼,文档也看了,别人的评测文章也读了,代码也 Down 下来研究了,到头来现在用的还是自己写的一套东西:虽然简陋,可是够用、好用。 PHP framework 的现状就好比战国争雄,风云变幻,快到你不敢轻易去接受。虽然我看好 CakePHP ;也觉得 Zend 亮的第一招虽不算惊艳但后劲十足;可也仅限于观望而已。
      这次这个 Code Igniter ,同样雄心勃勃。在今年的两月份发布了第一个 beta 1.0 版本,到四月初已经是最新的 version 1.3 。同样 Down 了它的 1.3 版本粗略浏览了一番,有几个初步印象:
    1. 其兼容于 PHP 4.x 的代码目前来说是好事,但对于以后的扩展就不见得有利。
    2. 文档化工作相当细致,条理也很清晰,这对于快速理顺思路,上手使用非常重要。
    3. 可以方便的在 framework 中创建多个 web application。
    4. 用一套 Help 函数集来封装了许多常用的重复性功能,比如文件操作/安全性控制/XML解析等。实际上即便不想使用一整套框架,单独把这套 Help 函数集拎出来也不错。
    5. ActiveRecord/Scaffolding/Logging/Caching/Template/URI Routing等常规功能的支持。不过似乎没发现关于 Ajax 方面的内容。
      总的来说, CodeIgniter 的文档书写、编码风格和设计思路都颇合我的胃口,值得长期关注:)

标签 ( PHP ) :
+ 0 - 1 | §PHP中文手册下载

chm 格式的 PHP 手册中文版,文件生成时间: Sun Mar 26 15:49:18 2006。可以到这里或者php.net下载。中文手册支持中文索引及搜索。集成最新的用户注释(截至03/26/2006)。一册在手,基本上可以不需要到php.net上去在线搜索帮助了。

标签 ( PHP ) :
+ 1 - 0 | §Links 2006-03-08: Zend Framework
标签 ( PHP ) :
+ 0 - 0 | §MySQL UNIX_TIMESTAMP到PHP date

通过 UNIX_TIMESTAMP 函数把 MySQL 数据库中的 date 类型数据转换成 unix timestamp 形式的一个整形数字:

select UNIX_TIMESTAMP('2006-02-28') testdate;

按理说得到的时间戳应该可以直接拿来给 PHP 的 date() 等函数使用。但奇怪的是:

echo date("Y-m-d",$testdate);

显示出来的日期跟数据库实际的日期相比却少了一天,百思不得其解。反复查看 MySQL 关于 UNIX_TIMESTAMP 函数的说明,终于发现问题所在:“The server interprets date as a value in the current time zone and converts it to an internal value in UTC.” 原来 MySQL 的 UNIX_TIMESTAMP 函数得到的时间戳是 UTC 时间,而不是服务器设定的特定 Time zone 的时间。经过这样一转化,时间戳就凭空少了8个小时(对于咱这里来说),而 PHP 中的 timestamp 则计算的都是系统设定时区的当地时间。因此 2006-02-28 这个日期被减去了8个小时,自然变成了2006-02-27。

解决方法:把这八个小时加回去(UNIX_TIMESTAMP('2006-02-28' + INTERVAL 8 HOUR));或者弃用 UNIX_TIMESTAMP 函数, 直接得到 MySQL date 字符串之后通过 strtotime() 函数来把字符串转化成真正的本地时间戳。

+ 1 - 0 | §Links 2006-02-24: PHP Frameworks
标签 ( PHP ) :
+ 2 - 0 | §Links 2006-01-09: Zend & PHP
标签 ( PHP ) :
+ 0 - 1 | §把多个图片转化成Flash轮播
要用Flash文件来轮播显示多个图片,你可以通过在Flash里面用ActionScript脚本来读取不同的图片文件显示,比如这个Project;但这样的话每次打开的时候会需要下载多个文件,有时候会影响速度。所以最好有脚本可以直接把多个图片文件合并成一个Slide show,输出到一个单独的Flash swf文件。Adi Setiawan提供了这样一个php class来实现这个功能。但这个类需要你的PHP安装了Ming扩展库。谁如果有更简便的不需要安装PHP扩展库能实现把多个图片转换成一个Flash swf文件的方法,请一定告诉我。  查看全文
+ 1 - 0 | §PHP源代码格式化系统

对于写代码不喜欢排格式,或者需要去读别人留下的一堆写的极其丑陋的代码的程序员来说,可以试试 Beautify PHP 带给你的便利。这个系统还可以把源代码的函数自动整理到文件的头部作为注释,很实用的一个功能。以前一直觉得JBuilder的代码Reformat功能很酷,看来PHP也可以看上去很美俄。 

Who needs it:

  • people, who get PHP code from other coders and are slightly confused
  • people, who can't read their own PHP code anymore
  • people, who want to share their PHP code

Basic features:

  • automatic indentation of PHP source code according to given number of spaces
  • automatic newlines, if required
  • includes settings for braces according to C or PEAR style
  • can make use of PHPs integrated code highlight option
  • can limit number of chars per line. This will break the code at a space and outputs the rest on the next line with an additional indent. (I used this to reformat my code to put it in a LATEX document. This PHP code normally can't be executed anymore, it is only useful for printout.)
  • turn off and on beautifying by inserting "// NO_BEAUTIFY" or "// BEAUTIFY" in source code
标签 ( PHP ) :
+ 1 - 1 | §phpXplorer-Web文件浏览器

phpXplorer是一个很酷的Web界面的服务器文件管理系统。只需要有PHP环境即可。能够通过浏览器进行服务器上文件的添加删除上下载等各种操作。具有用户/角色权限管理功能。如果Web Server是Apache的话可以提供更加高级的服务。

里面有个“共享”的概念。类似可访问目录。用root用户登陆以后再右边那个窗口的“系统”菜单选择之后可以进行管理员的各种管理操作。其中可以添加“可用共享”,即添加一个可以提供给用户访问的目录。然后把这个共享提供给某个用户或者角色,这些人就能看到这个目录下的东西并进行“文件”操作。

好像网上没找到汉化的版本,自己做了一个。同时这个系统没有操作日志记录功能,对于需要多用户使用的环境来说是一个缺憾。因此在我的这个汉化版本里面增加了日志记录功能,对于关键的文件添加/修改/删除操作进行了Logging。

初始超级用户: root / root

解压之后整个目录上传即可。首次访问会自动跳转到system/install.php进行安装检测,如果一切设置都没问题就可以进入使用了,否则请安装install界面的提示信息对错误进行修正。

原始英文版本(1,763,765 字节): phpXplorer_0.9.33.zip phpXplorer_0.9.33.zip

汉化+日志功能增强版本(1,638,123 字节):phpXplorer_0.9.33_zh.rar phpXplorer_0.9.33_zh.rar

Updated 2005-11-10 19:47 -- 有朋友指出汉化版本对于包含中文的文件名不支持,这两天凑空把几个关键文件转化成utf-8格式,基本上可以支持对中文的访问(只是在下载的时候保存的文件名会变成乱码,但所下载的内容应该是正确的。这个似乎和Apache服务器的配置有关)

修改涉及的文件清单:

system/config.php
system/classes/pxCLS_system_class.php
system/tmp/lang.pxLNGd/zh.pxLNG.php
modules/TinyMCE/lang.pxLNGd/zh.pxLNG.php
modules/TinyMCE/includes/tinymce/jscripts/tiny_mce/langs/zh_cn.js

修改之后的版本可以在这里下载(1,638,637 字节):phpXplorer_0.9.33_zh_utf-8.rar phpXplorer_0.9.33_zh_utf-8.rar 

+ 0 - 0 | §用PHP备份Bloglines feeds OPML信息
最近Bloglines动作频繁,也有听说某某的feeds subscription全部丢失的噩耗。偶从SharpReader转而使用在线的rss阅读器Bloglines也有段时间了,上面的feeds也不算少,另一方面在线阅读器的访问速度实在是我心头永远的痛(如果不是因为其跨机器的易用性同时不需要占用太多系统的资源的话,也许我还会继续用我的SharpReader),或许哪天有更让我心仪的rss阅读工具了,立马弃Bloglines而去。从这些因素考虑,有必要经常对自己放在上面的subscriptions备份一下。  查看全文
标签 ( PHP ) :
+ 0 - 0 | §PHP下的HTTP客户端实现
Class: Advanced HTTP Client . Author : GuinuX .  查看全文
标签 ( PHP ) :
+ 1 - 0 | §OCI_NLS_CHARSET_ID undeclared

php-4.3.10 + Oracle 9.2.0.4.0 , 在 linux下编译安装php的时候make报错: 
/root/php-4.3.10/ext/oci8/oci8.c: In function `_oci_open_session': 
/root/php-4.3.10/ext/oci8/oci8.c:2183: `OCI_NLS_CHARSET_ID' undeclared (first use in this function)

解决方法:

下载Oracle文件补丁  , 解压以后编辑文件oci.h,在文件最前面注释的下面增加一行内容:

#define OCI_NLS_CHARSET_ID 0

然后把所有的补丁文件 (.c 和 .h)拷贝到安装文件目录 /root/php-4.3.10/ext/oci8/ 以及 /root/php-4.3.10/main/ 下面

重新configure,make,install。

问题引起:应该是不同版本的PHP和Oracle之间的兼容性问题。

参考: http://cn.php.net/oracle

+ 1 - 0 | §[转]《十年》 之 PHP 版
偶然发现一篇《十年》的重新填词,讲嘀是php的故事,很有创意~ 向 Easy 致敬 :)  查看全文
标签 ( PHP ) :
+ 0 - 1 | §在页面上实现Google PR值的显示
Google本身提供了查询指定的url的PageRank值的接口,知道了这个接口,就可以很容易编写脚本在页面上实现这一功能,而无需再依赖google toolbar才能进行查询。本文提供了一个用PHP实现的pr查询接口。同时修正了大部分版本中存在的 Linux 操作系统及64位操作系统下无法正常生成checksum的问题。  查看全文
标签 ( PHP ) :
+ 0 - 1 | §PHP下中文编码各种格式间的转换类
目前该类库可以实现的编码转换有:简体中文 GB <-> 繁体中文 BIG5 编码互换,简/繁体中文 -> 拼音单向转换, 简/繁体中文 <-> UTF8 编码转换,简/繁体中文 -> Unicode单向转换。  查看全文
+ 0 - 1 | §PHP下如何对文件进行加锁
有时候你的php脚本或许需要线程安全的保证,比如进行文件写操作的时候。本文提供了文件加锁函数以及使用示例。文件加锁功能也可以用来获得独享的处理空间,防止脚本执行发生同步错误。  查看全文
+ 1 - 2 | §PHP下得到客户端ip的方法
PHP Manual中提及的使用getenv('REMOTE_ADDR')来获取客户端ip的方法存在不少问题,所以有必要考虑采用更为完善的方法来比较精确的获取用户客户端的ip。  查看全文
标签 ( PHP ) :
+ 1 - 1 | §[存] php下的RSA算法实现
当然,这个实现不是我自己写的,不过可能对很多人来说挺有用的,rsa_encrypt和rsa_decrypt这两个函数也许会解决你的燃眉之急,所以不妨以拿来主义之精神广而告之。同时也向Ireland的Edsko de Vries致以崇高的敬意。  查看全文
标签 ( PHP ) :
Since 2005.04.27  梦想 就像鸡蛋 要么孵化 要么臭掉RSS Feed (Entries) | About me | Back To Home | @ZEAL | zbird.com | 沪ICP备05024379号