4

我正在使用 Zend\Http\Request 和 Zend\Http\Client 发出以下请求

        //Creating request and client objects
        $request = new Request();
        $client = new Client();

        //Preparing Request Object
        $request->setMethod('POST');
        $request->setUri('https://my.api.address.com/apiendpointurl1234');
        $request->getHeaders()->addHeaders(array(
            'cache-control' => 'no-cache',
            'content-type' => 'application/json',
            'client_secret' => 'asdfasdfasdfasdfasdf',
            'client_id' => 'asdfasdfasdfasdfasdf',
            'accept' => 'application/json',
            'authorization' => 'Basic MTIzNDoxMjM0',
        ));
        $request->getPost()->set(json_encode(array(
            'student_id' => '123456',
            'short_description' => 'this is short description',
            'description' => 'this is detailed description of the question',
        )));

        //Sending Request
        $response = $client->send($request);

        var_dump( $response->getBody() );

但是响应带有此错误:

“错误”:“标题:需要 client_id”

当我通过 Postman 戳 API 时,它工作正常。但是当我从 PHP 应用程序调用它时,结果表明没有正确发送标头,这导致了上述错误。任何人都会知道为什么没有发送标题?

4

6 回答 6

1

我敢打赌,您需要将 Headers 对象的引用存储在您之后的变量中getHeaders,操作该对象,然后用于setHeaders更新 Request 对象上的标头。

$headers = $request->getHeaders();
$headers->addHeaders([ ... ... ]);
$request->setHeaders($headers);
于 2017-01-24T15:49:27.753 回答
1

尝试不使用 addHeaders 方法

// Setting multiple headers, overwriting any previous value
$client->setHeaders(array(
    'Host' => 'www.example.com',
    'Accept-encoding' => 'gzip,deflate',
    'X-Powered-By' => 'Zend Framework'));

也许您对客户端和请求对象有些困惑。

   $client = new Zend_Http_Client('http://example.org');
      $client->setHeaders(array(
        'Host' => 'www.example.com',
        'Accept-encoding' => 'gzip,deflate',
        'X-Powered-By' => 'Zend Framework'));
    $response = $client->request();

例如,您可以在 firebug 中检查您的查询并检查在服务器中发送了哪些标头

于 2017-01-19T09:20:22.103 回答
1

如果你想使用Request对象,你有使用setRequestdispatch方法:

use Zend\Http\Client;
use Zend\Http\Request;

$request = new Request();
$request->setUri('https://my.api.address.com/apiendpointurl1234');

// Performing a POST request
$request->setMethod(Request::METHOD_POST);
$request->getHeaders()->addHeaders(array(
        'cache-control' => 'no-cache',
        'content-type' => 'application/json',
        'client_secret' => 'asdfasdfasdfasdfasdf',
        'client_id' => 'asdfasdfasdfasdfasdf',
        'accept' => 'application/json',
        'authorization' => 'Basic MTIzNDoxMjM0',
    ));

$client = new Client();

$client->setRequest($request);
$response = $client->dispatch();
于 2017-01-19T11:59:15.837 回答
1

这对我有用:

//Creating request and client objects
$request = new Request();
$client = new Client();

//Preparing Request Object
$request->setMethod('POST');
$request->setUri('https://my.api.address.com/apiendpointurl1234');
$request->getHeaders()->addHeaders(array(
    'cache-control' => 'no-cache',
    'content-type' => 'application/json',
    'client_secret' => 'asdfasdfasdfasdfasdf',
    'client_id' => 'asdfasdfasdfasdfasdf',
    'accept' => 'application/json',
    'authorization' => 'Basic MTIzNDoxMjM0'
));

$client->setOptions(['strictredirects' => true]);

$request->setContent(json_encode(array(
    'student_id' => '123456',
    'short_description' => 'this is short description',
    'description' => 'this is detailed description of the question',
)));

//Sending Request
$response = $client->send($request);

echo ($response->getBody());

我的假设是从您的 api 重定向到另一个 url 并且标头被重置。您可以在 Client.php 的第 943 行看到

$this->resetParameters(false, false);

叫做。这在 Postman 中不会发生,因为 Postman 为重定向重用了相同的标头。

实际上,您可以通过添加来测试它

$client->setOptions(['strictredirects' => true]);

应该允许在重定向之间保留标头

PS:我用最新的稳定版本的zend http尝试了上面的代码,它在“$request->getPost()->set”行抛出了一些错误。无论如何,这不是问题的根源。

