简体   繁体   English

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

[英]Processwire/API hook (PHP function inside a function)

I'm writing a hook using the ProcessWire API... pretty common practice with it's powerful API. 我正在使用ProcessWire API编写钩子...强大的API是非常常见的做法。

The below works completely fine... 以下工作完全正常...

$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);
    }

});

However, as soon as I add a function to send the email (in order to set up two separate send mail functions (one to admin, one to customer) it doesn't work at all. No errors... just $mail returns NULL. 但是,一旦我添加了一个发送电子邮件的功能(以设置两个单独的发送邮件功能(一个发送给管理员,一个发送给客户),它就根本不起作用了。没有错误...只是$ 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);
    }

});

Is there any reason why a function like this wouldn't work? 有什么理由为什么这样的功能不起作用? Is it because technically there's a function inside a function? 是因为从技术上讲函数内部有一个函数? I would've at least have thought it would've returned an error. 我至少会以为它会返回错误。

Functions inside of functions are allowed in PHP, however the issue that you are experiencing is more of an issue with scoping. PHP中允许使用函数内部的函数,但是您遇到的问题更多是范围界定方面的问题。 $mail is no longer in scope after that function is completed, meaning, among other things, that you can no longer access that variable. 该功能完成后, $mail不再是作用域,这意味着,除其他外,您不再可以访问该变量。

One possible solution is to return that variable when the function completes, like so: 一种可能的解决方案是在函数完成时返回该变量,如下所示:

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;
}

That way, when you execute the function, you can set it to a variable. 这样,在执行函数时,可以将其设置为变量。

As an aside, I noticed you attempted to use the global keyword to access that $mail variable. 顺便说一句,我注意到您尝试使用global关键字访问该$mail变量。 Not only is that typically frowned upon as bad practice, it would never work in this context. 通常,这种做法不仅不受欢迎,而且在这种情况下永远都行不通。 The global keyword is used to make variables that are in the global namespace accessable. global关键字用于使global名称空间中的变量可访问。 The typical use is as follows: 典型用法如下:

$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: The global keyword makes variables that are in the global scope, be visible in the local scope. TLDR: global关键字使全局范围内的变量在本地范围内可见。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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