
本文旨在解决通过wordpress rest api (v2) 上传原始图片数据时,图片在媒体库中显示空白的问题。核心在于理解api对二进制数据上传的要求,即需将图片原始数据作为请求体直接发送,并正确设置`content-disposition`等http头部。教程将详细阐述使用curl和guzzle发送二进制数据的正确方法,确保图片能够被wordpress正确识别和存储。
在开发过程中,我们经常需要将图片直接从内存中的原始数据(例如Base64编码或二进制流)上传到WordPress媒体库,而非通过文件路径或URL。然而,如果不正确处理HTTP请求,上传的图片可能会在WordPress媒体库中显示为“空白”或损坏。本文将详细介绍如何正确地通过WordPress REST API (v2) 上传原始图片数据,并提供基于cURL和Guzzle的解决方案。
最初的尝试通常会遇到以下问题:
这些问题通常源于对WordPress REST API媒体上传机制的误解。WordPress期望接收的是图片的原始二进制数据作为HTTP请求体,并依赖特定的HTTP头部来识别文件类型和名称。将原始数据作为source_url或form_params的一部分发送是错误的,因为source_url用于外部URL引用,而form_params通常用于发送键值对数据(如application/x-www-form-urlencoded或multipart/form-data),而不是原始二进制流。
正确的做法是将图片原始数据直接作为HTTP请求体发送,并设置相应的Content-Disposition头部。以下是使用PHP cURL库实现此功能的详细步骤:
示例代码 (cURL):
<?php
// 假设 $data 包含 Base64 编码的图片数据
// 假设 $image_name 包含图片文件名,例如 'my_image.jpg'
// 假设 $result_auth->access_token 包含你的 Bearer token
// 假设 $url 是你的 WordPress 站点 URL
function uploadImageWithCurl($data, $image_name, $access_token, $wp_site_url) {
// 1. 创建临时文件路径
$filepath = sys_get_temp_dir() . '/' . uniqid() . '_' . $image_name;
// 2. 将 Base64 解码后的数据写入临时文件
// 注意:如果 $data 已经是原始二进制数据,则不需要 base64_decode
file_put_contents($filepath, base64_decode($data));
// 3. 确保临时文件存在
if (!file_exists($filepath)) {
error_log("Failed to create temporary image file: " . $filepath);
return null;
}
// 4. 读取文件内容作为POST数据
$file_content = file_get_contents($filepath);
// 5. 初始化 cURL
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 返回响应内容
curl_setopt($ch, CURLOPT_URL, $wp_site_url . '/wp-json/wp/v2/media/'); // API 端点
curl_setopt($ch, CURLOPT_POST, 1); // 设置为POST请求
curl_setopt($ch, CURLOPT_POSTFIELDS, $file_content); // 直接发送文件内容作为请求体
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Content-Disposition: attachment; filename=\"" . basename($image_name) . "\"", // 关键头部:指定文件名
"Content-Type: " . mime_content_type($filepath), // 根据文件类型设置MIME Type
'Authorization: Bearer ' . $access_token, // 认证头部
]);
// 6. 执行 cURL 请求
$result = curl_exec($ch);
// 7. 检查错误
if (curl_errno($ch)) {
error_log('cURL Error: ' . curl_error($ch));
curl_close($ch);
unlink($filepath); // 清理临时文件
return null;
}
// 8. 关闭 cURL 句柄并清理临时文件
curl_close($ch);
unlink($filepath); // 清理临时文件
// 9. 解码 API 响应
$api_response = json_decode($result);
return $api_response;
}
// 示例调用
// $product_image_data = $product['priority_web_image']['data']; // 假设这是 Base64 数据
// $product_image_name = $product['priority_web_image']['filename']; // 假设这是文件名
// $auth_token = $result_auth->access_token;
// $wordpress_url = 'https://your-wordpress-site.com';
// $upload_result = uploadImageWithCurl($product_image_data, $product_image_name, $auth_token, $wordpress_url);
// if ($upload_result && isset($upload_result->id)) {
// echo "图片上传成功,ID: " . $upload_result->id;
// } else {
// echo "图片上传失败。";
// print_r($upload_result);
// }
?>如果你使用Guzzle这样的HTTP客户端库,也可以实现类似的功能,且通常代码更简洁。关键在于使用Guzzle的body选项来发送原始数据,而不是form_params。
示例代码 (Guzzle):
<?php
use GuzzleHttp\Client;
use GuzzleHttp\Psr7\Utils;
// 假设 $data 包含 Base64 编码的图片数据
// 假设 $image_name 包含图片文件名,例如 'my_image.jpg'
// 假设 $result_auth->access_token 包含你的 Bearer token
// 假设 $wp_api_client 是你的 Guzzle 客户端实例,配置了 base_uri 为你的 WordPress API 根路径
function uploadImageWithGuzzle($data, $image_name, $access_token, Client $wp_api_client) {
// 1. 确定 MIME 类型
$ext = pathinfo($image_name, PATHINFO_EXTENSION);
if (empty($ext)) {
// 尝试从数据判断或默认一个
$mime_type = 'application/octet-stream';
} else {
$ext = strtolower($ext);
$mime_type_map = [
'jpg' => 'image/jpeg',
'jpeg' => 'image/jpeg',
'png' => 'image/png',
'gif' => 'image/gif',
'webp' => 'image/webp',
];
$mime_type = $mime_type_map[$ext] ?? 'application/octet-stream';
}
// 2. 解码 Base64 数据,得到原始二进制流
// 注意:如果 $data 已经是原始二进制数据,则不需要 base64_decode
$binary_data = base64_decode($data);
// 3. 构建 Guzzle 请求选项
$options = [
'headers' => [
'Authorization' => 'Bearer ' . $access_token,
'Content-Type' => $mime_type, // 设置正确的MIME类型
'Content-Disposition' => 'attachment; filename="' . basename($image_name) . '"', // 关键头部
],
'body' => $binary_data, // 直接将二进制数据作为请求体
];
try {
// 4. 发送 POST 请求到 media 端点
$response = $wp_api_client->request('POST', 'media', $options);
// 5. 解码响应
$bodyAry = json_decode($response->getBody()->getContents());
return $bodyAry;
} catch (\GuzzleHttp\Exception\GuzzleException $e) {
error_log("Guzzle Error: " . $e->getMessage());
return null;
}
}
// 示例调用
// $guzzle_client = new Client([
// 'base_uri' => 'https://your-wordpress-site.com/wp-json/wp/v2/',
// 'timeout' => 30.0,
// ]);
// $product_image_data = $product['priority_web_image']['data']; // 假设这是 Base64 数据
// $product_image_name = $product['priority_web_image']['filename']; // 假设这是文件名
// $auth_token = $result_auth->access_token;
// $upload_result = uploadImageWithGuzzle($product_image_data, $product_image_name, $auth_token, $guzzle_client);
// if ($upload_result && isset($upload_result->id)) {
// echo "图片上传成功,ID: " . $upload_result->id;
// } else {
// echo "图片上传失败。";
// print_r($upload_result);
// }
?>通过WordPress REST API上传原始图片数据,核心在于理解API期望接收的是图片二进制数据作为请求体,并通过Content-Disposition和Content-Type等HTTP头部提供必要的元信息。无论是使用cURL还是Guzzle,遵循这些原则可以确保图片被正确上传并显示在WordPress媒体库中,从而避免图片显示空白的问题。始终记得进行充分的错误处理和资源清理,以构建健壮的集成方案。
以上就是WordPress REST API 上传原始图片数据并避免媒体库空白问题的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号