编辑:我的第二个假设是“client_id”标头名称由 api 查询区分大小写,这会导致错误,因为请求是由 Zend\Http\Client 发送的,它使用“Zend\Http\Client\Adapter\Socket " 使每个标题的第一个字符大写(第 361 行)。所以“Client_id”是实际发送的。编辑 Zend\Http\Client\Adapter\Socket" 的第 361 行:

 $v = ucfirst($k) . ": $v";

  $v = $k . ": $v";

并测试是否收到了标头。

于 2017-01-24T09:47:43.960 回答
1

如果我没记错的话,自从我使用 Zend Framework for Requests 已经有一段时间了,但是该getHeaders方法返回 Headers 对象,因此您需要使用和设置。

所以你的代码

 $request->getHeaders()->addHeaders(array(
     'cache-control' => 'no-cache',
     'content-type' => 'application/json',
     'client_secret' => 'asdfasdfasdfasdfasdf',
     'client_id' => 'asdfasdfasdfasdfasdf',
     'accept' => 'application/json',
     'authorization' => 'Basic MTIzNDoxMjM0',
));

将需要成为

 $headers = $request->getHeaders();
 $headers->addHeaders(array(
     'cache-control' => 'no-cache',
     'content-type' => 'application/json',
     'client_secret' => 'asdfasdfasdfasdfasdf',
     'client_id' => 'asdfasdfasdfasdfasdf',
     'accept' => 'application/json',
     'authorization' => 'Basic MTIzNDoxMjM0',
 ));
 $request->setHeaders($headers);

正如其他答案之一所说:

在执行此操作之前,您需要将 URI 和方法设置为 Post,因为您将需要其他标头

$request->setUri('https://my.api.address.com/apiendpointurl1234');

// Performing a POST request
$request->setMethod(Request::METHOD_POST);

最后,您需要在执行此操作之前设置您的帖子数据,因为它会影响您的标题,因为在开始弄乱它们之前需要设置 Content-Length 标题

$request->setContent(json_encode(array(
    'student_id' => '123456',
    'short_description' => 'this is short description',
    'description' => 'this is detailed description of the question',
)));

所以你的脚本应该是

//Creating request and client objects
$request = new Request();
$client = new Client();
$request->setUri('https://my.api.address.com/apiendpointurl1234');

// Performing a POST request
$request->setMethod(Request::METHOD_POST);
$client->setOptions(['strictredirects' => true]);

$request->setContent(json_encode(array(
    'student_id' => '123456',
    'short_description' => 'this is short description',
    'description' => 'this is detailed description of the question',
)));
$headers = $request->getHeaders();
$headers->addHeaders(array(
    'cache-control' => 'no-cache',
    'content-type' => 'application/json',
    'client_secret' => 'asdfasdfasdfasdfasdf',
    'client_id' => 'asdfasdfasdfasdfasdf',
    'accept' => 'application/json',
    'authorization' => 'Basic MTIzNDoxMjM0',
));
$request->setHeaders($headers);
于 2017-01-25T14:07:52.117 回答
0

Turns out that Zend\Http\Request and Zend\Http\Client libraries converts underscores to hyphen (-) at the time of making the call. However, cURL behaves a bit differently. Still if you supply headers array in key value format, you won't be able to make the call as cURL will convert client-id to client-id. However, if you supply an standard array of values only by concatenating the headers, the call is successful. So here is my replacement code that worked:

    // Get cURL resource
    $curl = curl_init();
    // Set some options - we are passing in a useragent too here
    curl_setopt_array($curl, [
        CURLOPT_RETURNTRANSFER => 1,
        CURLOPT_URL => 'https://my.api.address.com/apiendpointurl1234',
        CURLOPT_POST => 1,
        CURLOPT_HTTPHEADER => [
            'client_id: ' . 'asdfasdfasdfasdf',
            'client_secret: ' . 'asdfasdfasdfasdfasdf',
            'Authorization: ' . 'Basic MTIzNDoxMjM0',
            'Content-Type: ' . 'application/json',
        ],
        CURLOPT_POSTFIELDS => [
            'student_id' => '111',
            'short_description' => 'this is the short description',
            'description' => 'this is the long description this is the long description this is the long description'
        ],
    ]);
    // Send the request & save response to $resp
    $response = curl_exec($curl);
    var_dump("Service call id is: " . $response);
    // Close request to clear up some resources
    curl_close($curl);

Hope that helps.

于 2017-01-30T02:54:29.383 回答