配置

    当然,还有其它可选的配置步骤可以采用,来充分利用 CakePHP 的灵活架构。可以容易地对继承自 CakePHP 核心的功能添加(新的功能),配置额外的/不同的网址(URL)映射(路由),以及定义额外/不同的词形变化(inflections)。

    CakePHP 期待的数据库配置信息位于 文件中。示例数据库配置文件在 app/Config/database.php.default 。一个完成的配置应该看起来像这样:

    (默认情况下)会使用 $default 连接数组,除非用模型的 $useDbConfig 属性指定了另外一个连接。例如,如果应用程序除了默认的数据库还有一个额外的遗留数据库,可以创建一个结构类似于 $default 数组的新的 $legacy 数据库连接数组,然后在适当的模型中设置 public $useDbConfig = 'legacy';,就可以使用遗留数据库了。

    填写配置数组中的键/值对以尽可能满足需求。

    • datasource
    • 该配置数组的数据源名称。例如:Database/Mysql、Database/Sqlserver、Database/Postgres、Database/Sqlite。可以使用 plugin syntax 指定要使用的插件数据源。
    • persistent
    • 是否使用连接数据库的持久化连接。当使用 SQLServer 时,应当不要启用持久化连接,因为这会造成难以诊断的崩溃。
    • host
    • 数据库服务器的主机名(或IP地址)。
    • login
    • 账号的用户名。
    • password
    • 账号的密码。
    • database
    • 该连接要使用的数据库名称。
    • prefix (可选)
    • 数据库中每个表名的前缀字符串。如果表没有前缀,设置为空字符串。
    • port (可选)
    • 用于连接服务器的 TCP 端口或 Unix 套接字(socket)。
    • encoding
    • 指定了发送 SQL 语句到服务器使用的字符集。对除了 DB2 数据库以外的所有数据库,默认使用数据库的默认编码。如果对 mysql/mysqli 连接想使用 UTF-8 编码,必须使用不带连字符的'utf8'。
    • schema
    • 用于 PostgreSQL 数据库设置,指定使用哪个 schema。
    • unix_socket
    • 用于支持通过 unix 套接字(socket)文件连接的驱动程序。如果使用 PostgreSQL数据库,并且想使用 unix 套接字,需要将 host 键留空。
    • ssl_key
    • SSL 密钥(SSL key)文件的路径(仅为 MySQL 所支持,要求 PHP 5.3.7+)。
    • ssl_cert
    • SSL 证书(SSL certificate)文件的路径(仅为 MySQL 所支持,要求 PHP 5.3.7+)。
    • ssl_ca
    • SSL 证书颁发机构(SSL certificate authority)文件的路径(仅为 MySQL 所支持,要求 PHP 5.3.7+)。
    • settings
    • 一个包含键值对的数组,在建立连接时应当作为 SET 命令发送到数据库服务器。该选项当前只被 Mysql、Postgres 和 Sqlserver 所支持。

    在 2.4 版更改: 参数 settingsssl_keyssl_certssl_ca 是在 2.4 版本中新增的。

    注解

    前缀设置作用于表,而不是 模型。举个例子,如果为 Apple 和 Flavor 模型创建了一个连接表,应当命名为 prefixapples_flavors(而不是prefix_apples_prefix_flavors),前缀设置应设为 'prefix'。

    在这个时候,你也许可以看下 。对表(以及某些字段)的正确命名让你自动获得一些功能,而且避免配置。例如,如果将表命名为big_boxes,模型命名为 BigBox,控制器命名为 BigBoxesController,那这一切就能够自动协作了。按照约定,数据库表名应当使用下划线分隔的小写复数形式 — 例如:bakers、pastry_stores 和 savory_cakes。

    额外的类路径

    偶尔,在同一个系统上的应用程序之间共享 MVC 类库是很有用的。如果想要在两个应用程序间使用同一个控制器,可以使用 CakePHP 的 bootstrap.php 把这些额外的类引入。

    在 bootstrap.php 使用 App::build() 可以定义额外的路径,CakePHP 就会在这些路径中搜寻类:

    1. App::build(array(
    2. 'Model' => array(
    3. '/path/to/models',
    4. '/next/path/to/models'
    5. ),
    6. 'Model/Behavior' => array(
    7. '/path/to/behaviors',
    8. '/next/path/to/behaviors'
    9. ),
    10. 'Model/Datasource' => array(
    11. '/path/to/datasources',
    12. '/next/path/to/datasources'
    13. ),
    14. 'Model/Datasource/Database' => array(
    15. '/path/to/databases',
    16. '/next/path/to/database'
    17. ),
    18. 'Model/Datasource/Session' => array(
    19. '/path/to/sessions',
    20. '/next/path/to/sessions'
    21. ),
    22. 'Controller' => array(
    23. '/path/to/controllers',
    24. '/next/path/to/controllers'
    25. ),
    26. 'Controller/Component' => array(
    27. '/path/to/components',
    28. '/next/path/to/components'
    29. ),
    30. 'Controller/Component/Auth' => array(
    31. '/path/to/auths',
    32. '/next/path/to/auths'
    33. ),
    34. 'Controller/Component/Acl' => array(
    35. '/path/to/acls',
    36. '/next/path/to/acls'
    37. ),
    38. 'View' => array(
    39. '/path/to/views',
    40. '/next/path/to/views'
    41. ),
    42. 'View/Helper' => array(
    43. '/path/to/helpers',
    44. '/next/path/to/helpers'
    45. ),
    46. 'Console' => array(
    47. '/path/to/consoles',
    48. '/next/path/to/consoles'
    49. ),
    50. 'Console/Command' => array(
    51. '/path/to/commands',
    52. '/next/path/to/commands'
    53. ),
    54. 'Console/Command/Task' => array(
    55. '/path/to/tasks',
    56. '/next/path/to/tasks'
    57. ),
    58. 'Lib' => array(
    59. '/next/path/to/libs'
    60. ),
    61. 'Locale' => array(
    62. '/path/to/locales',
    63. '/next/path/to/locales'
    64. ),
    65. 'Vendor' => array(
    66. '/path/to/vendors',
    67. '/next/path/to/vendors'
    68. ),
    69. 'Plugin' => array(
    70. '/path/to/plugins',
    71. '/next/path/to/plugins'
    72. ),
    73. ));

    注解

    所有额外路径的配置应该在程序的 bootstrap.php 最开始定义。这样会确保应用程序的其余部分可以使用这些路径。

    每个 CakePHP 应用程序包含一个配置文件 app/Config/core.php ,决定 CakePHP 的内部行为。这个文件是一个 Configure 类变量和常量定义的集合,决定应用程序的行为。在我们深入这些特定的变量之前,你需要熟悉 ,CakePHP的配置注册表类。

    Configure 类用来管理一系列 CakePHP 核心配置变量。这些变量可在app/Config/core.php 文件中找到。下面是每个变量的描述、以及如何影响到程序的。

    • debug
    • 改变 CakePHP 调试输出。

      • 0 = 生产模式。无输出。
      • 1 = 显示错误和警告。
      • 2 = 显示错误,警告和 SQL 语句。 [只有在视图或布局中添加$this->element('sql_dump') 才会显示 SQL 日志。]
    • Error
    • 配置处理应用程序错误的错误处理器。默认使用ErrorHandler::handleError()。当 debug > 0 时,使用 显示错误,而当 debug = 0 时,使用 CakeLog将错误记录在日志中。

    子键:

    • handler - callback - 处理错误的回调方法。可设置为任何回调类型,包括匿名函数。
    • level - int - 要捕获的错误等级。
    • trace - boolean - 是否在日志文件中记录错误的堆栈跟踪(stack trace)信息。
      • Exception
      • 配置异常处理程序用于未捕获的异常。默认情况下,会使用ErrorHandler::handleException()。对异常会显示一个 HTML 页面。当 debug > 0 时,像 Missing Controller 这样的框架错误会显示出来。而当 debug = 0 时,框架错误被强制转换为通常的 HTTP 错误。欲知更多异常处理的信息,请参见异常 一节。
      • App.baseUrl
      • 如果你不想或者无法在你的服务器上运行 mod_rewrite (或者一些其它兼容模块),你就要使用 CakePHP 的内置美观网址了。在 /app/ConfigScore.php 中,对下面这行去掉注释:
    1. Configure::write('App.baseUrl', env('SCRIPT_NAME'));

    也要删除这些 .htaccess 文件:

    1. /.htaccess
    2. /app/.htaccess
    3. /app/webroot/.htaccess

    这会让网址看起来象www.example.com/index.php/controllername/actionname/param rather而不是 www.example.com/controllername/actionname/param.

    如果你把 CakePHP 安装到不是 Apache 的 web 服务器上,你可以从 一节找到在其它服务器上使网址重写运行的说明。

    • App.encoding
    • 定义应用程序使用的编码。该编码用来生成布局(layout)中的字符集,和编码实体。这应当符合为数据库指定的编码值。
    • Routing.prefixes
    • 如果想要使用象 admin 这样的 CakePHP 前缀路由(prefixed routes),去掉对该定义的注释。设置该变量为你想要使用的路由的前缀名称数组。对此后面有更多的描述。
    • Cache.disable
    • 当设置为 true 时,整个网站的持久化缓存会被禁用。这会导致所有的Cache 读/写失败。
    • Cache.check
    • 如果设置为 true,启用视图缓存。仍然需要在控制器中启用,但是该变量开启了这些设置的检测。
    • Session
    • 包含设置数组,用于会话(session)配置。defaults 键用于定义会话的默认预设,这里声明的任何设置会覆盖默认配置的设置。

    子键

    • name - 要使用的,cookie 的名字。默认为'CAKEPHP'
    • timeout - 要会话存在的分钟数。这个超时是由 CakePHP 处理的。
    • cookieTimeout - 要会话 coookie 存在的分钟数。
    • checkAgent - 在启动会话时,要检查用户代理吗?在处理旧版 IE、ChromeFrame 或者某些网络浏览设备以及 AJAX 时,你或许想要设置该值为 false。
    • defaults - 会话作为基础使用的默认配置集。有四种内置(默认配置集): php、cake、cache、database。
    • handler - 可以用来启用自定义会话处理器。期待可用于session_save_handler 的回调数组。使用该选项会自动添加session.save_handler 到 ini 数组。
    • autoRegenerate - 启用该设置,就启用了会话的自动延续,以及频繁变化的sessionid。参看 CakeSession::$requestCountdown
    • ini - 要设置的额外 ini 值的关联数组。
      内置默认值为:

    • 'php' - 使用在 php.ini 中定义的设置。

    • 'cake' - 在 CakePHP 的 /tmp 目录中保存会话文件。
    • 'database' - 使用 CakePHP 的数据库会话。
    • 'cache' - 使用 Cache 类保存会话。
      要定义自定义会话处理器,把它保存在app/Model/Datasource/Session/<name>.php 中。确保这个类实现了CakeSessionHandlerInterface,并设置 Session.handler 为

    要使用数据库会话,用 cake 控制台命令运行 app/ConfigSSchema/sessions.php数据结构: cake schema create Sessions

    • Security.salt
    • 用于 安全哈希(security hashing)的一个随机字符串。
    • Security.cipherSeed
    • 随机数字字符串(只允许数字),用来加密/解密字符串。
    • Asset.timestamp
    • 在使用正确的助件时,在资源文件网址(CSS、JavaScript、Image)末尾附加特定文件最后修改的时间戳。

    合法值:

    • (boolean) false - 什么也不做(默认)
    • (boolean) true - 当 debug > 0 时附加时间戳
    • (string) 'force' - 当 debug >= 0 时附加时间戳
      • Acl.classname, Acl.database
      • 用于 CakePHP 的访问控制列表(Access Control Access)功能的常数。欲知详情,参见访问控制列表一章。

    注解

    在 core.php 中也有缓存配置 — 稍安勿躁,后面会讲到。

    类可以随时用来读写核心配置设置。这很方便,例如,在应用程序中要对有限的一部分逻辑启用 debug 设置。

    配置常量

    • constant LOG_ERROR
    • 错误常量。用于区分错误的日志记录和调试。当前 PHP 支持 LOG_DEBUG。

    核心缓存配置

    CakePHP 在内部使用两个缓存配置,cake_model 和 。cake_core 用于保存文件路径和对象位置。cakeMmodel 用于保存数据结构描述和数据源的源列表。建议对这些配置使用象 APC 或 Memcached 这样的高速缓存存储,因为它们会在每次请求时读取。默认情况下,当 debug 大于 0 时这两个配置都是每 10 秒就会过期。

    就象所有缓存在 Class 中的缓存数据一样,可以使用 清除数据。

    Configure 类

    • class Configure
    • 尽管在 CakePHP 中很少需要配置,有时对应用程序有自己的配置规则还是有用的。过去你也许在某些文件中定义变量或常量来定义自定义配置值。这么做迫使你在每次需要这些值时必须引入那个配置文件。

    CakePHP 的 Configure 类可以用来保存和读取应用程序或运行时相关的值。当心,这个类允许在其中保存任何东西,然后在代码的任何部分使用它:明显诱使人打破作为 CakePHP的设计目的的 MVC 模式。Configure 类的主要目标是保持变量集中在一起,可在许多对象之间共享。记得尽量保持“约定重于配置”,你就不会打破我们设定好的 MVC 结构了。

    这个类可以在应用程序的任何地方以静态方式调用:

    1. Configure::read('debug');
    • static Configure::write($key, $value)
    • 参数:
      • $key (string) — 要写入的键,可以是 值。
      • $value (mixed) — 要存储的值。

    write() 在应用程序的配置中存储数据:

    1. Configure::write('Company.name','Pizza, Inc.');
    2. Configure::write('Company.slogan','Pizza for your body and soul');

    注解

    $key 参数中使用的 dot notation 可以用来把配置设置组织成符合逻辑的分组。

    上面的例子也可以写成一个调用:

    1. Configure::write(
    2. 'Company',
    3. array(
    4. 'name' => 'Pizza, Inc.',
    5. 'slogan' => 'Pizza for your body and soul'
    6. )
    7. );

    可以使用 Configure::write('debug', $int) 来动态切换调试和生产模式。这对与 AMF 或 SOAP 的交互尤其方便,因为调试信息回引起解析的问题。

    • static Configure::read($key = null)
    • 参数:
      • $key (string) — 读取的键名,可以是 dot notation 值。

    用来从应用程序中读取配置数据。默认是 CakePHP 重要的 debug 值。如果提供键,则返回数据。使用上面的 write() 的例子,可以读取那个数据:

    如果$key为null,返回Configure中所有的值。如果对应制定的键$key的值不存在,则返回null。

    • static Configure::consume($key)
    • 参数:
      • $key (string) — 读取的键名,可以是 dot notation 值。

    从Configure读取并删除键。当你想要合并读取和删除值为单一操作时,这比较有用。

    • static Configure::check($key)
    • 参数:
      • $key (string) — 要检测的键。

    检测键/路径是否存在,且值不是 null 。

    2.3 新版功能: Configure::check() 是在 2.3 版本中新增的

    • static Configure::delete($key)
    • 参数:
      • $key (string) — 要删除的键,可以是 值。

    用来从应用程序中的配置中删除信息:

    1. Configure::delete('Company.name');
    • static Configure::version
    • 返回当前应用程序的 CakePHP 版本。

    • static Configure::config($name, $reader)

    • 参数:
      • $name (string) — 附加的读取器(reader)的名称。
      • $reader (ConfigReaderInterface) — 附加的读取器实例。

    在 Configure 类上附加一个配置读取器。然后附加的读取器就可以加载配置文件。欲知如何读取配置文件,请参见 。

    • static Configure::configured($name = null)
    • 参数:

    或者检查指定名称的读取器是否附加了,或者得到附加的读取器列表。

    • static Configure::drop($name)
    • 去掉一个连接的读取器对象。

    CakePHP 附带两种内置的配置文件读取器。PhpReader 能够读取 PHP 配置文件,与 Configure 类之前读取的格式相同。 能够读取 ini配置文件。欲知 ini 文件的更多细节,请参见PHP 文档。为了使用核心配置读取器,需要使用 把它附加到 Configure 类上:

    1. App::uses('PhpReader', 'Configure');
    2. // 从 app/Config 读取配置文件
    3. Configure::config('default', new PhpReader());
    4.  
    5. // 从其它路径读配置文件。
    6. Configure::config('default', new PhpReader('/path/to/your/config/files/'));

    可以有多个附加到 Configure 类的读取器,每个读取不同的配置文件,或者从不同种类的来源读取。可以用 Configure 类的一些其它方法与附加的读取器交互。要查看附加了哪些读取器别名,可以使用 Configure::configured() 方法:

    1. // 得到附加的读取器的别名数组。
    2. Configure::configured();
    3.  
    4. // 检查是否附加了某个特定的读取器
    5. Configure::configured('default');

    也可以删除附加的读取器。Configure::drop('default') 方法会删除默认的读取器别名。以后任何使用该读取器加载配置文件的企图都会失败。

    • static Configure::load($key, $config = 'default', $merge = true)
    • 参数:
      • $key (string) — 要加载的配置文件的标识符。
      • $config (string) — 配置的读取器的别名。
      • $merge (boolean) — 是否要合并读取的文件内容,或者覆盖现有的值。

    一旦在 Configure 类上附加了配置读取器,就可以加载配置文件:

    1. // 使用 'default' 读取器对象加载 my_file.php
    2. Configure::load('my_file', 'default');

    加载的配置文件把它们的数据与 Configure 类中的已有的运行时配置合并。这允许对现有的运行时配置进行覆盖和增加新值。设置 $merge 为 true,值就不会覆盖已有的配置了。

    创建或者修改配置文件

    • static Configure::dump($key, $config = 'default', $keys = array())
    • 参数:
      • $key (string) — 要创建的文件/保存的配置的名称。
      • $config (string) — 要保存数据的读取器的名称。
      • $keys (array) — 要保存的顶层键的列表。默认为所有键。

    把 Configure 类中的所有或部分数据保存到配置读取器支持的文件或存储系统中。序列化的格式由 $config 指定的附加配置读取器来决定。例如,如果 'default' 适配器为 类,生成的文件将会是一个 PHP 配置文件,能够由 类加载。

    假定 'default' 读取器是一个 PhpReader 的实例。保存 Configure 类中的所有数据到文件 my_config.php 中:

    1. Configure::dump('my_config.php', 'default');

    仅保存错误处理配置:

    1. Configure::dump('error.php', 'default', array('Error', 'Exception'));

    2.2 新版功能: 在 2.2 版本中增加了 Configure::dump() 方法。

    存储运行时配置

    • static Configure::store($name, $cacheConfig = 'default', $data = null)
    • 参数:
      • $name (string) — 缓存文件的存储键。
      • $cacheConfig (string) — 用来存储配置数据的缓存配置的名称。
      • $data (mixed) — 或者为要保存的数据,或者为 null 来保存 Configure 类中的所有数据。

    也可以保存运行时配置的值,在以后的请中使用。由于配置只记得当前请求的值,如果想要在以后的请求中使用,需要保存任何修改过的配置信息:

    保存的配置数据持久化在 Cache 类中。这让你可以把配置信息保存在任何可以与 类交互的存储引擎中。

    • static Configure::restore($name, $cacheConfig = 'default')
    • 参数:
      • $name (string) — 要加载的存储键。
      • $cacheConfig (string) — 要加载数据的源的缓存配置。

    一旦保存了运行时配置,很可能需要恢复它,从而可以再次访问。Configure::restore() 方法就是做这件事情的:

    1. // 从缓存恢复运行时配置。
    2. Configure::restore('user_1234', 'default');

    在恢复配置信息时,重要的是要使用保存时使用的相同的键和缓存配置来恢复。恢复的信息会合并到现有运行时配置上。

    创建自己的配置读取器

    既然配置读取器是 CakePHP 可以扩展的部分,就可以在应用程序和插件中创建配置读取器。配置读取器需要实现 ConfigReaderInterface 接口。该接口定义了read 方法为唯一必需的方法。如果你真的喜欢 XML 文件,你可以为应用程序创建一个简单的 Xml 配置读取器:

    1. // 在 app/Lib/Configure/MyXmlReader.php 中
    2. App::uses('Xml', 'Utility');
    3. class MyXmlReader implements ConfigReaderInterface {
    4. public function __construct($path = null) {
    5. if (!$path) {
    6. $path = APP . 'Config' . DS;
    7. }
    8. $this->_path = $path;
    9. }
    10.  
    11. public function read($key) {
    12. $xml = Xml::build($this->_path . $key . '.xml');
    13. return Xml::toArray($xml);
    14. }
    15.  
    16. // 在 2.3 版本中,还要求 dump() 方法
    17. public function dump($key, $data) {
    18. // 保存数据到文件的代码
    19. }
    20. }

    app/Config/bootstrap.php 中可以附加这个读取器并使用它:

    1. App::uses('MyXmlReader', 'Configure');
    2. Configure::config('xml', new MyXmlReader());
    3. ...
    4.  
    5. Configure::load('my_xml');

    警告

    把自定义配置类叫做 XmlReader,可不是个好主意,因为这个类名已经是 PHP内部的一个类了:

    配置读取器的 read() 方法必需返回一个名为 $key 的资源包含的配置信息数组。

    • interface ConfigReaderInterface
    • 定义读取配置数据和在 类中保存配置数据的类使用的接口。

    • ConfigReaderInterface::read($key)

    • 参数:
      • $key (string) — 要加载的键名或者标识符。

    这个方法应当加载/解析由 $key 标识的配置数据,并返回文件中的数据数组。

    • ConfigReaderInterface::dump($key, $data)
    • 参数:
      • $key (string) — 要写入的标识符。
      • $data (array) — 要保存的数据。

    这个方法把提供的配置数据保存到 $key 所指定的键中。

    2.3 新版功能: 在 2.3 版本中增加了 ConfigReaderInterface::dump() 方法。

    • exception ConfigureException
    • 在加载/保存/恢复配置数据时,当发生错误时抛出。 接口的实现在遇到错误时应当抛出这个异常。

    内置配置读取器

    • class PhpReader
    • 让你可以读取保存为普通 PHP 文件的配置文件。你可以从 app/Config 目录中读取,也可以用 plugin syntax 从插件配置目录中读取。文件 必须包含 $config 变量。下面是一个配置文件示例:
    1. $config = array(
    2. 'debug' => 0,
    3. 'Security' => array(
    4. 'salt' => 'its-secret'
    5. ),
    6. 'Exception' => array(
    7. 'handler' => 'ErrorHandler::handleException',
    8. 'renderer' => 'ExceptionRenderer',
    9. 'log' => true
    10. )
    11. );

    没有 $config 的文件将会导致 。

    在 app/Config/bootstrap.php 中插入如下代码来加载自定义配置文件:

    1. Configure::load('customConfig');
    • class IniReader
    • 让你可以读取保存为普通 .ini 文件的配置文件。ini 文件必须与 PHP 的parse_ini_file 函数兼容,并且从以下改进中获益

      • 点分隔的值会扩展为数组。
      • 象 'on' 和 'off' 这样的类似布尔类型的值会转化为布尔值。
        下面是一个 ini 文件示例:
    1. debug = 0
    2.  
    3. Security.salt = its-secret
    4.  
    5. [Exception]
    6. handler = ErrorHandler::handleException
    7. renderer = ExceptionRenderer
    8. log = true

    上述 ini 文件会得到与之前的 PHP 示例相同的最终配置数据。数组结构可以通过点分隔的值或者小节创建。小节可以包含点分隔的键来实现更深的嵌套。

    CakePHP 的命名约定真的很好 —— 你可以把数据库表命名为 big_boxes,把模型命名为BigBox,把控制器命名为 BigBoxesController,所有这一切就可以自动在一起运作。CakePHP 知道如何把这些联结在一起,是通过单词的单数和复数形式之间的词形变化。

    偶尔(特别是对我们操非英语的朋友们),你会遇到 CakePHP 的 类(把单词变成复数形式、单数形式、驼峰命名形式和下划线分隔形式的类)不像你希望的那样进行词形变化。如果 CakePHP 认不出你的 Foci 或者 Fish,你可以告诉 CakePHP这些特殊情形。

    加载自定义词形变化

    你可以在 app/Config/bootstrap.php 文件中用 Inflector::rules()方法加载自定义词形变化:

    或者:

    1. Inflector::rules('plural', array('irregular' => array('phylum' => 'phyla')));

    会把提供的规则合并到 lib/Cake/Utility/Inflector.php 中定义的词形变化集合中,新增的规则具有比核心规则更高的优先级。

    引导启动 CakePHP

    如果有任何额外的配置需求,可以使用 CakePHP 位于 app/Config/bootstrap.php 的引导文件。这个文件会在 CakePHP 的核心启动引导后执行。

    此文件非常适合用于一些常见的启动任务:

    • 定义方便的函数。
    • 注册全局常量。
    • 定义额外的模型、视图和控制器的路径。
    • 创建缓存配置。
    • 加载配置文件。
      当向引导文件添加内容时请注意保持 MVC 的软件设计模式:也许会忍不住想把格式化函数放在那里,从而可以在控制器中使用。

    请克制住这种想法。以后你会庆幸你在程序其它的部分这么做的。