2009-07
26

注:本文使用的CakePHP版本为 1.2.3.8166。

使用CakePHP开发时,免不了要将调试级别设置为2, 这样页面上会显示出执行的SQL语句及结果,很方便。 但在做API页面时就比较麻烦。一般API页面的输出结果是XML或者JSON格式, 如果后面多了些调试信息,客户端就无法正确解析了。

解决方法很简单,只要在API的action函数中改写调试等级即可:

function api_index() {
  ...
  Configure::write('debug', 0);
}

不过,每个action都要写这么一行,太麻烦了。能不能想个办法,自动地关闭所有API页面的调试信息?

阅读全文 »
2008-07
20
PHP+MySQL八大动态Web应用实战

豆瓣上的介绍, 购买此书: 当当, 卓越, ChinaPub, 蔚蓝

这本书是今年二月份翻译的,两个人合作,用了一个半月的时间翻译+校对,虽然进度安排比较紧,但总算是按时交了稿,翻译的质量也还说得过去。

上周接到博文视点的消息,说这本书已经出版了,样书已经寄出来了。不过我还没收到,估计下周就能收到样书了吧。到网上查了查,发现各大书店已经开始卖了。

这本书的内容主要是面向PHP初学者的,但正如作者在前言中所述,这本书不会教你PHP和MySQL的基础知识,而是通过实际的项目进行讲解,在项目进展的过程中逐步地讲授需要的知识。个人认为这种方法要比教科书的好得多。我们在实际工作中学习也与之类似,不会有人去一步步手把手地教你怎样学习,都是直接将新人投入到项目中,在项目中磨砺。

书中介绍了八个实际可用的项目,除了基本的PHP和MySQL之外,还有较为新颖的Ajax、较高深的PEAR等内容。初学者通过这些项目可以切实地体会到PHP的方便性,而稍有基础的人则可以将书中的例子直接拿来,简单修改后即可直接放在网站上使用。当然,如果你已经是PHP高手,那么能从此书中学到的内容就有限了。

当然,本书自身也有一些不足之处,或许是因为作者精于技术但不善表达的缘故,书中一些概念的解释不太容易理解。加之我们英文水平有限,许多原文中的俗语都无法精确翻译出来,也影响了原文意思的表达。还望读者在阅读的过程中,借助Google、百度等搜索引擎,主动去查找那些难以理解的概念。另外,我们尽最大的努力保持翻译结果符合原意,但难免有疏漏之处,希望读者能够指出。


2007-11
19

自连接,就是自己引用自己,比如员工表,某个员工的上司也保存到员工表中, 那么想要同时得到一个员工和他的上司的信息就得使用自连接。 表如下所示:

employees

PKidINT自动编号id
nameVARCHAR(64)员工姓名
FKsuper_idINT上司id,引用自身

那么查询时就需要这样写:

SELECT A.name,B.name FROM t_employees A, t_employees B
  WHERE A.parent_id=B.id

而在CakePHP中如何实现,就需要一点小技巧。 这篇文章 简单介绍了如何做到这一点,其实不难,能把model建好了就80%了。

原文讲得比较罗嗦, 我就不再重复了,仅将要点写在这里。

阅读全文 »
2007-11
02

前些日子就知道CakePHP发布了1.2 pre-beta版。 偶然在delicious上看到这篇文章: CakePHP 1.2的五个方便的新特性。 好文不敢独享,现将其大意记录如下。图片就不转载了,想看图的话可以直接去原文上看。

1. 集中显示友好的错误信息

使用框架时最郁闷的莫过于调试,PHP会报告框架出错,而实际上我们代码中的错误则很难发现。 CakePHP 1.2版中,错误信息会集中显示在页面上方,并且单击错误信息就能看到错误所在的位置, 可以节省大量的调试时间。

2. 内建分页功能

CakePHP 1.1时必须手动书写分页代码,而1.2版则内建了分页功能,还支持单击标题排序。 只需书写下面的代码:

class MembersController extends AppController {
    var $paginate = array('order'=> 'Member.created DESC');
    function listall() {
        $this->set('data', $this->paginate());
    }
}

3. 复杂的表单验证

原来1.1版的表单验证只能使用正则表达式,因此无法验证类似于“包含数字、字母并且长度不大于10且可以为空” 这样的复杂规则就很难通过表单验证实现。而1.2版则支持下面这种复杂的验证。

var $validate = array(
'title' => array(
    'required' => VALID_NOT_EMPTY,
    'length' => array( 'rule' => array('maxLength', 100))
    ),
'body' => VALID_NOT_EMPTY
);

4. 内置电子邮件功能

1.2版添加了发送电子邮件的模块。

5. HTTP请求生成、XML解析

1.2版支持HTTPSocket、XML模块,通过它们可以直接调用外部的WebAPI了。


2007-10
19

原文链接:http://www.avatarfinancial.com/pages/cake/

