yo2的服务质量是在堪忧啊。。 前一阵后台根本就进不来。
算了用自己的空间吧。、
reeze
新设计的博客首页
给自己的博客设计了一个新的界面,大概是定型了。。不想做了,明天还得上班,rblog还没有写好,不知道什么时候我的个人网站能上线啊。。

基于var_export 和 include返回值的缓存方案
前一篇文章我们研究了include调用返回值的问题,并指出可以通过这种方式来完成序列化相同的功能,现在我就来研究一下这种方法的可行性和效率,因为直接的返回php值肯定是比unserialize()函数要快。
class MyClass {
private $_var;
public $pub = array('pub value', 3, 4);
public function __constructor($var)
{
$this->_var = $var;
}
public function show()
{
echo $this->_var;
}
}
$string = "It's a string...";
$array = array(1, 2, 'key' => 'value', array('sub-array'));
$number = 135345.55;
$class = new MyClass('class var');
//通过serialize()方法我们可以将他们持久化比如:
echo serialize($string); //s:16:"It's a string...";
echo serialize($array); //a:4:{i:0;i:1;i:1;i:2;s:3:"key";s:5:"value";i:2;a:1:{i:0;s:9:"sub-array";}}
echo serialize($number); //d:135345.5499999999883584678173065185546875;
echo serialize($class); //O:7:"MyClass":2:{s:13:"MyClass_var";N;s:3:"pub";a:3:{i:0;s:9:"pub value";i:1;i:3;i:2;i:4;}}
function encode($var){
if (is_array($var)) {
$code = 'array(';
foreach ($var as $key => $value) {
$code .= "'$key'=>".encode($value).',';
}
$code = chop($code, ','); //remove unnecessary coma
$code .= ')';
return $code;
} else {
if (is_string($var)) {
return "'".$var."'";
} elseif (is_bool($var)) {
return ($var ? 'TRUE' : 'FALSE');
} elseif (is_numeric($var)) {
return "$var";
}
}
}
(PHP 4, PHP 5)
get_object_vars -- 返回由对象属性组成的关联数组
{
return get_obj_vars($this);
}
(PHP 4 >= 4.2.0, PHP 5)
var_export -- 输出或返回一个变量的字符串表示
描述
mixed var_export ( mixed expression [, bool return] )
此函数返回关于传递给该函数的变量的结构信息,它和 var_dump() 类似,不同的是其返回的表示是合法的 PHP 代码。
您可以通过将函数的第二个参数设置为 TRUE,从而返回变量的表示。
0 => 1, 1 => 2, 'key' => 'value', 2 => array ( 0 => 'sub-array', ),)*/
MyClass::__set_state(array( '_var' => NULL, 'pub' => array ( 0 => 'pub value', 1 => 3, 2 => 4, ),))*/
我们可以看到生成的都是合法的PHP表达式。通过设置第二个参数为true,就可以将返回结果赋值给变量比如$new_array_string = var_export($array, TRUE);然后将这个结果写入文件持久化 file_put_contents("data.php", "<?php return $new_array_string;");像上面提到的那样,include就可以将值得到。细心的读者一定会注意第四个类实例对象var_export()返回的类静态函数的调用,同时传递了一个数组参数,他的键值就是该对象的属性和属性值。哦。。原来是这样的啊。原来有这样一个方法__set_state(), 这和__get() __set()方法一样都是magic方法。这个方法的作用就是用来设置对象状态的。这样就好办了。$got_class = include("data.php");$got_class->show();这时会报错,提示__set_state()方法不存在,因为var_export()方法是调用魔术方法__set_state(array());来恢复状态的。下一步我们要做的就是给类定义一个__set_state()方法,它接受一个数组。
{
return new A();
}
{
$tmp = new MyClass();
foreach($array as $key => $value)
{
$this->$key = $value;
}
}
我们可以给需要序列化的对象实现这个方法。或者建立一个 基类。让他们继承也可以。当然非对象类型是不需要实现这个函数的。
// @author Reeze <reeze.xia(at)gmail(dot)com>
// 缓存函数,将数值缓存到设置的文件中
function cache($file, $value)
{
$value_string = var_export($value, TRUE);
file_put_contents($file, "<?php return $value_string"); // 简单起见,不错异常检查
}
// 取出缓存的结果
function cache_get($file)
{
$value = include $file; // 这里也不做出错检查:比如文件是否存在,文件是否异常等。
return $value;
}
////////////////////////////////////////////////
// 测试缓存
////////////////////////////////////////////////
class MyClass
{
private $_var;
public $pub = array('pub value', 3, 4);
public function __constructor($var)
{
$this->_var = $var;
}
public function show()
{
echo $this->_var;
}
public static function __set_state(array $array)
{
$tmp = new MyClass();
foreach($array as $key => $value)
{
$this->$key = $value;
}
}
}
// 一些变量
$string = "It's a string...";
$array = array(1, 2, 'key' => 'value', array('sub-array'));
$number = 135345.55;
$class = new MyClass('class var')
// 缓存
cache("string.data.php", $string); // 当然扩展名不一定非得php, 文件名我也只是简单的处理
cache("array.data.php", $array);
// 等等。。。
// 获取数据,当然也可以在其他文件中来获取。
$class = cache_get("class.data.php");
gmail新功能之标签改进
今天刚登陆gmail,又发现新的惊喜:

