phplaravelchatbotbotman

Incorrect reference to $this inside callback function of BotMan Conversation's ask method


I am using the BotMan framework in PHP to create a chatbot, and I have encountered an issue with the incorrect reference to $this inside a callback function used with the ask method of BotMan's Conversation class.

I have created a DepositConversation class that extends the Conversation class, and I have defined two methods, askAmount() and askPaymentMethod(), to ask questions to the user. However, when I call $this inside the callback function, which is the second parameter of the ask method, the $this reference is incorrect and refers to BotMan\BotMan\Messages\Conversation\InlineConversation instead of DepositConversation.

Here is an excerpt of my code:

use BotMan\BotMan\BotMan;
use BotMan\BotMan\Messages\Conversations\Conversation;

class DepositConversation extends Conversation
{
    // ...

    public function askAmount()
    {
        $this->ask('What is the amount you want to deposit?', function($answer) {
            // $this refers to BotMan\BotMan\Messages\Conversation\InlineConversation
            // instead of DepositConversation
            $this->amount = $answer->getText();
            
            // ...
        });
    }

    // ...
}

I expected $this to refer to the instance of DepositConversation so that I can access the class properties and perform additional operations. However, it doesn't seem to work as expected.

Has anyone encountered this issue before or knows how to resolve this incorrect reference error to $this inside a callback function of BotMan Conversation's ask method? Thank you in advance for your help!


Solution

  • Probably the ask method's Closure function is bound to another $this by using \Closure:bind.

    There's a simple trick in these use-cases, use $that or $self.

    public function askAmount()
    {   
        $that = $this;   // or $self = $this;
        $this->ask('What is the amount you want to deposit?', function($answer) use ($that) {
            $that->amount = $answer->getText();
            // ...
        });
    }