本文概述
- 常见错误1:不遵循CakePHP编码约定
- 常见错误2:在ORM中错误使用可包含的行为和递归级别
- 常见错误3:将业务逻辑保留在控制器中而不是模型中
- 常见错误4:给代码增加太多复杂性, 而不是经常返回
- 常见错误5:不使用DRY原理
- 常见错误#6:不评论代码
- 本文总结
CakePHP是一个了不起的PHP框架, 但学习曲线却很陡!要成为专家, 需要大量的研究和培训。
我有幸使用CakePHP已有7年多了, 那时我很荣幸能与CakePHP社区的许多成员一起工作。
在本CakePHP教程中, 我想描述一下我多年来发现的一些不良做法, 并提出避免这些错误的正确方法。这并不是说我的代码很完美, 但是作为程序员, 我们一直在学习, 因此遵循最佳实践并在学习过程中进行调整非常重要!
本文内容的灵感来自CakeCoded。如果你想了解有关CakePHP的更多信息, 请在此处访问我们的学习部分。
常见错误1:不遵循CakePHP编码约定
CakePHP编码约定可在此处查看。我将重点介绍一些在查看其他程序员代码时经常注意到的事情。
控制结构。因此, 你经常会看到程序员犯了这个错误, 并且在某些情况下还带来了其他编码语言的实践。 CakePHP需要以下语法:
if ((expr_1) || (expr_2)) {
// action_1;
} elseif (!(expr_3) && (expr_4)) {
// action_2;
} else {
// default_action;
}
第一个括号之前应该有1(一个)空格, 最后一个括号和左括号之间应该有1(一个)空格。因此, 这意味着以下错误:
if($this->request->data){
}
请注意if和(之间以及)和{之间的间距
始终在控制结构中使用花括号, 即使不需要它们也是如此。它们提高了代码的可读性, 并为你减少了逻辑错误。
因此, 例如, 以下错误:
if ($foo)
$bar = true
格式应如下所示:
if ($foo) {
$bar = true
}
最后, 注意放置括号的位置。左括号不应该换行。并确保所有括号对齐, 以便每个新括号都与右括号对齐。
这是一些不正确的示例:
if ($foo)
{
$bar = true;
}
这是不正确的, 左括号应在第一行中:
if ($foo) {
$bar = true;
if ($action) {
$to = false;
}
}
压痕需要正确对齐。
我经常听到程序员说:”但是我太忙了, 无法使代码整洁……。”我的回答是:”相信我, 简洁的代码将经受住时间的考验”。如果你需要在几个月内进行更改, 那么编写无法读取的CakePHP代码将是一场噩梦。
常见错误2:在ORM中错误使用可包含的行为和递归级别
最近, 我很幸运与Facebook的数据库开发人员进行了非正式讨论。我们开始谈论CakePHP, 他对我说:”哦, 使用ORM是吗?这可能会令人恐惧。”我问他是什么意思, 他评论说, 使用对象关系映射(ORM), SQL查询很容易变得不必要的大。
他在某种程度上是对的。 CakePHP的神奇之处在于其对ORM的使用以及将不同数据库表关系分组在一起的方式。默认情况下, CakePHP自动选择任何相关的”属于”, “有一个”和”有很多”数据, 这会导致非常大的SQL查询。最初开发应用程序时, 这些查询可能不会引起你的注意, 但是在收集实时数据六个月后, 你可能会发现应用程序变得非常慢, 并且在某些情况下, 如果不对查询进行优化也会导致崩溃。
在审核现有网站时, 我会注意两件事。首先, 是否更改了默认递归级别?默认情况下, CakePHP将递归级别设置为1, 在我看来, 这太高了。我总是将其设置为-1, 然后使用可包含的行为来获取任何相关模型。
这导致了我要寻找的第二件事-是否使用了Containable行为?我经常有新客户来找我, 说CakePHP很慢。原因几乎总是因为未使用Containable!一个好的CakePHP程序员将优化他们的SQL查询, 而不管幕后进行了多少”自动魔术”。
直到CakePHP 1.2才添加可遏制的行为, 但是男孩有什么不同吗?确保尽可能使用可包含的内容, 因为这是优化SQL的有效方法。有关如何实现和使用Containable行为的更多信息, 请单击此处。
常见错误3:将业务逻辑保留在控制器中而不是模型中
好的CakePHP代码将在模型文件中包含逻辑。这需要一点时间来习惯, 但是一旦掌握了就不会回头!控制器文件应用于MVC模式中的预期用途-控制!因此, 在将业务逻辑放到模型文件中的同时, 使用控制器文件来处理用户操作。
一个很好的例子就是一个简单的CRUD-一个日常动作!让我们以博客教程中的添加帖子功能为例。默认添加功能如下:
public function add() {
if ($this->request->is('post')) {
$this->Post->create();
if ($this->Post->save($this->request->data)) {
$this->Session->setFlash(__('Your post has been saved.'));
return $this->redirect(array('action' => 'index'));
}
$this->Session->setFlash(__('Unable to add your post.'));
}
}
此控制器操作适合简单的添加, 但是如果你想做一些事情, 例如在添加帖子时向管理员发送电子邮件, 或在添加帖子时更新另一个模型关联, 将会发生什么。这是附加的逻辑, 但不应将此逻辑放入我们的控制器文件中。
相反, 我们将在Post.php模型中为此编写一个函数。也许是这样的:
public function addPost($data = array(), $emailAdmin = true) {
$this->create();
$this->save($data);
// update any other tables
// send the email to the admin user
if ($emailAdmin) {
}
// if all is successful
return true;
}
然后, 这将导致对控制器操作的较小更改, 如下所示:
public function add() {
if ($this->request->is('post')) {
if ($this->Post->addPost($this->request->data)) {
$this->Session->setFlash(__('Your post has been saved.'));
return $this->redirect(array('action' => 'index'));
}
$this->Session->setFlash(__('Unable to add your post.'));
}
}
如你所见, 新动作实际上少了一行, 因为$ this-> Post-> create()已移至模型文件。
这是一个完美的日常示例, 说明将逻辑移至模型文件是个好主意-无疑可以使代码基础更加简洁!
常见错误4:给代码增加太多复杂性, 而不是经常返回
这始终是一个持续不断的辩论, 但是经常返回, 并且早日返回确实可以使代码看起来更简洁。这最适用于模型方法。
但是我到底是什么意思?好, 让我们看一下我们在上面的CakePHP教程中添加的方法:
public function addPost($data = array(), $emailAdmin = true) {
$this->create();
$this->save($data);
// update any other tables
// send the email to the admin user
if ($emailAdmin) {
}
// if all is successful
return true;
}
经常返回, 并尽早返回意味着在我们运行函数时, 我们检查以确保一切正常。如果不是, 则返回false, 否则返回CakePHP错误。
举个例子最简单地展示一下。以上功能可以通过两种方式编写:
public function addPost($data = array(), $emailAdmin = true) {
if ($data) {
$this->create();
$result = $this->save($data);
if ($result) {
// update any other tables
// send the email to the admin user
if ($emailAdmin) {
// send the admin email
}
} else {
// problem saving the data
return false;
}
// if all is successful
return true;
} else {
// no data submitted
return false;
}
}
看看代码如何迅速变得难以阅读?到处都是ifs和else, 功能很快成为一大缩影。不要误会我的意思, 我喜欢简洁的缩进, 但是请注意, 如果函数经常以return的形式出现, 请注意函数的外观。
public function addPost($data = array(), $emailAdmin = true) {
if (!$data) {
// no data submitted
return false;
}
$this->create();
$result = $this->save($data);
if (!$result) {
// problem saving the data
return false;
}
// update any other tables
// send the email to the admin user
if ($emailAdmin) {
// send the admin email
}
// if all is successful
return true;
}
直接在这个小例子中, 你可以看到该代码仅具有单个缩进并且更具可读性。逻辑实际上更有意义-让逻辑逐行运行, 如果在执行过程中出现任何问题, 请返回错误, 而不继续进行下一行。
这允许CakePHP程序员以与读取相同的方式编写-从左到右, 从上到下读取代码, 而不是在不同的块中读取代码, 这可能会很快使你感到困惑!
常见错误5:不使用DRY原理
DRY代表”不要重复自己”, 这是在CakePHP中进行编码时应遵循的一种哲学。使用面向对象的代码, 没有任何借口重复两次相同的代码块!
以下是CakePHP的一些技巧, 可确保你不会重复自己:
-
如上所述, 旨在将逻辑放入模型文件中, 以便你可以共享逻辑。
-
在视图文件中, 如果要重复视图, 则将视图代码创建为Element甚至是自定义帮助器。
-
设置一些配置设置-app / Config / bootstrap.php文件是个不错的选择。这有助于确保你不会对应用程序名称和主要电子邮件地址之类的内容进行硬编码。你要做的最后一件事就是浏览数百个文件, 这仅仅是因为客户端要求更新应用程序中的电子邮件地址。
-
总是问自己:”如果我要重复代码, 是否有更好的方式编写此代码, 我是否将该代码放在正确的位置?”如果你需要重复代码, 可能会写得更好。
常见错误#6:不评论代码
我要说的最后一点是关于评论。首先, 文档阻止。文档块是在你记录方法或动作时的文档。只需花一分钟即可记录一下函数的功能, 但是在代码的可读性方面却有很大的不同。
CakePHP文档块需要与页面的左边缘相对。所以是一个使用上面代码的简单示例。
/**
* Adds & saves a post as well as emails the admin to let them know the post has been added.
* Also performs some saving to another table
*
* @param array $data The post data
* @param bool $emailAdmin If set to true, will email the website admin
* @return bool Returns true if successful
*/
public function addPost($data = array(), $emailAdmin = true) {
如你所见, 编写doc块并不需要很长时间, 但是在代码的使用寿命方面却有很大的不同。最终, 这意味着代码可以像开发人员一样活在你身上。
同样带有在线注释。不要害怕解释你的代码在做什么以及为什么!从长远来看, 这使你更容易理解你的代码, 尤其是在其他开发人员正在查看它的情况下!
本文总结
CakePHP是一个广泛的, 功能齐全的框架。鉴于在配置方面遵循约定, CakePHP比其他基于PHP的框架更严格, 从某种意义上来说, “被迫”用户必须遵循某种方式布置代码。这可能会引起争议, 但是以我的经验, 它会导致代码库更加一致, 可读性和可理解性–开发团队将按照Cake的约定编写一致的代码, 而不是让开发人员”选择”应如何编写代码。 。
通过遵循CakePHP教程并确保代码编写正确, 应用程序可以经受住时间的考验。应该始终为明天编写代码-这样, 如果另一位开发人员几年后再查看特定的代码块, 他将理解该代码, 并遵守预期的标准。 CakePHP没什么不同, 希望本指南将有助于纠正一些不良习惯。
评论前必须登录!
注册