[英]Processwire/API hook (PHP function inside a function)
我正在使用ProcessWire API编写钩子...强大的API是非常常见的做法。
以下工作完全正常...
$this->addHookAfter('Pages::saved', function(HookEvent $event) {
$arguments = $event->arguments();
$page = $event->arguments(0);
if ($page->template == 'user') {
// Require relevent libraries
require_once($this->config->paths->root . 'api/sendgrid/sendgrid-php.php');
// SendGrid API init
$sgAPIKey = "XXXX";
// Set email confirmation settings
$email_admin = 'test@example.com';
$email_customer = $page->email;
$email_admin_subject = "You added a new user $page->name";
$email_customer_subject = 'Your login details';
$from = new \SendGrid\Email("Example User", $email_admin);
$subject = "Sending with SendGrid is Fun";
$to = new \SendGrid\Email("Example User", $email_customer);
$content = new \SendGrid\Content("text/plain", "and easy to do anywhere, even with PHP");
$mail = new \SendGrid\Mail($from, $subject, $to, $content);
$sg = new \SendGrid($sgAPIKey);
$response = $sg->client->mail()->send()->post($mail);
// Dump SendGrid object with TracyDebugger
bd($mail);
}
});
但是,一旦我添加了一个发送电子邮件的功能(以设置两个单独的发送邮件功能(一个发送给管理员,一个发送给客户),它就根本不起作用了。没有错误...只是$ mail返回空值。
$this->addHookAfter('Pages::saved', function(HookEvent $event) {
$arguments = $event->arguments();
$page = $event->arguments(0);
if ($page->template == 'user') {
// Require relevent libraries
require_once($this->config->paths->root . 'api/sendgrid/sendgrid-php.php');
// SendGrid API init
$sgAPIKey = "XXXX";
// Set email confirmation settings
$email_admin = 'test@example.com';
$email_customer = $page->email;
$email_admin_subject = "You added a new user $page->name";
$email_customer_subject = 'Your login details';
$email_customer_body = 'This is a test';
function send_email($from_email, $to_email, $subject, $body) {
global $sgAPIKey;
$from = new \SendGrid\Email(null, $from_email);
$to = new \SendGrid\Email(null, $to_email);
$content = new \SendGrid\Content("text/html", $body);
$mail = new \SendGrid\Mail($from, $subject, $to, $content);
$sg = new \SendGrid($sgAPIKey);
$response = $sg->client->mail()->send()->post($mail);
}
send_email($email_admin, $email_customer, $email_customer_subject, $email_customer_body);
// Dump SendGrid object with TracyDebugger
global $mail;
bd($mail);
}
});
有什么理由为什么这样的功能不起作用? 是因为从技术上讲函数内部有一个函数? 我至少会以为它会返回错误。
PHP中允许使用函数内部的函数,但是您遇到的问题更多是范围界定方面的问题。 该功能完成后, $mail
不再是作用域,这意味着,除其他外,您不再可以访问该变量。
一种可能的解决方案是在函数完成时返回该变量,如下所示:
function send_email($from_email, $to_email, $subject, $body) {
global $sgAPIKey;
$from = new \SendGrid\Email(null, $from_email);
$to = new \SendGrid\Email(null, $to_email);
$content = new \SendGrid\Content("text/html", $body);
$mail = new \SendGrid\Mail($from, $subject, $to, $content);
$sg = new \SendGrid($sgAPIKey);
$response = $sg->client->mail()->send()->post($mail);
return $mail;
}
这样,在执行函数时,可以将其设置为变量。
顺便说一句,我注意到您尝试使用global
关键字访问该$mail
变量。 通常,这种做法不仅不受欢迎,而且在这种情况下永远都行不通。 global
关键字用于使global
名称空间中的变量可访问。 典型用法如下:
$global_variable = "foobar";
class Foo {
public static function test() {
return $global_variable;
}
public static function test_two() {
global $global_variable;
return $global_variable;
}
}
echo(Foo::test()); //echoes nothing, since in scope, the variable is not set
echo(Foo::test_two()); //echoes 'foobar', since we told PHP to put it in scope
TLDR: global
关键字使全局范围内的变量在本地范围内可见。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.