使用Square Connect API和PHP上传项目图像

问题描述 投票:2回答:4

我已经回顾了Stackoverflow上发布的有关此问题的旧问题。但我没有找到任何php集成的例子。

以下是我的代码示例,但它失败了

    $url = 'https://connect.squareup.com/v1/me/items/9999999/image';
    $auth_bearer = 'Authorization: Bearer ' . $this->accessToken;
    $image_data = base64_encode(file_get_contents('image.jpeg'));
    $header = array(
        $auth_bearer,
        'Accept: application/json',
        'Content-Type: multipart/form-data; boundary=BOUNDARY',

    );

    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
    curl_setopt($ch, CURLOPT_POSTFIELDS, 'files=' . $image_data);
    $head = curl_exec($ch);
    curl_close($ch);

    $response = json_decode($head);
    echo "<pre>";
    print_r($response);
    echo "</pre>";

什么都没发生......这里有什么帮助?

谢谢

php square-connect
4个回答
2
投票

您需要使用适当的multipart标头发布原始图像数据(不是base64编码)作为文件对象。这是一个工作示例(替换ACCESS_TOKENITEM_IDIMAGE_FILE)。

<?php
function uploadItemImage($url, $access_token, $image_file) {
    $headers = ["Authorization: Bearer $access_token"];

    $ch = curl_init();

    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, ['image_data' => "@$image_file"]);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

    $data = curl_exec($ch);
    $return_status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    print "POST to $url with status $return_status\n";

    curl_close($ch);

    return $data ? json_decode($data) : false;
}

print_r(
    uploadItemImage(
        'https://connect.squareup.com/v1/me/items/ITEM_ID/image',
        'ACCESS_TOKEN',
        'IMAGE_FILE.jpg'
    )
);
?>

0
投票

这是我用于上传PNG图像的PHP实现。有时,不同的代码视图有帮助。

正如@Troy所说,包含图像的重要领域是“内容类型:多部分/表单数据”。我上传到Square的其他所有内容都使用'Content-Type:application / json'。

$square_url = 'https://connect.squareup.com/v1/me/items/' . $square_item_id . '/image';

$cfile = new CURLFile($image_path_on_server, 'image/png', 'image_data');
$image_data = array('image_data' => $cfile);

$curl = curl_init();
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
  'Authorization: Bearer ' . $access_token,
  'Content-Type: multipart/form-data',
  'Accept: application/json'
));
curl_setopt($curl, CURLOPT_POSTFIELDS, $image_data);
curl_setopt($curl, CURLOPT_URL, $square_url);
curl_setopt($curl, CURLOPT_POST, TRUE);
curl_setopt($curl, CURLOPT_SAFE_UPLOAD, TRUE);
curl_setopt($curl, CURLOPT_BINARYTRANSFER, TRUE);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($curl, CURLINFO_HEADER_OUT, TRUE);
curl_setopt($curl, CURLOPT_VERBOSE, TRUE);
$json = curl_exec($curl);
curl_close($curl);

0
投票

严格来说,Square API文档可以实现其方法,并记住一些事项。

- 您的请求必须包含在边界内,并包含内容处置,名称,文件名,内容类型,如下面的示例所示。

--BOUNDARY
Content-Disposition: form-data; name="image_data"; filename="MyImage.png"
Content-Type: image/png
                               {BLANK LINE IS REQUIRED}
IMAGE BINARY DATA GOES HERE
--BOUNDARY--

实质上,请求的格式必须与样本中指定的完全一致。这包括“边界”,换行符,必要的标题,标题之间的空白行(由于某些原因,如果行不存在则无效),以及实际的图像二进制数据。注意:边界可以是您选择的任何字符串,但必须始终如一地使用。在代码中,这看起来像这样:

$boundary = "---------------------" . md5(mt_rand() . microtime());
$imageToUpload = "--{$boundary}" . "\r\n" .
             "Content-Disposition: form-data; name=\"image_data\"; filename=\"" . $full_path_to_image_file . "\"" . "\r\n" .
             "Content-Type: image/jpeg" . "\r\n" .
             "\r\n" . // <- empty line is required
             (file_get_contents($full_path_to_image_file)) . "\r\n" .
             "--{$boundary}--";

以上将产生如下所示的请求:

-----------------------51b62743876b1201aee47ff4b1910e49
Content-Disposition: form-data; name="image_data"; filename="/some/directory/image.jpg"
Content-Type: image/jpeg

����
-----------------------51b62743876b1201aee47ff4b1910e49--

- 从技术上讲,请求中的内容类型必须根据您上传的图像类型(image / jpeg或image / png)进行更改。您可以将内容类型设置为application / octet-stream以涵盖所有基础。

-----------------------51b62743876b1201aee47ff4b1910e49
Content-Disposition: form-data; name="image_data"; filename="/some/directory/image.jpg"
Content-Type: application/octet-stream

����
-----------------------51b62743876b1201aee47ff4b1910e49--

上面的两个示例将上传图像。

- “图像二进制数据”可能会产生误导,因为我的每次搜索都显示使用base64_encode函数获得图像二进制。在我的实验中,base64_encoding没有做任何事情。您只需要使用file_get_contents打开该文件。

- 在cURL请求中,必须将标头的Content-Type设置为multipart / form-data,并且边界与请求相同。示例如下:

curl_setopt($curl, CURLOPT_HTTPHEADER, array('Authorization: Bearer ' . $personalAccessToken, 'Content-Type: multipart/form-data; boundary=' . $boundary ));

因此,这为混合添加了另一种解决方案。


0
投票

使用@的Troy解决方案已被弃用,我无法让它工作。 Byron的解决方案适用于CURLOPT_POSTFIELDS之前的CURLOPT_POST(请参阅https://www.php.net/manual/en/function.curl-setopt.php上的Mavooks评论)并从标题中删除Content-Type。那是因为如果CURLOPTS_POSTFIELDS是一个数组并且手动包含它似乎覆盖它,它会自动成为多部分,但是它会丢失边界。

$square_url = 'https://connect.squareup.com/v1/me/items/' . $square_item_id . '/image';

$cfile = new CURLFile($image_path_on_server, 'image/png', 'image_data');
$image_data = array('image_data' => $cfile);

$curl = curl_init();
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
  'Authorization: Bearer ' . $access_token,
  'Accept: application/json'
));
curl_setopt($curl, CURLOPT_POST, TRUE);
curl_setopt($curl, CURLOPT_POSTFIELDS, $image_data);
curl_setopt($curl, CURLOPT_URL, $square_url);
curl_setopt($curl, CURLOPT_SAFE_UPLOAD, TRUE);
curl_setopt($curl, CURLOPT_BINARYTRANSFER, TRUE);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($curl, CURLINFO_HEADER_OUT, TRUE);
curl_setopt($curl, CURLOPT_VERBOSE, TRUE);
$json = curl_exec($curl);
curl_close($curl);
© www.soinside.com 2019 - 2024. All rights reserved.