如何使用 Guzzle PHP 获取 SENT 数据的主体?
How do I get the body of SENT data with Guzzle PHP?
我在 PHP 中使用 Guzzle (v6.1.1) 向服务器发出 POST 请求。它工作正常。我正在添加一些日志记录功能来记录发送和接收的内容,但我不知道如何获取 Guzzle 发送到服务器的数据。我可以很好地获得响应,但是如何获得 sent 数据? (这将是 JSON 字符串。)
这是我的代码的相关部分:
$client = new GuzzleHttp\Client(['base_uri' => $serviceUrlPayments ]);
try {
$response = $client->request('POST', 'Charge', [
'auth' => [$securenetId, $secureKey],
'json' => [ "amount" => $amount,
"paymentVaultToken" => array(
"customerId" => $customerId,
"paymentMethodId" => $token,
"publicKey" => $publicKey
),
"extendedInformation" => array(
"typeOfGoods" => $typeOfGoods,
"userDefinedFields" => $udfs,
"notes" => $Notes
),
'developerApplication'=> $developerApplication
]
]);
} catch (ServerErrorResponseException $e) {
echo (string) $e->getResponse()->getBody();
}
echo $response->getBody(); // THIS CORRECTLY SHOWS THE SERVER RESPONSE
echo $client->getBody(); // This doesn't work
echo $client->request->getBody(); // nor does this
如有任何帮助,我们将不胜感激。我确实尝试在 Guzzle 源代码中查找类似于 getBody() 的函数,它可以处理请求,但我不是 PHP 专家,所以我没有想出任何有用的东西。我还搜索了很多 Google,但发现只有人们在谈论从服务器返回响应,我对此没有遇到任何问题。
您可以通过创建 Middleware 来完成这项工作。
use GuzzleHttp\Client;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Middleware;
use Psr\Http\Message\RequestInterface;
$stack = HandlerStack::create();
// my middleware
$stack->push(Middleware::mapRequest(function (RequestInterface $request) {
$contentsRequest = (string) $request->getBody();
//var_dump($contentsRequest);
return $request;
}));
$client = new Client([
'base_uri' => 'http://www.example.com/api/',
'handler' => $stack
]);
$response = $client->request('POST', 'itemupdate', [
'auth' => [$username, $password],
'json' => [
"key" => "value",
"key2" => "value",
]
]);
然而,这是在收到响应之前触发的。你可能想做这样的事情:
$stack->push(function (callable $handler) {
return function (RequestInterface $request, array $options) use ($handler) {
return $handler($request, $options)->then(
function ($response) use ($request) {
// work here
$contentsRequest = (string) $request->getBody();
//var_dump($contentsRequest);
return $response;
}
);
};
});
您可以通过执行
来重现请求创建的数据字符串
$data = array(
"key" => "value",
"key2" => "value",
);
$response = $client->request('POST', 'itemupdate', [
'auth' => [$username, $password],
'json' => $data,
]);
// ...
echo json_encode($data);
这会将您的数据输出为 JSON 字符串。
文档位于 http://php.net/manual/fr/function.json-encode.php
编辑
Guzzle 有一个 Request
和一个 Response
class(以及许多其他)。
Request
有一个有效的 getQuery()
方法,returns 一个包含你的 data
的对象是私有的,与所有其他成员一样。
也无法访问。
这就是为什么我认为手动编码是更简单的解决方案。
如果您想知道 Guzzle 做了什么,它还有一个 Collection
class 可以转换数据并在请求中发送它。
使用 Guzzle 6.2。
过去几天我也一直在努力解决这个问题,同时尝试构建一种方法来审计与不同 API 的 HTTP 交互。在我的案例中,解决方案是简单地倒回请求正文。
请求的主体实际上是作为 stream 实现的。因此,当发送请求时,Guzzle 从流中读取。读取完整的流会将流的内部指针移动到末尾。因此,当您在发出请求后调用 getContents()
时,内部指针已经位于流的末尾,而 returns 什么也没有。
解决办法?将指针倒回开头并再次读取流。
<?php
// ...
$body = $request->getBody();
echo $body->getContents(); // -->nothing
// Rewind the stream
$body->rewind();
echo $body->getContents(); // -->The request body :)
我对 Laravel 的解决方案来自 5.7:
MessageFormatter 使用变量替换,请参阅:https://github.com/guzzle/guzzle/blob/master/src/MessageFormatter.php
$stack = HandlerStack::create();
$stack->push(
Middleware::log(
Log::channel('single'),
new MessageFormatter('Req Body: {request}')
)
);
$client = new Client();
$response = $client->request(
'POST',
'https://url.com/go',
[
'headers' => [
"Content-Type" => "application/json",
'Authorization' => 'Bearer 123'
],
'json' => $menu,
'handler' => $stack
]
);
我在 PHP 中使用 Guzzle (v6.1.1) 向服务器发出 POST 请求。它工作正常。我正在添加一些日志记录功能来记录发送和接收的内容,但我不知道如何获取 Guzzle 发送到服务器的数据。我可以很好地获得响应,但是如何获得 sent 数据? (这将是 JSON 字符串。)
这是我的代码的相关部分:
$client = new GuzzleHttp\Client(['base_uri' => $serviceUrlPayments ]);
try {
$response = $client->request('POST', 'Charge', [
'auth' => [$securenetId, $secureKey],
'json' => [ "amount" => $amount,
"paymentVaultToken" => array(
"customerId" => $customerId,
"paymentMethodId" => $token,
"publicKey" => $publicKey
),
"extendedInformation" => array(
"typeOfGoods" => $typeOfGoods,
"userDefinedFields" => $udfs,
"notes" => $Notes
),
'developerApplication'=> $developerApplication
]
]);
} catch (ServerErrorResponseException $e) {
echo (string) $e->getResponse()->getBody();
}
echo $response->getBody(); // THIS CORRECTLY SHOWS THE SERVER RESPONSE
echo $client->getBody(); // This doesn't work
echo $client->request->getBody(); // nor does this
如有任何帮助,我们将不胜感激。我确实尝试在 Guzzle 源代码中查找类似于 getBody() 的函数,它可以处理请求,但我不是 PHP 专家,所以我没有想出任何有用的东西。我还搜索了很多 Google,但发现只有人们在谈论从服务器返回响应,我对此没有遇到任何问题。
您可以通过创建 Middleware 来完成这项工作。
use GuzzleHttp\Client;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Middleware;
use Psr\Http\Message\RequestInterface;
$stack = HandlerStack::create();
// my middleware
$stack->push(Middleware::mapRequest(function (RequestInterface $request) {
$contentsRequest = (string) $request->getBody();
//var_dump($contentsRequest);
return $request;
}));
$client = new Client([
'base_uri' => 'http://www.example.com/api/',
'handler' => $stack
]);
$response = $client->request('POST', 'itemupdate', [
'auth' => [$username, $password],
'json' => [
"key" => "value",
"key2" => "value",
]
]);
然而,这是在收到响应之前触发的。你可能想做这样的事情:
$stack->push(function (callable $handler) {
return function (RequestInterface $request, array $options) use ($handler) {
return $handler($request, $options)->then(
function ($response) use ($request) {
// work here
$contentsRequest = (string) $request->getBody();
//var_dump($contentsRequest);
return $response;
}
);
};
});
您可以通过执行
来重现请求创建的数据字符串$data = array(
"key" => "value",
"key2" => "value",
);
$response = $client->request('POST', 'itemupdate', [
'auth' => [$username, $password],
'json' => $data,
]);
// ...
echo json_encode($data);
这会将您的数据输出为 JSON 字符串。
文档位于 http://php.net/manual/fr/function.json-encode.php
编辑
Guzzle 有一个 Request
和一个 Response
class(以及许多其他)。
Request
有一个有效的 getQuery()
方法,returns 一个包含你的 data
的对象是私有的,与所有其他成员一样。
也无法访问。
这就是为什么我认为手动编码是更简单的解决方案。
如果您想知道 Guzzle 做了什么,它还有一个 Collection
class 可以转换数据并在请求中发送它。
使用 Guzzle 6.2。
过去几天我也一直在努力解决这个问题,同时尝试构建一种方法来审计与不同 API 的 HTTP 交互。在我的案例中,解决方案是简单地倒回请求正文。
请求的主体实际上是作为 stream 实现的。因此,当发送请求时,Guzzle 从流中读取。读取完整的流会将流的内部指针移动到末尾。因此,当您在发出请求后调用 getContents()
时,内部指针已经位于流的末尾,而 returns 什么也没有。
解决办法?将指针倒回开头并再次读取流。
<?php
// ...
$body = $request->getBody();
echo $body->getContents(); // -->nothing
// Rewind the stream
$body->rewind();
echo $body->getContents(); // -->The request body :)
我对 Laravel 的解决方案来自 5.7:
MessageFormatter 使用变量替换,请参阅:https://github.com/guzzle/guzzle/blob/master/src/MessageFormatter.php
$stack = HandlerStack::create();
$stack->push(
Middleware::log(
Log::channel('single'),
new MessageFormatter('Req Body: {request}')
)
);
$client = new Client();
$response = $client->request(
'POST',
'https://url.com/go',
[
'headers' => [
"Content-Type" => "application/json",
'Authorization' => 'Bearer 123'
],
'json' => $menu,
'handler' => $stack
]
);