我有三个PHP文件,其中包含不同位置的邮件功能。这是一个初步实施。现在我需要在我的应用程序日志中显示邮件发送计数和其他结果。我创建了几行语句,如下所示。我使用一个简单的increment ++运算符来递增从数据库中检索的值:
// Talking to database
$previous_val = $from_db; // Getting previous value stores
if(!empty($previous_val)|| $previous_val == 0 ){
$previous_val++;
// Storing previous value here
}
else{
$previous_val = 1;
// Storing previous value here
}
问题是,当邮件功能运行如下时,我已经将其他一些语句用于其他目的:
if(mail($to, $subject, $msg, $headers)){
// Other statements for other purposes are here
}
我不想在三个文件中包含counter语句。所以我想创建一个通用计数器函数并在邮件块中调用它和其他语句,如下所示:
function mail_counter(){
// Talking to database
$previous_val = from_db; // Getting previous value stores
if(!empty($previous_val)|| $previous_val == 0 ){
$previous_val++;
// Storing previous value here
}
else{
$previous_val = 1;
//Storing previous value here
}
}
我想在所有邮件功能中使用上述功能:
if(mail($to, $subject, $msg, $headers)){
// Other statements for other purpose are here
mail_counter();
}
一切正常。但是,我想进一步减少编码。这可能吗?我可以通过将mail_counter()
函数与mail
函数联系起来,以便每当调用mail
函数时,也可以调用mail_counter()
函数吗?就像在jQuery中绑定一样。我不知道是否可能?
我也想为我的自定义功能做同样的事情。就像调用函数x
时一样,我也需要执行函数y
。有很多重复代码。我的主要目标是创建良好的代码,无需重复代码和合理的行数。有人可以帮我解决这个问题吗?
答案 0 :(得分:0)
据我所知(几年前我问过这个)没有办法将观察者绑定到函数调用。唯一的方法(也是一种非常优雅的方式)就是编写自己的函数或方法,并传递与mail()
相同的变量,并让函数或方法调用mail()
。一般来说,邮件是一个" atomic"功能和大多数现代平台都没有直接在编码中调用它,而是拥有某种类型的Mail类,以便在发送之前进行预配置,处理日志记录等。
也许您可以调用您的函数enhanced_mail()
并使用它来处理发送附件,bcc等等。有些课程可以做到这一点,但我想在这里更直接地回答您的问题
答案 1 :(得分:0)
没有想太多,但也许你可以使用类似Cascade
类的回调选项。
class Cascade {
private $callbacks = [ ];
public function addCallback($callable) {
if (is_callable($callable)) {
$this->callbacks[] = $callable;
} else {
$test = [ $this, $callable ];
if (method_exists($test)) {
$this->callbacks[] = $test;
}
}
}
function __call($name, $arguments) {
$ret = call_user_func_array($name, $arguments);
foreach ($this->callbacks as $callback) {
$callback($name, $arguments);
}
return $ret;
}
}
在这种情况下,你会:
$mailer = new Cascade();
$mailer->addCallback(function() { ... });
$mailer->mail(arguments);
您也可以将最常用的函数放在Cascade(或Cascade的子类)中并使用静态方法:
Cascade::build('callback1')->mail(...arguments...)
或在特定子类的构建调用中添加默认回调:
LoggingCascade::build()->mail(...arguments...)
由于魔法__call方法,级联可以调用任何东西,只要它已定义。
使用相同的逻辑,您可以扩展类以添加例如requisites(在真实函数之前被称为的可调用,并且在某些情况下甚至可以中止调用 - 你做出必要的返回true或false并相应地执行)或过滤器(得到{{ 1}}并操纵它。)