
本文详解如何在 cURL POST 请求中正确将 PHP 变量(如 $_GET['tracknumber'])注入 JSON 数据,避免字符串拼接错误与 XSS 风险,推荐使用 json_encode() 构建结构化请求体。
本文详解如何在 curl post 请求中正确将 php 变量(如 `$_get['tracknumber']`)注入 json 数据,避免字符串拼接错误与 xss 风险,推荐使用 `json_encode()` 构建结构化请求体。
在 PHP 中向外部 API(如 UPS Label Recovery 接口)发送 JSON 格式的 POST 请求时,常见误区是试图在 JSON 字符串中直接拼接 PHP 变量或误用 echo,例如:
"TrackingNumber": "echo json_encode($nam);"
这不仅语法错误(echo 是语句,不能出现在字符串内),更会导致 JSON 格式破坏、变量未解析,甚至引发严重安全漏洞(如 JSON 注入或 XSS)。
✅ 正确做法是:完全避免手动拼接 JSON 字符串,改用 PHP 原生数组 + json_encode() 自动序列化。它能自动处理引号转义、特殊字符(如空格、斜杠、Unicode)、布尔值与 null,确保输出严格符合 RFC 8259 标准。
以下是重构后的专业写法(含关键安全增强):
立即学习“PHP免费学习笔记(深入)”;
<?php
// ✅ 1. 安全获取并过滤输入(防止恶意跟踪号)
$trackNumber = filter_input(INPUT_GET, 'tracknumber', FILTER_SANITIZE_STRING);
if (!$trackNumber || strlen(trim($trackNumber)) === 0) {
die('Error: Missing or invalid tracknumber.');
}
// ✅ 2. 构建嵌套关联数组(逻辑清晰、易维护)
$data = [
'LabelRecoveryRequest' => [
'LabelSpecification' => [
'HTTPUserAgent' => '',
'LabelImageFormat' => ['Code' => 'GIF'],
],
'LabelDelivery' => [
'LabelLinkIndicator' => '',
'ResendEMailIndicator' => '',
'EMailMessage' => ['EMailAddress' => ''],
],
'TrackingNumber' => $trackNumber, // 直接赋值,无需引号包裹
]
];
// ✅ 3. 序列化为标准JSON(自动转义、UTF-8安全)
$jsonPayload = json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
if ($jsonPayload === false) {
die('JSON encode error: ' . json_last_error_msg());
}
// ✅ 4. 配置cURL(使用数组语法更简洁)
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => 'https://onlinetools.ups.com/ship/v1/shipments/labels',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30, // 建议设置合理超时
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => $jsonPayload,
CURLOPT_HTTPHEADER => [
'Username: xxxxx',
'Password: xxxxx',
'AccessLicenseNumber: xxxxxxx',
'Content-Type: application/json',
'Accept: application/json'
],
]);
$response = curl_exec($curl);
$httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
curl_close($curl);
// ✅ 5. 健壮性处理响应
if ($response === false || $httpCode !== 200) {
error_log("UPS API Error (HTTP {$httpCode}): " . curl_error($curl));
die('Failed to retrieve label.');
}
// 解析Base64图像(建议改用JSON解码而非正则,更可靠)
$result = json_decode($response, true);
if (json_last_error() !== JSON_ERROR_NONE || !isset($result['LabelRecoveryResponse']['LabelImage']['GraphicImage'])) {
die('Invalid API response format.');
}
$base64Image = $result['LabelRecoveryResponse']['LabelImage']['GraphicImage'];
echo "@@##@@";? 关键注意事项:
- 绝不手动拼接 JSON:"key": "$var" 或 "key": "echo $var" 均非法,会破坏 JSON 结构;
- 始终验证输入:$_GET 参数必须过滤(filter_input)和校验,防止空值、SQL/JSON 注入;
- 启用 JSON 错误检查:json_encode() 失败时返回 false,需用 json_last_error_msg() 排查;
- 设置超时与 HTTP 状态码检查:避免无限等待或静默失败;
- 优先解析 JSON 响应:用 json_decode() 替代正则匹配,提升可读性与健壮性;
- 敏感凭证保护:API 凭据(Username/Password/AccessLicense)应从环境变量或配置文件加载,禁止硬编码。
通过以上方式,你不仅能解决变量无法注入的问题,更能构建出安全、可维护、符合现代 PHP 最佳实践的 API 集成代码。











