繁体   English   中英

Processwire / API挂钩(函数内的PHP函数)

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM