CakePHP 约定
我们是约定优于配置的忠实信徒。花费很少的时间来学习 CakePHP 的约定,长远来看,会节省你的时间:通过遵循约定,你能够获得免费的功能,并且可以从维护和追踪配置文件的梦魇中解脱。约定还造成了系统开发的统一性,使其他程序员更易于加入和提供帮助。
CakePHP 约定提炼于多年的 web 开发经验和最佳实践。 我们建议你在用 CakePHP 编程时使用这些约定,但是我们也要说明这些原则很容易覆盖 —— 在与遗留的系统一同工作时,有些东西非常有用。
控制器约定
控制器类名是复数的、驼峰格式,并且使用 Controller 结尾。 PeopleController 和 LatestArticlesController 都是约定类名的例子。
为控制器编写的第一个方法很可能是 index() 方法。 当只指定了控制器,但没有指定动作(action)时,CakePHP 的默认行为是执行这个控制器的 index() 方法。 例如: http://www.example.com/apples/ 请求会调用ApplesController 的 index() 方法,而 http://www.example.com/apples/view/ 会调用 ApplesController 的 view 方法。
在 CakePHP 中,你还可以通过在控制器方法的名称前添加下划线来改变其可见性。 如果一个控制器方法以一个下划线开头,这个方法将不能通过 web 访问,但可以在内部使用。例如:
1 class NewsController extends AppController { 2 3 public function latest() { 4 $this->_findNewArticles(); 5 } 6 7 protected function _findNewArticles() { 8 // Logic to find latest news articles 9 } 10 }
用户可以象通常那样访问 http://www.example.com/news/latest/ , 一些人尝试访问http://www.example.com/news/_findNewArticles/ 就会得到一个错误, 因为这个方法是以下划线开头的。 你还可以使用 PHP 的可见性关键词来指定一个方法是否能通过 url 访问。非公有的方法将不能被访问。
关于控制器命名的思考
正像你看到的那样,单个单词命名的控制器简单容易的用小写的 URL 路径访问,ApplesController (在 ‘ApplesController.php’ 定义的)可以通过 http://example.com/apples 访问。
多个单词组成的控制器 能 被下面的几种功能相同的方法任意扭曲:
- /redApples
- /RedApples
- /Red_apples
- /red_apples
都将解析为 RedApples 控制器的 index 方法。但是这个约定是你的 url 是小写加下划线,因此 /red_apples/go_pick 可以正确的访问 RedApplesController::go_pick 动作。
关于 CakePHP URL 的更多信息和参数处理,参见 路由配置 。
文件名和类名约定
通常,文件名和类名是相匹配的,也遵守驼峰规则。因此在 Cake里,如果你的类名是 MyNiftyClass,对应的文件名就是 MyNiftyClass.php。 下面的例子是关于如何为 CakePHP 应用程序中不同类型的类所在的文件命名的经典规则:
- 控制器类 KissesAndHugsController 存储在 KissesAndHugsController.php 文件中
- 组件类 MyHandyComponent 存储在 MyHandyComponent.php 文件中
- 模型类 OptionValue 存储在 OptionValue.php 文件中
- 行为类 EspeciallyFunkableBehavior 存储在 EspeciallyFunkableBehavior.php 文件中
- 视图类 SuperSimpleView 存储在 SuperSimpleView.php 文件中
- 助手类 BestEverHelper 存储在 BestEverHelper.php 文件中
每个文件都存放在 app 文件夹的相应子文件夹中。
模型和数据库约定
模型类是单数、驼峰式的。Person、BigPerson 和 ReallyBigPerson 都是符合约定的模型命名实例。
表名与 CakePHP 的模型一致,是单数的,用下划线间隔单词的。表 people、 big_people 和 really_big_people 分别对应上面提及的模型。
可以使用工具库 弯曲 检验单词的单/复数形式。更多信息参见 弯曲 。
两个以上单词构成的域名用下划线间隔,如 first_name 。
hasMany、belongsTo 或者 hasOne 关系中的外键默认是用关系表名带 _id 来识别。 所以,如果 Baker hasMany Cake,cake 表将使用 baker_id 外键引用 baker 表。对于多个单词构成的表,例如 category_types,外键就是 category_type_id 。
在模型间使用 hasAndBelongsToMany (HABTM) 关系连接表,其命名将按照字母顺序(apples_zebras 优先于 zebras_apples)。
每个 CakePHP 模型中的所有表(包括期望连接的表),仅包含单域主键用于唯一标识一个行。 也许你希望模型表没有单域主键,但 CakePHP 约定要求表加入一个单域主键。如果你想使用表模型,就必须加入一个单域主键。
CakePHP 不支持多域主键。如果你想要直接控制你的连接表数据,使用 query 调用或者按照默认模式加入一个单域主键。例如:
1 CREATE TABLE posts_tags ( 2 id INT(10) NOT NULL AUTO_INCREMENT, 3 post_id INT(10) NOT NULL, 4 tag_id INT(10) NOT NULL, 5 PRIMARY KEY(id));
相对于使用 auto-increment 键作为主键,你还可以使用 char(36) 类型。Cake 将在你使用 Model::save 方法保存一条记录时使用唯一的 36 个字节的 uuid (String::uuid) 。
视图约定
视图模板文件是用控制器的函数命名的,用下划线间隔多个单词。PeopleController 类的 getReady() 函数的视图模板是 /app/View/People/get_ready.ctp。
基本的模式是 /app/View/Controller/underscored_function_name.ctp。
如果使用 CakePHP 约定命名你的应用程序片断,你不需要维护配置就可以获得需要的功能。这是遵循约定的最终实例:
- 数据库表: “people”
- 模型类: “Person”,在 /app/Model/Person.php 文件中
- 控制器类: “PeopleController”,在 /app/Controller/PeopleController.php 文件中
- 视图模板,在 /app/View/People/index.ctp 文件中
使用这些约定,Cakephp 知道 http://example.com/people/ 请求是要调用 PeopleController 类的 index() 函数,Person 模型自动有效(并且自动绑定到数据库的‘people’表)并渲染一个文件。这些关系完全不需要配置,你只需要建立相应的文件即可。
现在,你已经了解了 CakePHP 的基本原理,你可以试着通过运行 博客课程 ,看看它们是怎样一直工作的。