很久以前gmail就支持了给邮件加标签的功能,但是到后面基本没有用到,主要有两个原因: 加标签麻烦,以前标签的位置有点低,即使是拖到最上面还是很低,比较麻烦,二是因为以前给邮件加标签似乎只能通过菜单栏来加标签,现在可以直接通过拖放给邮件加标签,如下图:

现在标签的位置和收件箱紧靠着,同时可以把不常用的标签隐藏起来,标签可以重排序,gmail的beta是实实在在的beta,永远不满足,我喜欢:)

PHP中include()函数(以及相关函数)的返回值及避免序列化开销的方法
以前乱翻symfony生成的缓存文件的时候看到很多类似:
<?php return array('key' => "value"....); ?>
这种表达式,当时并没有怎么在意,今天研究symfony代码的时候看到这样一句代码
<?php $this->classes = include($file); ?>
一直都是通过include require来包含文件,但是从来没有使用过他的返回值,印象中include返回的无非是true &false吧。今天自己看了下文档,发现在php文件中是可以直接调用return的。比如
// return.php
<?php
$value = array('haha', 1, 3);
return $value;
?>
// get_return.php
<?php
$value = include("return.php");
echo $value; // 输出 Array, 因为$value 是从return.php返回的一个数组
?>
其实项目中很少情况需要这样的返回方法。如果想要从return.php中得到返回值一般是通过调用return.php中所调用的函数来得到。
在symfony中这种方式就很合理,如果大家熟悉symfony的话,应该知道,symfony运行起来以后会在cache目录下生成系统配置文件的缓存 ,诚然可以通过序列化的方式来缓存这些信息,但是反序列化是需要消耗资源的。通过这种方式来做持久化也是个不错的选择.
PHP5.2.6中无法在exception_handler函数中抛出异常
在PHP bugs列表中也找到这个bug,但是似乎没有被处理,bug提出的时间是2005年,不知道新版本的有没有解决。
PHP:5.2.6
OS: Mac OS Leopard 10.5.7
Server: Apache 2.2
这个代码就有问题:
function e_handler($e)
{
throw new Exception();
}
set_exception_handler('e_handler');
throw new Exception();
这将会导致
Fatal error: Exception thrown without a stack frame in Unknown on line 0
Update: 这应该属于设计问题,如果在exception_handler()函数中可以跑出异常,则这个异常优惠调用exception_handler(),这样下去就会出现死循环,这就是为什么程序会出错的原因吧。
通过try catch来处理的话就没有问题。。
function e_handler($e)
{
try
{
throw new Exception();
}
catch (Exception $e)
{
echo "catched...";
}
}
set_exception_handler('e_handler');
throw new Exception();
Mac下我常用的软件
习惯了Mac OS X Leopard以后发现自己已经离不开它了。像很多Linuxer一样除了上网银以外统统不用Windows,玩个CS什么的也都用Wine了,我很笨,目前在Mac 上和Ubuntu下都没有Wine成功过
``, 下面就介绍一些我认为在Mac下非常使用的软件吧。
1. QuickSilver
只需要Command+Space 再加上几个字母就可以方便的你的程序,通过一些插件QuickSilver能极大的提高我们的效率,强烈推荐,唯一不足的是这款软件的作者已经不继续维护这款软件了,他被Google请去做另外一款和这个类似的软件Google Quick Search Box 试用了一下还不够成熟,目前和QS比起来还是差太多了。
2. TextMate
这款软件就不用多介绍了吧,强大的编辑器。开发进度有点慢,作者对软件质量要求很高,不许诺2.0版本到底何时能出来,很多人都以为作者停止了开发,前不久作者发布了这篇文章,声明开发仍在继续,感兴趣的同学可以看这里看看TextMate2.0到底有哪些改进。这篇在2007年就发布了。实在过的有点久了。
3.Things
GTD绝佳软件,缺点不具有网络同步功能
4.Evernote
笔记软件,很方便,之前我也用Evernote来做GTD发现管理器来很不方便,后来发现上面提到的Things就放弃用Evernote做GTD了,Evernote做笔记绝对顺手,他同时提供Windows 和Mac OS 两个版本,还有Web版的,跨平台很有优势。免费用户提供40M得空间,对我来说这其实绝对够用。
5.Adium
多协议IM客户端支持:Gtalk, MSN, ...QQ(因为QQ的协议是不公开的,所以可能定期会抽风,上QQ也可以用官方的 QQ for Mac)..
6.Tweetie
Twitter就靠他了,说不出那里好,就是很好用。免费版有广告。还好基本不影响用户体验。
7.iChm
看chm的电子书就靠它了。支持搜索
8.RescueTime
这个软件也有各个操作系统的版本,收集自己的时间分配,然后会有个汇总。
9.AppZapper
卸载软件用它来卸载还是比较干净的。方便快捷
10.Monolingual
帮你清除一些不需要的语言信息,节省磁盘空间。
Mac OS 启动sshd服务
想push自己写的一些代码到本地的版本库中去,看了很多的协议,都挺麻烦的,至今没有配置好一个git server,遂放弃搭建server,直接使用ssh来提交到本地
无奈Mac OS X 似乎默认不启动SSHD服务。所以我尝试启动
Leopard:etc reeze$ sshd
sshd re-exec requires execution with an absolute path
看来不行。
不过这个提示错误似乎不是很明白。上网baidu了一把。发现
只能用绝对路径启动。不知道为什么程序非得用绝对路劲启动。有时间研究下为何是这样的,或者有知道的直接告诉我:)
$ sudo /usr/sbin/sshd
服务就启动了
不能每次都这么运行一下先啊。放在 ~/.bashrc 似乎可以,不过这个得需要管理员权限
得sudo,每次输入密码很烦人。干脆放到 /etc/rc.common,
#####
/usr/sbin/sshd
网上有人说apple不推荐这么干。但是我又不知道怎么让他自动启动。先就这么放着吧。找到好方法再改。
PHP调试函数
在项目中经常要调试程序,但是我电脑上的ZendStudio总是没配置好,不能单步调试,不过有时候不一定需要让ZendStudio来帮我们调试,所以写了下面这个辅助函数来方便调试,因为有时候调试的位置加多了自己也不知道到底是加在什么地方了,下面的函数就是方便的dump对象信息,同时显示调试的问题和所在的行数。
//调试函数,方便显示调试函数的位置和文件
function p(){
$args = func_get_args();
$backtrace = debug_backtrace(); // 调用栈
$file = $backtrace[0]['file'];
$line = $backtrace[0]['line'];
echo "<pre>";
echo "$file:$line\n";
foreach ($args as $arg)
{
var_dump($arg);
}
echo "</pre>";
exit;
}
debug_backtrace()可以返回调用栈。这样 我们就可以方便的知道函数在哪里条用的。