Can anyone give me an example for PHP's CURLFile class? - php

I had a very simple PHP code to upload a file to a remote server; the way I was doing it (as has been suggested here in some other solutions) is to use cUrl to upload the file.
Here's my code:
$ch = curl_init("http://www.remotesite.com/upload.php");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, array('fileupload' => '#'.$_FILES['Filedata']['tmp_name']));
echo curl_exec($ch);
The server is running PHP 5.5.0 and it appears that #filename has been deprecated in PHP >= 5.5.0 as stated here under the CURLOPT_POSTFIELDS description, and therefore, I'm getting this error:
Deprecated: curl_setopt(): The usage of the #filename API for file uploading is deprecated. Please use the CURLFile class instead in ...
Interestingly, there is absolutely nothing about this Class on php.net aside from a basic class overview. No examples, no description of methods or properties. It's basically blank here. I understand that is a brand new class with little to no documentation and very little real-world use which is why practically nothing relevant is coming up in searches on Google or here on Stackoverflow on this class.
I'm wondering if there's anyone who has used this CURLFile class and can possibly help me or give me an example as to using it in place of #filename in my code.
Edit:
I wanted to add my "upload.php" code as well; this code would work with the traditional #filename method but is no longer working with the CURLFile class code:
$folder = "try/";
$path = $folder . basename( $_FILES['file']['tmp_name']);
if(move_uploaded_file($_FILES['file']['tmp_name'], $path)) {
echo "The file ". basename( $_FILES['file']['tmp_name']). " has been uploaded";
}
Final Edit:
Wanted to add Final / Working code for others looking for similar working example of the scarcely-documented CURLFile class ...
curl.php (local server)
<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post" enctype="multipart/form-data">
<label for="file">Filename:</label> <input type="file" name="Filedata" id="Filedata" />
<br />
<input type="submit" name="submit" value="Submit" />
</form>
<?php
if ($_POST['submit']) {
$uploadDir = "/uploads/";
$RealTitleID = $_FILES['Filedata']['name'];
$ch = curl_init("http://www.remotesite.com/upload.php");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$args['file'] = new CurlFile($_FILES['Filedata']['tmp_name'],'file/exgpd',$RealTitleID);
curl_setopt($ch, CURLOPT_POSTFIELDS, $args);
$result = curl_exec($ch);
}
?>
upload.php (remote server)
$folder = "try/";
$path = $folder . $_FILES['file']['name'];
if(move_uploaded_file($_FILES['file']['tmp_name'], $path)) {
echo "The file ". basename( $_FILES['file']['name']). " has been uploaded";
}

There is a snippet on the RFC for the code: https://wiki.php.net/rfc/curl-file-upload
curl_setopt($curl_handle, CURLOPT_POST, 1);
$args['file'] = new CurlFile('filename.png', 'image/png', 'filename.png');
curl_setopt($curl_handle, CURLOPT_POSTFIELDS, $args);
You can also use the seemingly pointless function curl_file_create( string $filename [, string $mimetype [, string $postname ]] ) if you have a phobia of creating objects.
curl_setopt($curl_handle, CURLOPT_POST, 1);
$args['file'] = curl_file_create('filename.png', 'image/png', 'filename.png');
curl_setopt($curl_handle, CURLOPT_POSTFIELDS, $args);

Thanks for your help, using your working code I was able to solve my problem with php 5.5 and Facebook SDK. I was getting this error from code in the sdk class.
I don't thinks this count as a response, but I'm sure there are people searching for this error like me related to facebook SDK and php 5.5
In case someone has the same problem, the solution for me was to change a little code from base_facebook.php to use the CurlFile Class instead of the #filename.
Since I'm calling the sdk from several places, I've just modified a few lines of the sdk:
In the method called "makeRequest" I made this change:
In this part of the code:
if ($this->getFileUploadSupport()){
$opts[CURLOPT_POSTFIELDS] = $params;
} else {
$opts[CURLOPT_POSTFIELDS] = http_build_query($params, null, '&');
}
Change the first part (with file upload enabled) to:
if ($this->getFileUploadSupport()){
if(!empty($params['source'])){
$nameArr = explode('/', $params['source']);
$name = $nameArr[count($nameArr)-1];
$source = str_replace('#', '', $params['source']);
$size = getimagesize($source);
$mime = $size['mime'];
$params['source'] = new CurlFile($source,$mime,$name);
}
if(!empty($params['image'])){
$nameArr = explode('/', $params['image']);
$name = $nameArr[count($nameArr)-1];
$image = str_replace('#', '', $params['image']);
$size = getimagesize($image);
$mime = $size['mime'];
$params['image'] = new CurlFile($image,$mime,$name);
}
$opts[CURLOPT_POSTFIELDS] = $params;
} else {
$opts[CURLOPT_POSTFIELDS] = http_build_query($params, null, '&');
}
Maybe this can be improved parsing every $param and looking for '#' in the value.. but I did it just for source and image because was what I needed.

