簡體   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