PHP Telegram Bot框架中Command类getMessage()方法运行原理求助
问题
使用框架开发Telegram Bot时,发现抽象类Command中并未定义getMessage()方法,但代码里却直接调用了$this->getMessage(),无法理解其运行机制,求解答。
相关代码如下:
<?php /** * Class Command * * Base class for commands. It includes some helper methods that can fetch data directly from the Update object. * * @method Message getMessage() Optional. New incoming message of any kind — text, photo, sticker, etc. */ abstract class Command { /** * Constructor * * @param Telegram $telegram * @param Update|null $update */ public function __construct(Telegram $telegram, ?Update $update = null) { $this->telegram = $telegram; if ($update !== null) { $this->setUpdate($update); } $this->config = $telegram->getCommandConfig($this->name); } /** * Set update object * * @param Update $update * * @return Command */ public function setUpdate(Update $update): Command { $this->update = $update; return $this; } /** * Pre-execute command * * @return ServerResponse * @throws TelegramException */ public function preExecute(): ServerResponse { if ($this->need_mysql && !($this->telegram->isDbEnabled() && DB::isDbConnected())) { return $this->executeNoDb(); } if ($this->isPrivateOnly() && $this->removeNonPrivateMessage()) { $message = $this->getMessage(); if ($user = $message->getFrom()) { return Request::sendMessage([ 'chat_id' => $user->getId(), 'parse_mode' => 'Markdown', 'text' => sprintf( "/%s command is only available in a private chat.\n(`%s`)", $this->getName(), $message->getText() ), ]); } return Request::emptyResponse(); } }
解答
这是PHP框架常用的动态方法调用实现方式,核心靠两个关键点:
@method文档注解
你看到的@method Message getMessage()是给IDE看的注释标记,它不会影响代码运行,但能告诉IDE:这个类存在getMessage()方法,返回Message类型对象,避免IDE报“方法未定义”的错误提示。魔术方法
__call的代理逻辑
虽然Command类没显式写getMessage(),但这个基类(或它继承的父类、引入的trait)肯定实现了PHP的魔术方法__call。当调用类中不存在的方法时,PHP会自动触发__call方法处理请求。放到这个Telegram Bot框架里,逻辑大概是:
- 调用
$this->getMessage()时,因为类里没这个方法,触发__call - 从方法名里提取出要获取的对象类型(比如
Message) - 内部调用
$this->update->getMessage(),把结果返回给调用者
简单说就是,
Command类通过__call把这类方法请求,代理给了已存入的$update对象,相当于帮你简化了$this->update->getMessage()的写法。- 调用
内容的提问来源于stack exchange,提问作者Ahmad Ahmadpour
相关产品推荐
相关产品推荐

