全局便捷方法
嗯,在 PHP(至少 5.2)中你不能真正做到monkey patching,这对于在你离开后必须维护你的代码的开发人员来说可能是一件好事。 :)
CakePHP - 作为一个具有严格约定的 MVC 框架 - 仅允许您单独扩展您需要的部分(即AppModel、AppController 等),从而使您很难打破 MVC 范式,并且在核心中保持面向对象的基础不受影响(使得添加“可以在任何地方使用”以防潜在滥用的代码变得困难)。
至于添加超越所有 MVC 分离的功能,这里是app/config/bootstrap.php。当您将代码放在这里时,很明显它不是框架的一部分(完全正确),但允许您在 CakePHP 加载之前添加这些基本要素。在这里可以做的一些选择可能是:
- 创建一个函数(例如,一些自定义函数,例如
error(),它们以您喜欢的方式调用CakeLog::write()。)
- 加载一个类(例如,加载你自己的日志类,称为..
Log,这样你就可以在某些地方调用Log::error())
- 见下文:
记录器 API
Cake 确实允许对诸如记录器之类的东西进行许多自定义,但不幸的是,在这种情况下,向我们公开的 API 已经在核心中定义了。登录 CakePHP 的 API 如下,你可以在任何你喜欢的地方使用任何一种方法(嗯,前者只在类中):
$this->log($msg, $level) // any class extending `Object` inherits this
// or
CakeLog::write($level, $message); // this is actually what is called by the above
您试图消除的任意$level 参数实际上是quite a powerful feature:
$this->log('Cannot connect to SMTP server', 'email'); // logs to app/logs/email.log
// vs
$this->email('Cannot connect to SMTP server'); // ambiguous - does this send emails?
我们刚刚创建了一个全新的日志类型,没有编写额外的代码行,很清楚我们代码的意图是什么。
自定义记录器
核心开发人员对add a condition 有远见,如果我们愿意,我们可以完全替换记录器类:
function log($msg, $type = LOG_ERROR) {
if (!class_exists('CakeLog')) { // winning
require LIBS . 'cake_log.php';
}
// ...
如您所见,核心 CakeLog 类仅在不存在此类类时才会被实例化,让您有机会插入自己创建的内容(或稍加调整的精确副本 - 尽管您希望同步随核心更改 - 手动 - 升级时):
// app/config/bootstrap.php
App::import('Lib', 'CakeLog'); // copy cake/libs/cake_log.php to app/lib/cake_log.php
以上内容可以让您完全控制应用程序中CakeLog 类的实现,因此您可以执行一些操作,例如将调用类名称动态添加到日志消息中。但是,更直接的方式(以及其他类型的日志记录 - 例如数据库)是create a custom log stream:
CakeLog::config('file', array(
'engine' => 'FileLog', // copy cake/libs/log/file_log.php to app/libs/log/file_log.php
));
TL;DR - 虽然您可以在 CakePHP 引导之前加载自己的代码,或者在提供的每个 MVC 层中单独使用,但您不应该篡改核心提供的对象层次结构.这使得添加全局继承的类方法变得困难。
我的建议:使用提供给您的 API 并专注于添加更多功能而不是语法上的细微差别。 :)