FOR curl_setopt(): The usage of the #filename API for file uploading is deprecated. Please usethe CURLFile class instead
$img='image.jpg';
$data_array = array(
'board' => $board_id,
'note' => $note,
'image' => new CurlFile($img)
);
$curinit = curl_init($url);
curl_setopt($curinit, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curinit, CURLOPT_POST, true);
curl_setopt($curinit, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($curinit, CURLOPT_POSTFIELDS, $data_array);
curl_setopt($curinit, CURLOPT_SAFE_UPLOAD, false);
$json = curl_exec($curinit);
$phpObj = json_decode($json, TRUE);
return $phpObj;

CURLFile has been explained well above, but for simple one file transfers where you don't want to send a multipart message (not needed for one file, and some APIs don't support multipart), then the following works.
$ch = curl_init('https://example.com');
$verbose = fopen('/tmp/curloutput.log', 'w+'); // Not for production, but useful for debugging curl issues.
$filetocurl = fopen(realpath($filename), 'r');
// Input the filetocurl via fopen, because CURLOPT_POSTFIELDS created multipart which some apis do not accept.
// Change the options as needed.
$options = array(
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => array(
'Content-type: application/whatever_you_need_here',
'Authorization: Basic ' . $username . ":" . $password) // Use this if you need password login
),
CURLOPT_NOPROGRESS => false,
CURLOPT_UPLOAD => 1,
CURLOPT_TIMEOUT => 3600,
CURLOPT_INFILE => $filetocurl,
CURLOPT_INFILESIZE => filesize($filename),
CURLOPT_VERBOSE => true,
CURLOPT_STDERR => $verbose // Remove this for production
);
if (curl_setopt_array($ch, $options) !== false) {
$result = curl_exec($ch);
$info = curl_getinfo($ch);
curl_close($ch);
} else {
// A Curl option could not be set. Set exception here
}
Note the above code has some extra debug - remove them once it is working.

Php POST request send multiple files with curl function:
<?php
$file1 = realpath('ads/ads0.jpg');
$file2 = realpath('ads/ads1.jpg');
// Old method
// Single file
// $data = array('name' => 'Alexia', 'address' => 'Usa', 'age' => 21, 'file' => '#'.$file1);
// $data = array('name' => 'Alexia', 'address' => 'Usa', 'age' => 21, 'file[0]' => '#'.$file1, 'file[1]' => '#'.$file2);
// CurlFile method
$f1 = new CurlFile($file1, mime_content_type($file1), basename($file1));
$f2 = new CurlFile($file2, mime_content_type($file2), basename($file2));
$data = array('name' => 'Alexia', 'address' => 'Usa', 'age' => 21, 'file[1]' => $f1, 'file[2]' => $f2);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://url.x/upload.php');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_SAFE_UPLOAD, false); // !!!! required as of PHP 5.6.0 for files !!!
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-GB; rv:1.9.2) Gecko/20100115 Firefox/3.6 (.NET CLR 3.5.30729)");
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); // 1, 2
curl_setopt($ch, CURLOPT_TIMEOUT, 60);
// curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
$res2 = curl_exec($ch);
echo $res2;
?>
<?php
// upload.php
$json = json_decode(file_get_contents('php://input'), true);
if(!empty($json)){ print_r($json); }
if(!empty($_GET)){ print_r($_GET); }
if(!empty($_POST)){ print_r($_POST); }
if(!empty($_FILES)){ print_r($_FILES); }
?>

Related

PHP Curl Post and Get Response

