REST HTTP谓词的PHP __call方法


PHP __call method for REST HTTP Verbs

我正在编写一个REST包装类,它看起来像:

class RestApi
{
      public function __call($method, $resource, $data = []){
           return $this->call($method, $resource, $data);
      }
      public function call($http_verb, $resource, $data = []){}
}

但当我尝试运行以下。。。

$ra = new RestApi();
$ra->post('api/book/index');

它抛出以下错误。。。

RestApi::__call()必须正好接受2个参数

我想消除重复代码,所以我决定对所有四个http动词使用__call魔术方法。请建议一种方法。谢谢

如错误消息所示,__call魔术方法只接受两个参数:请求的方法的名称和传递的参数的数组。所有这些信息都可以在这里找到。

考虑到这一点,也许可以修改你的代码,使其看起来更像这样:

public function __call($method, $arguments) {
    return $this->call($method, $arguments[0], $arguments[1]);
}

假设您使用CURL实现了实际的API请求(这可能是一个很大的假设),那么您可以在call()方法中执行类似的操作:

switch (strtoupper($http_verb)) {
    case 'GET':
        // Nothing special happens here, this is CURL's default behavior
        break;
    case 'POST':
        curl_setopt($ch, CURLOPT_POST, true);
        break;
    case 'PUT':
        curl_setopt($ch, CURLOPT_PUT, true);
        break;
    // Etc...
}

这纯粹是一个示例,用于演示可以使用__call()魔术方法进行的条件逻辑。有很多库和框架可以创建REST包装器,就像你正在尝试做的那样。我建议把其中一个看作是一种学习体验,或者研究像Guzzle这样的库。

注意:当然,对于可选的第二个参数(如上面所述),明智的做法是在盲目传递之前先检查$arguments[1]等是否存在。否则你会得到类似PHP Notice: Undefined offset: 1的东西。

更新

关于我的最后一段,@JayTaph有一个很好的建议。一个简洁的方法(一行,无需额外检查)是使用以下内容:

public function __call($method, $arguments) {
    return this->call($method, array_shift($arguments), $arguments);
}

如果只传递一个参数,那么在第一个元素被array_shift()移位后,$arguments将是一个空数组,这避免了我上面提到的PHP Notice: Undefined offset错误。