类中的动态方法定义


Dynamic method definition in a class

我正在尝试创建一个PrestaShop模块,该模块使用钩子触发POST请求。

钩子被这样调用:

if(is_callable(array($moduleInstance, 'hook'.$hook_name)) {
    $moduleInstance->{'hook'.$hook_name}($hook_args);
}

这意味着要捕获hook事件,我需要在类中提供现成的方法。假设我想调用一个名为myCustomEvent的钩子,我需要以下内容:

class myModule extends Module {
    public function hookmyCustomEvent($params) {
    }
}

然而,我想做的是在数据库中存储一个钩子事件列表,并在调用钩子时激发它们。但要做到这一点,我需要在类中定义一个方法。我想做的是有一种"魔术"/通配符方法,可以从hook开始捕获所有这些方法。

这可能吗?

编辑:

这些方法并不存在,因为我本质上希望它们被动态调用,执行另一个方法。

示例的真实代码:

public function hookactionValidateOrder($params) {
    $this->fireWebhook('actionValidateOrder', $params);
}
public function hookactionOrderStatusUpdate($params) {
    $this->fireWebhook('actionOrderStatusUpdate', $params);
}
public function hookactionUpdateQuantity($params) {
    $this->fireWebhook('actionUpdateQuantity', $params);
}
private function fireWebhook($event, $data) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, Configuration::get('HOOK_URL'));
    curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
        'event' => $event,
        'data' => $data
    ]));
    curl_exec($ch);
    curl_close($ch);
}
public function __call($methodName, array $params) {
    if (substr($methodName, 0, 4) === 'hook') {
        // this matches something starting with "hook" so pull your instructions from the db here
    }
}

这样的东西可以匹配一个方法,而无需将其明确定义为类方法,我认为是你的意图吗?

要对动态定义执行方法调用,请使用call_user_func或call_user_func_array

call_user_func( array($moduleInstance, 'hook'.$hook_name) , $hook_args );

至于你要求执行从hook开始的所有方法,我建议如下:

class MyModule
{
    /* ... */
    public function executeHooks()
    {
        $methods = get_class_methods($this);
        foreach ($methods as $method) {
            if (substr($method, 0, 4) == 'hook') {
                // Method is a hook
                call_user_func( array($this, $method) );
            }
        }
    }
    /* ... */
}