CakePHP 约定

我们非常喜欢约定优于配置的原则。虽然学习 CakePHP 的约定需要一些时间,但从长远来看,你会节省时间。通过遵循约定,你将获得免费的功能,并且可以从跟踪配置文件的维护噩梦中解脱出来。约定还可以带来非常统一的开发体验,让其他开发人员可以轻松加入并提供帮助。

控制器约定

控制器类名称是复数形式,驼峰式命名,并以 Controller 结尾。 UsersControllerMenuLinksController 都是控制器名称的示例。

控制器上的公共方法通常作为可通过 Web 浏览器访问的“操作”公开。它们使用骆驼式命名。例如, /users/view-me 映射到 UsersControllerviewMe() 方法(如果使用默认的破折号形式进行路由)。受保护或私有方法无法通过路由访问。

控制器名称的 URL 注意事项

正如你所见,单个单词的控制器映射到一个简单的 URL 路径(小写形式)。例如, UsersController(定义在名为 UsersController.php 的文件中)可以通过 http://example.com/users 访问。

虽然你可以通过任何你喜欢的方式路由多个单词的控制器,但约定是你的 URL 使用小写字母,并使用 DashedRoute 类以破折号形式分隔,因此 /menu-links/view-all 是访问 MenuLinksController::viewAll() 操作的正确形式。

当你使用 this->Html->link() 创建链接时,可以使用以下约定作为 url 数组

