浅谈对CACHE操作的封装及最佳实践

作为WEB开发者,CACHE对我们来说是再熟悉不过了。但是,你真的有研究如何把它用得更“优雅”吗?下面以较常见的Memcache为例,谈谈对CACHE操作的几种常见封装方法,并推荐一种我认为最佳的实践。如果你有更好的解决方案,请不吝赐教:)

为什么要封装?

$mc = new Memcached();
$mc->addServers('127.0.0.1', 11211);
$key = 'test';
$duration = 3600;
$value = $mc->get($key);
if ($mc->getResultCode() == Memcached::RES_NOTFOUND) {
    $value = getValueFromDB();
    $mc->set($key, $value, $duration);
}

第一次使用CACHE的同学,往往会写出上面的代码。简陋且有效,拿来写个Hello World是再合适不过了,但是真正在项目中使用CACHE的时候,还这么写就太low了。没有异常处理和重试机制、不能做负载均衡,大量的重复代码……当你受不了维护之繁琐时,就会想办法来解决这些问题,那就是封装。 Continue reading 浅谈对CACHE操作的封装及最佳实践

解决SimpleTest 1/2 test cases complete的问题

最近一直在用SimpleTest测试代码,发现这个问题其实已经很久了,但一直因为无关痛痒没有去解决,今天终于憋足劲把它搞定了,把过程写出来给大家分享:)

复现问题

首先新建一个test.php,内容如下:

现在执行这个测试,你会发现test cases complete的数字不对劲。显示的TestCase总数多于真实的TestCase数量。如下图:

排查原因

Google无果后,只能自己排查SimpleTest源码了。先在项目里搜索”test cases complete”,定位到reporter.php:
Continue reading 解决SimpleTest 1/2 test cases complete的问题

解决Rockmongo不显示中文的问题

Mongodb是时下非常流行的数据库,而Rockmongo可以说是最普及的web版gui了。但是Rockmongo在显示utf-8中文数据时一直有问题,最新版本v1.1.2仍然没有解决。今天专门腾了点时间debug并将其解决,将过程记录一下供大家参考。

问题现象

1、插入一条包含中文的数据

2、保存之后,中文数据不见了

DEBUG

审查元素发现,从服务器端返回时中文已经不见了,排除问题在浏览器端的可能性

Continue reading 解决Rockmongo不显示中文的问题

通过macports安装的php,extension的配置被分离

我现在的开发环境,php、php-mongo、php-mysql、php-redis、xdebug等都是通过macports安装的。一直使用都没有问题,直到今天编辑php.ini的时候发现,这些extension居然都没有在php.ini中定义。奇怪了,那它们是怎么加载的呢?

首先怀疑我编辑的php.ini不是php实际使用的配置文件。通过查看phpinfo(),在Configure Command中可以确认–with-config-file-path为/opt/local/etc/php54,编辑的php.ini没有问题。

既然php.ini中没有定义,而extension又实际上被加载了。那么可以初步判断,通过macports安装的php,extension的相关配置是存在php.ini之外的一个地方,那么究竟在哪呢?

继续分析phpinfo(),发现这么一条–with-config-file-scan-dir=/opt/local/var/db/php54。进入这个目录一看,mongo.ini、mysql.ini、redis.ini、xdebug.ini等都在这里。于是乎真相大白,原来extension相关的配置文件都被分离到这里了。

究其原因,macports这样做是为了方便维护extension。好处如下:

1、extension的配置与php.ini隔离,方便维护(直接修改php.ini会引发各种问题)
2、各个extension的配置文件相互隔离,互不影响(安装卸载只要添加删除文件即可)

在不同php版本中实现model层重复代码的去除

问题

MVC架构中的model层主要负责和数据直接交互,如果没有使用ORM框架,那么很多原子操作(CRUD等)需要自己实现。一般来说一个系统会有多个Model,每一个Model都需要重复实现这些原子操作,而这些代码往往除了表名外都是一样的:

class User {
  public static function findById ( $id ) {
    return DBProxy::getDb( 'user' )->findOne( array( '_id' => new MongoId( $id ) ) );
  }
}
class Video {
  public static function findById ( $id ) {
    return DBProxy::getDb( 'video' )->findOne( array( '_id' => new MongoId( $id ) ) );
  }
}

当我们增加一个Model类的时候,比如Article,就要从其他类复制这些原子操作(比如find、findOne、findById、update、save、count等等)过来。如果有一个方法需要变更,比如增加一个参数或者添加log日志,就得修改所有Model类中的同名方法。这实在是一件很痛苦很无奈的事情。

《重构》一书告诉我们,重复的代码是坏味道,那么我们该怎么改良呢? Continue reading 在不同php版本中实现model层重复代码的去除

mac下配置php环境后出现syntax error

刚在mac上配置好php环境,运行项目代码就出现错误:

Parse error: syntax error, unexpected end of file in xxx.php on line 21

检查出错的文件,21行是该文件的最后一行,是一句很简单的php代码,没有发现任何问题。于是我准备用排除法来定位问题,将该行删除后刷新页面,错误信息变成:

Parse error: syntax error, unexpected end of file in xxx.php on line 20

错误行变成20行,而该行是一个html标签。这样就很奇怪了,非php的代码怎么会引发php的语法错误?

再继续排查,该文件中还有一段php代码:

<?php foreach ( $tags as $tag ) {
    ?><a href="<?= $tag[ 'url' ] ?>"><?= $tag[ 'name' ] ?></a>

虽然觉得不太可能,但还是将这段不能再简单的代码删除测试一下,居然不报错了!

继续测试,结果发现只要把循环体彻底删除,就不会报错。而只要保留循环体,哪怕是?><?,也会报错。脑中浮现出之前google时见过的一个诡异问题,莫非⋯⋯

打开php.ini,搜索short_open_tag,好吧,不知道出于什么目的,在用port装的php54里这个值居然是Off!貌似我用yum、apt-get乃至手动编译php,这个值都是On啊。

果断改之,重启php,问题顺利解决。