Reputation: 6696
I am building a mobile site that runs from an API and have an API CALL handler class which does all the calls which I run from a primary functions file.
The issue here is my files are not being sent through to the API and it's not recognising what is a file and is returning a file not present error.
NOTE: ISSUE SOLVED AND WORKING CODE BELOW
Code Below:
FORM
<form id="uploadPhoto" action="<?php uploadStreamPhoto(); ?>" method="post" enctype="multipart/form-data">
<input type="file" name="streamPhotoUpload" id="streamPhotoUpload" />
<input type="submit" name="streamPhotoUploadSubmit" id="streamPhotoUploadSubmit" value="Upload" />
</form>
UPLOAD FUNCTION
function uploadStreamPhoto()
{
if(isset($_POST['streamPhotoUploadSubmit']))
{
$apiHandler = new APIHandler();
$result = $apiHandler->uploadStreamPhoto($_FILES['streamPhotoUpload']['tmp_name']);
$json = json_decode($result);
var_dump($json);
//header('Location: '.BASE_URL.'stream-upload-preview');
}
}
HANDLER METHOD
public function uploadStreamPhoto($file)
{
$result = $this->request(API_URL_ADD_PHOTO, array(
'accessToken' => $this->accessToken,
'file' => "@$file;filename=".time().".jpg",
'photoName' => time(),
'albumName' => 'Stream'
));
return $result;
}
CURL REQUEST METHOD
/**
* Creates a curl request with the information passed in post fields
*
* @access private
* @param string $url
* @param array $postFields
* @return string
**/
private function request($url, $postFields = array())
{
$curl = curl_init();
//Check the SSL Matches the host
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);
if($this->debug == true)
{
//Prevent curl from verifying the certificate
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
}
//Set the URL to call
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_HEADER, 0);
//Set the results to be returned
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
//Set the curl request as a post
curl_setopt($curl, CURLOPT_POST, 1);
//Set the post fields
curl_setopt($curl, CURLOPT_POSTFIELDS, $postFields);
$result = curl_exec($curl);
if($result === false)
{
$result = 'Curl error: '.curl_error($curl);
}
curl_close($curl);
return $result;
}
Upvotes: 0
Views: 3908
Reputation: 676
My 2 cents for those ending up here by after the release of PHP 5.5. There are two things worth mentioning:
In PHP 5.5 a new function was introduced that changed the file upload procedure. rfc:curl-file-uploads describes it the best. So if you are using PHP 5.5 or newer, you should probably try to use curl_file_create() instead of adding @/full/file/path
as the file field value.
If you are using PHP 5.5 or newer, you might encounter issues when using old way of uploading files.
First of them is the fact that you have to use CURLOPT_SAFE_UPLOAD
option and set it to FALSE
.
Second, and the thing that made me spend hours debugging, is that you have to do this before setting CULROPT_POSTFIELDS
. If you use curl_setopt_array()
then CURLOPT_SAFE_UPLOAD
should be added to that array before CURLOPT_POSTFIELDS
. If you are using curl_setopt()
then you just have to set CURLOPT_SAFE_UPLOAD
before. Failing to do this will cause the file fields to be send as text containing @/full/file/path
string instead of properly uploading files.
<?php
$options = array(
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => TRUE,
CURLOPT_SAFE_UPLOAD => FALSE,
CURLOPT_POSTFIELDS => array(
'text1' => 'test',
'submit' => 'Send!',
'file1' => '@' . realpath('images/a.jpg'),
'file2' => '@' . realpath('images/b.jpg'),
),
);
$ch = curl_init();
// Needed for PHP > 5.5 to enable the old method of uploading file.
// Make sure to include this before CURLOPT_POSTFIELDS.
if (defined('CURLOPT_SAFE_UPLOAD')) {
curl_setopt($ch, CURLOPT_SAFE_UPLOAD, FALSE);
}
curl_setopt_array($ch, $options);
$content = curl_exec($ch);
$info = curl_getinfo($ch);
curl_close($ch);
$options = array(
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => TRUE,
CURLOPT_POSTFIELDS => array(
'text1' => 'test',
'submit' => 'Send!',
'file1' => curl_file_create(realpath('images/a.jpg')),
'file2' => curl_file_create(realpath('images/b.jpg')),
),
);
$ch = curl_init();
curl_setopt_array($ch, $options);
$content = curl_exec($ch);
$info = curl_getinfo($ch);
curl_close($ch);
Upvotes: 8
Reputation: 6696
OK I have found out what the issue was, hopefully the solution will help a lot of people who don't want to change how their code is in lieu of someone elses.
cURL was not detecting that it was supposed to send this form as a multipart so it was sending the post as a default encoding meaning the other end wasn't receiving the $_FILES variable.
To solve this you need to give the postdata as an array, I was creating the string for the send, I have removed this and am giving the CURLOPT_POSTFIELDS an array.
Another important thing when uploading directly from a form using cURL is to include the information for your file along with the actual file.
My API Call handler now created the array as follows:
public function uploadStreamPhoto($file)
{
$result = $this->request(API_URL_ADD_PHOTO, array(
'accessToken' => $this->accessToken,
'file' => "@$file;filename=".time().".jpg",
'photoName' => time(),
'albumName' => 'Stream'
));
return $result;
}
Take note that the $file variable is $_FILES['tmp_name'] You then also have to define the file name. I will be updating the question with the solution.
Upvotes: 1
Reputation: 1365
function curl_grab_page($url,$data,$secure="false",$ref_url="",$login = "false",$proxy = "null",$proxystatus = "false")
{
if($login == 'true') {
$fp = fopen("cookie.txt", "w");
fclose($fp);
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_COOKIEJAR, "cookie.txt");
curl_setopt($ch, CURLOPT_COOKIEFILE, "cookie.txt");
curl_setopt($ch, CURLOPT_TIMEOUT, 60);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
if ($proxystatus == 'true') {
curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, TRUE);
curl_setopt($ch, CURLOPT_PROXY, $proxy);
}
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
if($secure=='true')
{
curl_setopt($ch, CURLOPT_SSLVERSION,3);
}
curl_setopt( $ch, CURLOPT_HTTPHEADER, array( 'Expect:' ) );
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_REFERER, $ref_url);
curl_setopt($ch, CURLOPT_HEADER, TRUE);
curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
ob_start();
return curl_exec ($ch); // execute the curl command
curl_getinfo($ch);
ob_end_clean();
curl_close ($ch);
unset($ch);
}
use this curl function according to your need as i was using it to send data in post even files.
and
$data['FileName'] = '@'.$ProperPath;
// Proper Path = c:/images/a.jpg
curl_grab_page("url", $data);
Upvotes: 0