I have a shell code as below."curl -X POST -F 'file=#textomate-api.pdf;type=text/plain' https://textomate.com/a/uploadMultiple"
This code send a file to the URL and get the response below.
{
"countedFiles": [
{
"wordsNumber": 340,
"charsNumber": 2908,
"charsNoSpacesNumber": 2506,
"wordsNumberNN": 312,
"charsNumberNN": 2755,
"charsNoSpacesNumberNN": 2353,
"md5": null,
"fileName": "textomate-api.pdf",
"error": null
}
],
"total": {
"wordsNumber": 340,
"charsNumber": 2908,
"charsNoSpacesNumber": 2506,
"wordsNumberNN": 312,
"charsNumberNN": 2755,
"charsNoSpacesNumberNN": 2353,
"md5": null
}
}
And I want to post a file via PHP and get this response or only value of "charsNoSpacesNumber".
Could you please help me with this?
Thanks a lot
You can do it as follows:
YET be sure to first check their T&C as I am not sure if they provide such a service for free.
Also be sure to include some error / exceptions handling.
<?php
//Initialise the cURL var
$ch = curl_init();
//Get the response from cURL
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
//Set the Url
curl_setopt($ch, CURLOPT_URL, 'https://textomate.com/a/uploadMultiple');
$path = '/path/to/your/file.pdf';
$file = curl_file_create($path, 'application/pdf', 'file');
//Create a POST array with the file in it
$postData = array(
'file' => $file,
);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
// Execute the request, decode the json into array
$response = json_decode(curl_exec($ch), true);
var_dump($response['total']['charsNoSpacesNumber']);
Thanks for your support Bartosz.
This is my code and I also shared an image of the code and results.
I hope there are enough information.
<?php
if(is_callable('curl_init')){
echo "curl is active";
} else {
echo "curl is passive";
}
//Initialise the cURL var
$ch = curl_init();
//Get the response from cURL
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
//Set the Url
curl_setopt($ch, CURLOPT_URL, 'https://textomate.com/a/uploadMultiple');
$path = 'textomate-api.pdf';
$file = curl_file_create($path, 'application/pdf', 'file');
//Create a POST array with the file in it
$postData = array(
'file' => $file,
);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
// Execute the request, decode the json into array
$response = json_decode(curl_exec($ch), true);
var_dump($response['total']['charsNoSpacesNumber']);
var_dump($response);
var_dump(file_exists($path));
?>
Updated code is below and you can see the results in the image.
I want to use this API on my website to be able to calculate character count of documents. I am using Wordpress and API provider gives us 3 options, Java, PHP (Wordpress) and Shell. They have something for Wordpress but I don't know how to use it.
You can reach all the files from here.
https://github.com/zentaly/textomate-api
If you take a look there, you can get more information and maybe you can find me a better solution.
And again thank you so much for your support, I appreciate it.
<?php
if(is_callable('curl_init')){
echo "curl is active";
} else {
echo "curl is passive";
}
//Initialise the cURL var
$ch = curl_init();
//Get the response from cURL
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
//Set the Url
curl_setopt($ch, CURLOPT_URL, 'https://textomate.com/a/uploadMultiple');
curl_setopt($ch, CURLOPT_VERBOSE, 2);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_exec: var_dump(curl_errno($ch));
var_dump(curl_error($ch));
$path = 'textomate-api.pdf';
$file = curl_file_create($path, 'application/pdf', 'file');
//Create a POST array with the file in it
$postData = array(
'file' => $file,
);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
// Execute the request, decode the json into array
$response = curl_exec($ch);
var_dump($response);
$response = json_decode($ch);
var_dump($response['total']['charsNoSpacesNumber']);
var_dump($response);
var_dump(file_exists($path));
var_dump($file);
?>

PHP set multipart or form data

I am trying to work with a html file using the following but I am having an issue doing it with the PHP api. I already have the files ready on the server but I cannot figure out how to set the multipart/form data using the following code to do the conversion. Lets say I have a html file in the same folder how do I use it in the following code for conversion.
Code for conversion :
<?php
//set POST variables
$fields = array('from' => 'markdown',
'to' => 'pdf',
'input_files[]' => "#/".realpath('markdown.md').";type=text/x-markdown; charset=UTF-8"
);
//open connection
$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-type: multipart/form-data"));
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); //needed so that the $result=curl_exec() output is the file and isn't just true/false
//execute post
$result = curl_exec($ch);
//close connection
curl_close($ch);
?>
Since PHP 5.5, the # format for specifying a file path is no longer valid, and the value will be sent as a raw string. Instead try curl_file_create. Also, regardless of version, don't forget to set CURLOPT_POST variable to true as well. This code also assumes you have read access to the file being uploaded.
<?php
$url = 'http://c.docverter.com/convert';
$fields = [
'from' => 'markdown',
'to' => 'pdf',
'input_files[]' => (PHP_VERSION_ID < 50500) ? '#' . realpath('markdown.md') : curl_file_create('markdown.md')
];
$result_file = 'uploads/result.pdf';
//open connection
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $fields,
CURLOPT_RETURNTRANSFER => true
]);
$result = curl_exec($ch);
curl_close($ch);
file_put_contents($result_file, $result);

