You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何无需自定义类修改Laravel Http客户端PendingRequest的请求负载?

解决Laravel Http客户端请求负载转XML的问题

你的思路方向是对的——利用PendingRequest的宏和beforeSending钩子来处理数据转换,但问题出在你修改的是$options的副本,而非实际要发送的请求内容。Laravel的beforeSending回调中,$options是按值传递的,所以你在回调里修改它不会影响原请求。不过不用自定义PendingRequest子类,我们可以直接操作Request实例来修改负载。

修正后的实现代码

这里是调整后的宏定义,能正确将数组负载转换为XML字符串:

use Illuminate\Http\Client\PendingRequest;
use Illuminate\Http\Client\Request;
// 假设你用的是Spatie的ArrayToXml,根据实际情况调整引入类
use Spatie\ArrayToXml\ArrayToXml;

public function registerRequestMacros(): void
{
    $rootElement = 'request';

    PendingRequest::macro('acceptXml', function () {
        return $this->accept('application/xml');
    });

    PendingRequest::macro('convertDataToXml', function () use ($rootElement) {
        $this->beforeSending(function (Request $request) use ($rootElement) {
            $body = $request->body();
            
            // 仅当body是数组时才转换为XML
            if (is_array($body) && !empty($body)) {
                // 转换数组为XML字符串
                $xmlContent = ArrayToXml::convert($body, $rootElement);
                
                // 直接修改请求的body内容
                $request->setBody($xmlContent);
                // 确保Content-Type头与内容匹配
                $request->headers->set('Content-Type', 'application/xml');
            }
        });
    });

    PendingRequest::macro('asXml', function () {
        $this->convertDataToXml();
        // 使用raw格式,让客户端直接发送XML字符串
        return $this->bodyFormat('raw')->acceptXml();
    });
}

关键修改点说明

  1. 直接操作Request实例:
    放弃修改$options,转而通过$request->body()获取当前请求的负载,转换后用$request->setBody()覆盖原内容,这样修改会直接作用于即将发送的请求。

  2. 调整bodyFormat为raw:
    调用asXml()时设置bodyFormat('raw'),是因为我们最终要发送的是XML字符串,而非Laravel默认的表单或JSON格式。这个设置告诉Http客户端直接将字符串作为请求体发送,不需要额外编码。

  3. 确保请求头一致性:
    在转换后显式设置Content-Type为application/xml,避免头信息和实际内容不匹配导致的接口解析错误。

使用示例

现在你可以像这样发送XML格式的请求:

$response = Http::asXml()->post('https://your-api-endpoint.com', [
    'user' => [
        'name' => 'John Doe',
        'email' => 'john@example.com'
    ]
]);

这个请求会自动将数组转换为以<request>为根节点的XML字符串,并带上正确的请求头。

内容的提问来源于stack exchange,提问作者Mark

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 20:47:37