这篇文章可以说是CakePHP教程中最经典的了。虽然不是完整的手把手系列, 但作者将自己使用CakePHP的经验总结了21条,这些尤其是对新手十分有用。

翻译时故意保留了一些CakePHP中特有的词语没有翻译, 如controller、model等。相信学过CakePHP的人应该马上就能理解它们的意思吧。

另外,CakePHP的wiki已经失效,取而代之的是一个名为bakery的网站。 原文中引用的wiki的链接也都已更新到了bakery上。

阅读全文 »
2007-10
08

这两天一直被一个问题所困扰。同样的一段程序,在自己的机器上调试完全没有问题,放到服务器上时间显示就快了8个小时。显然这8个小时就差在时区设置上。我在自己的机器上写代码时,对timestamp进行了时区调整($now += 8 * 3600)之后再进行getdate()转换,结果完全正确;放到服务器上执行,就要将时区调整代码去掉之后才正常。一时百思不得其解。

写了个小测试程序:先用 time() 取得当前时间戳,再用 getdate() 获取当前的小时、分、秒,分别放到开发环境和服务器上执行。结果很显然,服务器上显示的时间是正确的(22点显示为22点),而我的机器的时间是错误的(22点显示为14点)。从时区的角度来看,服务器使用了正确的CST时区(中国时区),而我的开发环境的时区则是UTC的。但开发环境操作系统是Windows,时区设置也正确,为什么会出错?

窄多的blog上看到,通过date_default_timezone_set()函数可以设置默认时区名。天啊,居然有这样的函数,查了查资料发现它的反义函数date_default_timezone_get(),将这个函数分别在开发环境和服务器上执行,果然,我的时区设置为 UTC。

知道了原因就好修改了。打开开发环境中的 php.ini,找到 date.timezone,去掉注释并将其设置为 Asia/Chongqing,再运行,这次结果正确了。


2007-07
06

某个功能被编译到so文件中,那么如何通过php来调用它? 一个方法是写一个php模块(php extension),在php中调用该模块内的函数, 再通过该模块来调用so中的函数。下面做一个简单的例子,使用的操作系统是Fedora Core 6。

阅读全文 »
2006-09
23

下载并安装 httpd 2.2。

$ tar xjvf httpd-2.2.3.tar.bz2
$ cd httpd-2.2.3/
$ ./configure --enable-rewrite --enable-so
$ make
$ sudo make install

下载并安装 mysql-3.23

$ sudo tar xzvf mysql-3.23.58-pc-linux-i686.tar.gz -C /usr/local/mysql
$ sudo groupadd mysql
$ sudo useradd -d /usr/sbin -s /bin/false -g mysql mysql
$ sudo chown -R mysql.mysql /usr/local/mysql
$ cd  /usr/local/mysql
$ sudo ./scripts/mysql_install_db
$ sudo cp support-files/mysql.server /etc/init.d/mysql
$ /etc/init.d/mysqld start

下载并安装 php 5.1.6。

$ sudo apt-get install flex bison libxml2-dev
$ tar xjvf php-5.1.6.tar.bz2
$ cd php-5.1.6/
$ ./configure --with-apxs2=/usr/local/apache2/bin/apxs --with-gd
                  --with-gettext --with-mysql --with-zlib-dir=/usr/lib 
                  --with-mysql=/usr/local/mysql

2006-08
31

本文介绍了在Windows下安装Apache、PHP、mod_perl、mod_python、subversion的方法。
阅读全文 »


2006-04
26

学过C++的人都应该知道C++中有个虚函数的概念。而在php5中如何实现这个虚函数呢?请看下面的代码:

<?php
 class A {
    public function x() {
        echo "A::x() was called.\n";
    }
    public function y() {
        self::x();
        echo "A::y() was called.\n";
    }
    public function z() {
        $this->x();
        echo "A::z() was called.\n";
    }
}
class B extends A {
    public function x() {
        echo "B::x() was called.\n";
    }
}

$b = new B();
$b->y();
echo "--\n";
$b->z();
?>

该例中,A::y()调用了A::x(),而B::x()覆盖了A::x(),那么当调用B::y()时,B::y()应该调用A::x()还是B::x()呢?在C++中,如果A::x()未被定义为虚函数,那么B::y()(也就是A::y())将调用A::x(),而如果A::x()使用virtual关键字定义成虚函数,那么B::y()将调用B::x()。然而,在PHP5中,虚函数的功能是由 self 和 $this 关键字实现的。如果父类中A::y()中使用 self::x() 的方式调用了 A::x(),那么在子类中不论A::x()是否被覆盖,A::y()调用的都是A::x();而如果父类中A::y()使用 $this->x() 的方式调用了 A::x(),那么如果在子类中A::x()被B::x()覆盖,A::y()将会调用B::x()。

上例的运行结果如下:

A::x() was called. A::y() was called. 
--
B::x() was called. A::z() was called.