CakePHP一些零碎的技巧
CakePHP一些零碎的技巧
--来自逸舟的博客
快速创建静态页面
我想实现功能:
已知:建立几个页面,它们仅包含静态数据,使用默认layout,没有任何model
要求:不用在controller里面为每个静态页面定义一个action,这种方法太笨拙了,根本不适合快速建立静态页面!
实际上只要使用pages controller就可以做到——只要在 views/pages 文件夹下创建一个 view,就可以通过 /pages 来访问。例如,我创建了 /views/pages/matt.thtml , 就可以通过 http://localhost/pages/matt 来访问。 (显然,pages是cake内置的一个controller)
快速创建后台管理
如果你需要创建后台管理程序,并且希望所有管理action都位于某个特定文件夹下, 那么打开 config/core.php 并将下面这一行的注释去掉:
define('CAKE_ADMIN', 'admin');
这样所有以”admin_”开头的action都可以通过 /admin/yourcontroller/youraction 来访问。例如,如果在posts controller中创建了名为”admin_add”的action, 那么可以通过 www.example.com/admin/posts/add 访问这个action。这样就可以方便地为admin目录设置密码以避免他人随意访问。
获取丰富的开发文档
别总是盯着手册。wiki和API也是无价之宝。wiki中的开发指南十分有用,而API文档初看起来比较难, 但你很快就会发现这里的信息对你创建CakePHP 网站十分重要。`
使用bake.php
Bake是个命令行PHP脚本,可以根据数据库自动生成model、controller和view。在开发的最初阶段,我强烈推荐使用 scaffolding让你的原型程序跑起来。但如果你清楚地知道scaffolding不合适,我推荐你使用bake。 bake会生成所有的文件并保存到磁盘上,以便你随意修改。这样能节省创建关联、view、基本的CRUD crollder操作的重复工作。
(译者注:CRUD - Create, Read, Update, Delete,数据库应用的四种基本操作,即”增删查改”。)
bake很方便。你只需在数据库中建立一个表,然后到 /cake/scripts/ 目录下执行 php bake.php 即可。
如果你通过交互方式来运行bake,它会分几步提示你创建model、controller和view。 创建结束之后,我通常会阅读所有生成的代码并做必要的修改。
发布程序时注意权限
有一次我在发布程序时,将整个cake目录打包然后用scp上传到了服务器上。只要一关闭调试信息,就会出现错误——数据库调用无法返回任何数据。我一筹莫展,因为我必须通过调试信息才能调试问题。后来有人告诉我,/app/tmp应当对apache可写。将权限改为777之后问题就解决了。
创建不使用数据库表的model
我需要创建一个不使用任何表的model,为什么呢,因为我只是想调试一下,但如果创建model时对应的表不存在,CakePHP 就会报错,可以在model中加入以下代码可以解决这个问题:
var $useTable = false;
复杂model验证
我需要进行更复杂的验证,而不仅仅是验证输入框非空或者符合某个正则表达式这样的简单验证。 例如,我要验证用户注册时使用的邮件地址是否已被使用。在wiki中我找到了这篇关于高级验证的文章, 其中提到了一些十分有用的高级验证方法。
重定向之后记得exit()
对于有经验的人来说这应当是理所当然的事儿,调用 $this->redirect() 之后,剩下的代码如果不想运行 要exit()。我也这样做,但以前曾经认为 $this->redirect() 会为我调用exit(实际上不会)。
如何正确插入多行
需求:我需要遍历一个列表,并将其中的每个元素都插入到数据库中。
结果:我发现如果在一次插入完成后立即进行下一次插入,那么第二次插入的内容完全不会被插入,而是会被更新到第一次插入的行中。例如:
$items = array('Item 1','Item 2','Item 3'); foreach ($items as $item) { $this->Post->save(array('Post' => array('title' => $item))); }
这段代码将在posts表中插入仅一行:“Item 3”。 CakePHP首先插入“Item 1”,但马上将其更新为“Item 2”,再更新为“Item 3”,因为$this->Post->id保存的是上一次插入成功的行的id。通常这个特性很有用,但在这个例子中反而帮了倒忙。其实只要在每次插入之后设置 $this->Post->id = false 就可以解决这个问题。
更新:有人发邮件告诉我,正确的做法是调用create()初始化model,再set/save新数据。
自定义HABTM关系的SQL语句
我曾试图在自定义的SQL语句上定义一个HABTM关系(has-and-belongs-to-many),却遇到了问题。根据本文撰稿时的文档,应当先在自己的model中设置finderSql,但从CakePHP的源代码来看,应该设置finderQuery。这只是文档中的一个小问题,但指出问题却能为他人节约时间。
发送邮件
我在wiki中找到两篇教程:发送邮件和 通过PHPMailer发送邮件。强烈推荐后者,通过PHPMailer发送邮件更安全,而且不需要自己处理邮件头,减少许多麻烦。
自定义Helper生成的HTML
我需要修改调用$html->selectTag()时生成的<option>,使其生成“请选择”选项来代替默认的空白选项。我也希望单选按钮能带有标签,这样用户就无需精确地点击单选按钮本身,而只需单击到关联的文字上即可。
建立 /app/config/tags.ini.php,然后添加以下的内容:
; Tag template for a input type='radio' tag. radio = "<input type="radio" name="data[%s][%s]" id="%s" %s /><label for="%3$s">%s</label>" ; Tag template for an empty select option tag. selectempty = "<option value="" %s>-- Please Select --</option>"
你可以从/cake/config/tags.ini.php中获得完整的标签列表。但我不建议修改该文件,否则升级CakePHP时可能会让你的修改丢失。