$this->Html->link('link-title', [
    'prefix' => 'MyPrefix' // CamelCased
    'plugin' => 'MyPlugin', // CamelCased
    'controller' => 'ControllerName', // CamelCased
    'action' => 'actionName' // camelBacked
]

有关 CakePHP URL 和参数处理的更多信息,请参阅 连接路由

文件和类名称约定

一般来说,文件名与类名匹配,并遵循 PSR-4 标准以实现自动加载。以下是一些类名及其文件名的示例

  • 控制器类 LatestArticlesController 将位于名为 LatestArticlesController.php 的文件中

  • 组件类 MyHandyComponent 将位于名为 MyHandyComponent.php 的文件中

  • 表类 OptionValuesTable 将位于名为 OptionValuesTable.php 的文件中。

  • 实体类 OptionValue 将位于名为 OptionValue.php 的文件中。

  • 行为类 EspeciallyFunkableBehavior 将位于名为 EspeciallyFunkableBehavior.php 的文件中

  • 视图类 SuperSimpleView 将位于名为 SuperSimpleView.php 的文件中

  • 助手类 BestEverHelper 将位于名为 BestEverHelper.php 的文件中

每个文件都将位于应用程序文件夹中的相应文件夹/命名空间中。

数据库约定

与 CakePHP 模型对应的表名称是复数形式,并使用下划线分隔。例如 usersmenu_linksuser_favorite_pages。表名称包含多个单词时,只需将最后一个单词复数化,例如 menu_links

包含两个或多个单词的列名称使用下划线分隔,例如 first_name

hasMany、belongsTo/hasOne 关系中的外键默认情况下被识别为相关表的(单数)名称,后跟 _id。因此,如果 Users hasMany Articles,则 articles 表将通过 user_id 外键引用 users 表。对于像 menu_links 这样的包含多个单词的表,外键将是 menu_link_id

连接表(或“联接”表)用于模型之间的 BelongsToMany 关系。这些表应根据它们连接的表命名。名称应复数化,并按字母顺序排序:articles_tags,而不是 tags_articlesarticle_tags如果未遵循此约定,bake 命令将无法工作。如果连接表除了链接外键之外还包含任何其他数据,则应为该表创建具体的实体/表类。

除了使用自动递增的整数作为主键之外,你还可以使用 UUID 列。每当你使用 Table::save() 方法保存新记录时,CakePHP 将使用 (Cake\Utility\Text::uuid()) 自动创建 UUID 值。

模型约定

表类名称是复数形式,驼峰式命名,并以 Table 结尾。 UsersTableMenuLinksTableUserFavoritePagesTable 都是与 usersmenu_linksuser_favorite_pages 表相匹配的表类名称示例。

实体类名称是单数形式,驼峰式命名,没有后缀。 UserMenuLinkUserFavoritePage 都是与 usersmenu_linksuser_favorite_pages 表相匹配的实体名称示例。

枚举类名称应使用 {Entity}{Column} 约定,枚举情况应使用驼峰式命名。

视图约定

视图模板文件根据它们显示的控制器函数命名,使用下划线形式分隔。 ArticlesController 类的 viewAll() 函数将在 templates/Articles/view_all.php 中查找视图模板。

基本模式是 templates/Controller/underscored_function_name.php

注意

默认情况下,CakePHP 使用英语词形变化规则。如果你的数据库表或列使用其他语言,你需要添加词形变化规则(单数变复数和反之亦然)。可以使用 Cake\Utility\Inflector 来定义自定义的词形变化规则。有关更多信息,请参见关于 Inflector 的文档。

插件约定

在包名中使用“cakephp-”作为 CakePHP 插件的前缀是有帮助的。这使名称在语义上与它所依赖的框架相关联。

不要使用 CakePHP 命名空间 (cakephp) 作为供应商名称,因为它是为 CakePHP 拥有的插件保留的。约定是使用小写字母和破折号作为分隔符。

// Bad
cakephp/foo-bar

// Good
your-name/cakephp-foo-bar

有关详细信息,请参见 awesome 列表推荐

总结

通过使用 CakePHP 约定命名应用程序的各个部分,你可以获得功能,而无需配置的麻烦和维护束缚。以下是一个将约定结合在一起的最终示例。

  • 数据库表:“articles”, “menu_links”

  • 表类:ArticlesTable,位于 src/Model/Table/ArticlesTable.php

  • 实体类:Article,位于 src/Model/Entity/Article.php

  • 控制器类:ArticlesController,位于 src/Controller/ArticlesController.php

  • 视图模板,位于 templates/Articles/index.php

使用这些约定,CakePHP 知道对 http://example.com/articles 的请求映射到 ArticlesControllerindex() 方法的调用,其中 Articles 模型会自动可用。所有这些关系都没有通过任何方式进行配置,只是通过创建你本来就需要创建的类和文件。

示例

articles

menu_links

数据库表

articles

menu_links

与 CakePHP 模型对应的表名是复数形式,并使用下划线分隔。

文件

ArticlesController.php

MenuLinksController.php

ArticlesTable.php

MenuLinksTable.php

表类名是复数形式,使用骆驼式命名法,并以 Table 结尾。

实体

Article.php

MenuLink.php

实体类名是单数形式,使用骆驼式命名法:Article 和 MenuLink。

ArticlesController

MenuLinksController

控制器

ArticlesController

MenuLinksController

复数形式,使用骆驼式命名法,以 Controller 结尾。

模板

Articles/index.php Articles/add.php Articles/get_list.php

MenuLinks/index.php MenuLinks/add.php MenuLinks/get_list.php

视图模板文件以它们显示的控制器函数命名,使用下划线分隔。

行为

ArticlesBehavior.php

MenuLinksBehavior.php

视图

ArticlesView.php

MenuLinksView.php

助手

ArticlesHelper.php

MenuLinksHelper.php

组件

ArticlesComponent.php

MenuLinksComponent.php

插件

错误:cakephp/articles 正确:you/cakephp-articles

cakephp/menu-links you/cakephp-menu-links

在包名中使用“cakephp-”作为 CakePHP 插件的前缀是有帮助的。不要使用 CakePHP 命名空间 (cakephp) 作为供应商名称,因为它是为 CakePHP 拥有的插件保留的。约定是使用小写字母和破折号作为分隔符。

每个文件都将位于应用程序文件夹中的相应文件夹/命名空间中。

数据库约定总结

外键

hasMany belongsTo/ hasOne BelongsToMany

默认情况下,关系由相关表的(单数)名称后跟 _id 来识别。用户 hasMany Articles,articles 表将通过 user_id 外键引用 users 表。

多个单词

menu_links 的名称包含多个单词,外键将是 menu_link_id

自动递增

除了使用自动递增的整数作为主键之外,你还可以使用 UUID 列。每当你使用 Table::save() 方法保存新记录时,CakePHP 将使用 (Cake\Utility\Text::uuid()) 自动创建 UUID 值。

联接表

应该以它们将要联接的模型表命名,或者 bake 命令将无法正常工作,并按字母顺序排列(articles_tags 而不是 tags_articles)。对于联接表上的附加列,你应该为该表创建一个单独的实体/表类。

现在你已经了解了 CakePHP 的基础知识,可以尝试通过 内容管理教程 来了解事物是如何组合在一起的。