How to receive a file in PHP and send it to another API as a file?

时间:2015-07-28 22:11:44

标签: javascript php api

I have two different APIs for my website. One is the main API which does all the processing, saving and validation. The other is just a proxy to my main API to get around cross domain errors.

I am trying to post an image as a file to my proxy domain and then pass that same image as a file again to my main API.

Here is my Javascript calling my API

function saveImage () {
    //Getting my image as base64. Works perfectly since I can log it and view it in a new window
    var imageEncoded = postImgUpload.getImageDataURl();

    var resourceApiData = {
        type: 1,
        content: imageEncoded
    };

    apiService.createNewResource(resourceApiData);
}

//My function inside 'apiService'
createNewResource: function(apiData) {
    var image = new Image();
    image.src = "data:image/png;base64," + apiData.content;

    var formData = new FormData();
    formData.append("type", apiData.type);
    formData.append("content", image);

    var apiRequest = postApiRoot + "createNewResource";

    return $http({
        method: 'POST',
        url: apiRequest,
        data: apiData,
        headers: {'Content-Type': 'application/x-www-form-urlencoded'},
        responseType: 'json'
    });
},

Here is my PHP processing the passed up data and sending it to my main API

private function createNewResource() {
    $content = $_FILES['content']['tmp_name'];
    $type = "image";

    $data = array(
      'type' => $type,
      'content' => $content
    );

    $this->runApiCall($url, true, "POST", $data, false);
}

The runApiCall method definitely works since I am currently using it for all other API calls on my site. This is the only one that is giving me a 422 Unprocessable Entity response from my main API.

If I go into POSTman and post my image as a file directly to my main API, it works with no problem at all.

enter image description here


EDIT

Here is my runApiCall method:

private function runApiCall($url, $returnTransfer, $method, $postData, $header) {
    $url = "example.org/" . $url;

    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, $returnTransfer);
    curl_setopt($ch, CURLOPT_HEADER, $header);
    if($method === 'POST') {
        curl_setopt($ch, CURLOPT_POST, 1);
    }
    if($method === "DELETE") {
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "DELETE");
    }
    if($method === "PUT") {
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
        curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/x-www-form-urlencoded'));
    }
    if($postData !== "") {
        if($method === "PUT") {
            curl_setopt($ch, CURLOPT_POSTFIELDS,http_build_query($postData));
        } else {
            curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
        }
    }

    curl_setopt($ch, CURLOPT_COOKIE, 'PHPSESSID=' . $_COOKIE['nxsession']);
    session_write_close();
    $result = curl_exec($ch);
    $status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    $this->response($result, $status);
}

2 个答案:

答案 0 :(得分:0)

If both API's have access to the same file system, you could have the first API save the file on the file system and then just pass along the full path to the file to the second API.

答案 1 :(得分:0)

Depends how did you implemented runApiCall, but it needs to append whole data but you are passing just temporally path to file uploaded to the server.

Look at: http://php.net/manual/en/class.httprequest.php and http://php.net/manual/en/httprequest.addpostfile.php

Update (reaction to posted curl implementation)

Ok, you are using curl, so it should be easy. Just perpend "@" before actual path. See https://coderwall.com/p/fck2ta/how-to-send-files-via-curl-in-php.

Update (added edited code)

private function createNewResource() {
    $content = "@".$_FILES['content']['tmp_name'];
    $type = "image";

    $data = array(
      'type' => $type,
      'content' => $content
    );

    $this->runApiCall($url, true, "POST", $data, false);
}