【问题标题】:Upload item image using Square Connect API and PHP使用 Square Connect API 和 PHP 上传商品图片
【发布时间】:2015-07-23 02:15:00
【问题描述】:

我已经查看了 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


    【解决方案1】:

    您需要使用文件对象的正确多部分标头发布原始图像数据(未经过 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'
        )
    );
    ?>
    

    【讨论】:

    • 谢谢@Troy .. 它工作得很好......非常感谢......我认为他们必须把这个例子放到文档中
    • 很遗憾,我们目前没有针对不同语言的代码示例,但我总是乐于提供帮助。我实际上有这个方便,因为人们由于某种原因往往在上传图片时遇到问题。
    • @Troy 你有 JavaScript 示例吗? (不是 Node.js)
    【解决方案2】:

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

    正如@Troy 所说,包含在图像中的重要字段是“Content-Type: multipart/form-data”。我上传到 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);
    

    【讨论】:

      【解决方案3】:

      严格来说 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--
      

      -- 从技术上讲,请求中的 Content-Type 必须随着您上传的图像类型(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 ));
      

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

      【讨论】:

        【解决方案4】:

        Troy 使用 @ 的解决方案已被弃用,我无法让它工作。 Byron 的解决方案使用 CURLOPT_POST before CURLOPT_POSTFIELDS(请参阅 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);
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-10-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多