Posting a file with cURL doesn't work with # at the beginning of the path

So I'm trying to send files to another page using cURL, along with other POST variables. Most of it works, except the file sending. But it only doesn't work on my localhost. When it's uploaded to the hosted web server, it works exactly like it should.
I also don't want to use CURLFile because the web server doesn't support it.
Here is the code:
// Output the image
imagejpeg($fileData['imageBackground'], $newFileName, 75);
// Get Old Background
$query['getBackground'] = $this->PDO->prepare("SELECT backgroundImage FROM accounts WHERE token = :token");
$query['getBackground']->execute(array(':token' => $token));
$queryData = $query['getBackground']->fetch(PDO::FETCH_ASSOC);
$verificationKey = self::newVerificationKey($token);
// Send the file to the remote
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $uploadURL);
curl_setopt($ch, CURLOPT_POST, true);
$postArgs = array(
'action' => 'updateBackground',
'verificationKey' => $verificationKey,
'file' => '#' . realpath($newFileName),
'oldBackground' => $queryData['backgroundImage']
);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postArgs);
curl_setopt($ch, CURLOPT_SAFE_UPLOAD, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
curl_close($ch);
unlink($newFileName);
Thanks in advance!
Most likely your webserver is running an older version which supports the "#" - but not curlfile. Your local machine supports curlfile - but not the "#" (in the default configuration)...
You can use
if (class_exists("CurlFile")){
$postArgs = array(
'action' => 'updateBackground',
'verificationKey' => $verificationKey,
'file' => new CurlFile($newFileName),
'oldBackground' => $queryData['backgroundImage']
);
}else{
$postArgs = array(
'action' => 'updateBackground',
'verificationKey' => $verificationKey,
'file' => '#' . realpath($newFileName),
'oldBackground' => $queryData['backgroundImage']
);
}
which is recommended, because the #-way is considered unsafe, so use CurlFile, when available.
However, to have the #-way working lokaly as well, you can use
curl_setopt($ch, CURLOPT_SAFE_UPLOAD, false);
This defaulted to false prior to PHP 5.5, but defaults to true for later versions.
Note, play arround with the "order". There seems to be an issue with CURLOPT_POSTFIELDS beeing somewhat sensitive to existing options. So
curl_setopt($ch, CURLOPT_POSTFIELDS, $postArgs);
curl_setopt($ch, CURLOPT_SAFE_UPLOAD, false);
might not work, while
curl_setopt($ch, CURLOPT_SAFE_UPLOAD, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postArgs);
might.

mailchimp http error: you must specify a apikey

I'm the using MailChimp 2.0 api and trying to post a lists/subscribe call using php. The call is returning an error "You must specify a apikey value".
Here's the code that makes the post:
function json_post ($url, $params)
{
print '<p>url = ' . $url . '</p>';
$data = json_encode ($params);
print '<p>data = ' . $data . '</p>';
$handle = curl_init ($url);
curl_setopt ($handle, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt ($handle, CURLOPT_POST_FIELDS, $data);
curl_setopt ($handle, CURLOPT_RETURNTRANSFER, true);
curl_setopt ($handle, CURLOPT_HTTPHEADER, array ('Content-Type: application/json',
'Content-Length: ' . strlen($data_string)));
$result = curl_exec ($handle);
print '<p>curl_error: ' . curl_errno ($handle) . '</p>';
return $result;
}
The print statements show:
url = https://us10.api.mailchimp.com/2.0/lists/subscribe.json
data = {"apikey":"...","id":"...","email":{"email":"test1#abc.com"},"merge_vars":{"groupings":{"name":"test"}}}
curl_error: 0
{"status":"error","code":-100,"name":"ValidationError","error":"You must specify a apikey value"}
I presume there's something wrong with the syntax. The api key is cut & pasted from my mailchimp account page. I've tried it with and without the -us10 suffix. Any ideas?
To subscribe:
$email='';
$apikey='';
$listId='';
$data = array(
'email_address'=>$email,
'apikey'=>$apikey,
'merge_vars' => array(),
'id' => $listId,
'double_optin' => false,
'update_existing' => true,
'replace_interests' => false,
'send_welcome' => false,
'email_type' => 'html'
);
$submit_url = "http://us6.api.mailchimp.com/1.3/?method=listSubscribe";
$payload = json_encode($data);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $submit_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, urlencode($payload));
$result = curl_exec($ch);
curl_close ($ch);
$data = json_decode($result);
if (isset($data->error) and $data->error){
//Error
} else {
//Ok
}
Cases where you get "API Key Missing" but the API Key is definitely there usually comes from JSON Syntax errors, which MailChimp doesn't catch specifically. You'll want to make sure that JSON isn't getting double-encoded or anything like that.
In this case, it is probably CURLOPT_POST_FIELDS -- the actual PHP Constant you're looking for is CURLOPT_POSTFIELDS.
You should use Guzzle or another HTTP library to ensure you're not double-encoding your JSON or otherwise getting tripped up by the Curl library's verbosity.

PHP Taleo Library : Update a candidate resume

I am using following php library for to work with Taleo
Taleo : http://www.oracle.com/us/products/applications/taleo/overview/index.html
PHP library : https://github.com/Polzme/Taleo
Taleo REST API documentation: http://www.oracle.com/technetwork/documentation/default-1841567.html
POST /candidate/{id}/resume
I wanted to use above API for my project
I wanted to create candidate and upload resume for them using api.
I went through the library code but i didn't found any file or any code line, which is related to resume or attachment
Can you please help me with simple example with library or without library.
Here is working the example, some how I am able to get it worked
<?php
function getCurlValue($filename, $contentType, $postname)
{
// PHP 5.5 introduced a CurlFile object that deprecates the old #filename syntax
// See: https://wiki.php.net/rfc/curl-file-upload
if (function_exists('curl_file_create')) {
return curl_file_create($filename, $contentType, $postname);
}
// Use the old style if using an older version of PHP
$value = "#{$filename};filename=" . $postname;
if ($contentType) {
$value .= ';type=' . $contentType;
}
return $value;
}
function Curl_file_upload($url, $postData)
{
$filename = '/Users/bhushan/Downloads/resume.pdf';
$cfile = getCurlValue($filename,'application/pdf','resume.pdf');
//NOTE: The top level key in the array is important, as some apis will insist that it is 'file'.
$data = array('file' => $cfile);
$ch = curl_init();
$options = array(CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLINFO_HEADER_OUT => true, //Request header
CURLOPT_HEADER => true, //Return header
CURLOPT_SSL_VERIFYPEER => false, //Don't veryify server certificate
CURLOPT_POST => true,
CURLOPT_COOKIE =>"authToken=".$_SESSION['authToken'],
CURLOPT_POSTFIELDS => $data
);
curl_setopt_array($ch, $options);
$output = $result = curl_exec($ch);
$header_info = curl_getinfo($ch,CURLINFO_HEADER_OUT);
$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$header = substr($result, 0, $header_size);
$body = substr($result, $header_size);
curl_close($ch);
return $output;
}
function curl_call($url, $postData)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,true);
curl_setopt($ch,CURLOPT_HEADER, false);
//curl_setopt($ch, CURLOPT_HTTPHEADER,$header);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData));
$output=curl_exec($ch);
curl_close($ch);
return $output;
}
if(!isset($_SESSION['authToken']) || empty($_SESSION['authToken']))
{
$data = array('orgCode' => 'xxxx', 'userName' => 'xxxx', 'password' => 'xxx');
echo $json = curl_call('https://xxx.xxx.taleo.net/ldd01/ats/api/v1/login', $data);
$json = json_decode($json, true);
if(isset($json['response']['authToken'])) $_SESSION['authToken'] = $json['response']['authToken'];
}
else if(isset($_SESSION['authToken']) && !empty($_SESSION['authToken']))
{
$params = array();
echo $json = Curl_file_upload('https://xxx.xxx.taleo.net/ldd01/ats/api/v1/object/candidate/58/resume', $params);
}

Categories