Sending imagepng() object to server using cURL - php

I'm trying to take an imagepng() object and upload it to a different server using cURL. Here is the code I've got. To be clear, I know the imagepng file works correctly and is being generated because I can save it locally on the server the code is running on. I'm just not sure how to send that info to a new server. All of the variables are set before this code ($fileName, $imageObject, etc.):
$file = imagepng($imageObject, 'newTest'.$counter.'.png');
if($file){
$ch = curl_init();
$fp = $file;
curl_setopt($ch, CURLOPT_URL, 'ftp://'.$ftp_user.':'.$ftp_pass.'#'.$ftp_server.'/'.$fileName.'.png');
curl_setopt($ch, CURLOPT_UPLOAD, 1);
curl_setopt($ch, CURLOPT_INFILE, $fp);
curl_setopt($ch, CURLOPT_INFILESIZE, filesize($file));
curl_exec ($ch);
$error_no = curl_errno($ch);
curl_close ($ch);
if ($error_no == 0) {
$error = 'File uploaded succesfully.';
} else {
$error = 'File upload error.';
}
}
The errors I am getting for every file (this code is in a loop processing multiple files) is. Of course {MY_URL} is replaced with the actual URL of my file:
Warning: curl_setopt(): supplied argument is not a valid File-Handle resource in {MY_URL} on line 43
Warning: filesize() [function.filesize]: stat failed for 1 in {MY_URL} on line 44
So it appears that the file is the wrong format when it's being cURLed. What do I need to set it to in order to send it correctly?
Thanks for your help!

imagepng outputs image into a file,but does not return a file handle (it only returns TRUE in case of success). You need to use something like fopen to get a valid file handle. Try replacing $fp=$file with this:
$fp = fopen('newTest'.$counter.'.png', "rb");
Also, replace filesize($file) with filesize($fp).
In general, $file is just a boolean, not a file handle. Use $fp for every function that expects a file handle. Also, don't forget to close every file at the end of the loop (e.g. add the following line after curl_close):
fclose($fp);

Related

How to download client-site a video with cURL / PHP?

If the following PHP is runnig, I would like to download the file with `cURL on the client-site. It means, if one of my website visitor run's an action, which starts this PHP file, it should download the file on this PC.
I tried with different locations, but without any success. If I run my code, it does always download it on my WebSever, which is not this, what I want.
<?php
//The resource that we want to download.
$fileUrl = 'https://www.example.com/this-is-a-example-video';
//The path & filename to save to.
$saveTo = 'test.mp4';
//Open file handler.
$fp = fopen($saveTo, 'w+');
//If $fp is FALSE, something went wrong.
if($fp === false){
throw new Exception('Could not open: ' . $saveTo);
}
//Create a cURL handle.
$ch = curl_init($fileUrl);
//Pass our file handle to cURL.
curl_setopt($ch, CURLOPT_FILE, $fp);
//Timeout if the file doesn't download after 20 seconds.
curl_setopt($ch, CURLOPT_TIMEOUT, 20);
//Execute the request.
curl_exec($ch);
//If there was an error, throw an Exception
if(curl_errno($ch)){
throw new Exception(curl_error($ch));
}
//Get the HTTP status code.
$statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
//Close the cURL handler.
curl_close($ch);
if($statusCode == 200){
echo 'Downloaded!';
} else{
echo "Status Code: " . $statusCode;
}
?>
How can I change the cURL downloading process to the client-site?
PHP cannot run client-side.
You could use cURL to download data to the server (without saving it to a file) and then output that data to the client.
Don't do this:
//Open file handler.
$fp = fopen($saveTo, 'w+');
or this:
//Pass our file handle to cURL.
curl_setopt($ch, CURLOPT_FILE, $fp);
Then capture the output:
//Execute the request.
curl_exec($ch);
Should be:
//Execute the request.
$output = curl_exec($ch);
Then you can:
echo $output;
… but make sure you set the Content-Type and consider setting the Content-Length response headers. You might also want Content-Disposition.
Under most circumstances, it would probably be better to simply send the browser to fetch the file directly instead of proxying it through the server.
$fileUrl = 'https://www.example.com/this-is-a-example-video';
header("Location: $fileUrl");

Upload image to telegra.ph with PHP

I don't know the Python language. Can someone help me understand whether I correctly converted this to PHP? I want to upload a file to http://telegra.ph with PHP, but I don't know how to upload from PHP.
This code is an example from a Python Telegraph API wrapper library:
import requests
with open('/Users/python273/Desktop/123345.jpeg', 'rb') as f:
print(
requests.post(
'http://telegra.ph/upload',
files={'file': ('file', f, 'image/jpeg')} # image/gif, image/jpeg, image/jpg, image/png, video/mp4
).json()
)
And this is my PHP code that doesn't work. Is there something wrong?
$url = 'http://example.com/image.jpg';
$img = 'http://telegra.ph/upload/';
$ch = curl_init($url);
$fp = fopen($img, 'wb');
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_exec($ch);
curl_close($ch);
fclose($fp);
When I run this code, I see the following error:
Warning: copy(telegra.ph/upload): failed to open stream: HTTP wrapper does not support writeable connections
Your code:
$img = 'http://telegra.ph/upload/';
...
$fp = fopen($img, 'wb');
PHP fopen() documentation is here http://php.net/manual/en/function.fopen.php , check what $mode parameter means. Why are you trying to open remote file for writing, if you only need to read it?

Highchart save chart image using cURL

I am using HighCharts and saving image of chart using cURL. It is working fine at my localhost. But when I try the same code on server, the image is blank. And in server error_log I found this warning message:
PHP Warning: imagecreatefromjpeg(): '10361254147.jpeg' is not a valid JPEG file in public_html/project/assign_img.php on line 34
The code that I am using is as below:
$imgNm = 'https://export.highcharts.com/charts/chart.2ce468213abe432aa1c288339f90171e.jpeg';
$img = 'xyz.jpeg';
$ch = curl_init($imgNm);
$fp = fopen($img, "w");
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_exec($ch);
curl_close($ch);
fclose($fp);
imagecreatefromjpeg($img);
Not sure where I am wrong.
If you just want to save your file and show in your browser you don't need cURL:
$imgNm = 'https://export.highcharts.com/charts/chart.2ce468213abe432aa1c288339f90171e.jpeg';
$filename = 'xyz.jpeg';
$image_data = file_get_contents($imgNm);
file_put_contents($filename, __DIR__ . '/' . $imgNm);
After this the file is save in same directory as your script (named 'xyz.jpeg') and you can use it in whatever way you want
I added a line for SSL verification to be false and the code worked fine for me.
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
Hope this help someone.

Upload images to Imgur with Curl PHP

<form action="php.php" method="post" enctype="multipart/form-data">
Send these files:<br />
<input name="img[]" type="file" multiple="multiple" /><br />
<input type="submit" value="Send files" />
</form>
<?php
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
foreach ($_FILES['img']['tmp_name'] as $index => $tmpName) {
if( !empty( $tmpName ) && is_uploaded_file( $tmpName ) )
{
$handle = fopen($tmpName, "r");
$data = fread($handle, filesize($tmpName));
$client_id = "d5f419ef9aedf16";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.imgur.com/3/image.json');
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: Client-ID ' . $client_id));
curl_setopt($ch, CURLOPT_POSTFIELDS, array('image' => base64_encode($data)));
curl_setopt($ch, CURLOPT_VERBOSE, true);
curl_setopt($ch, CURLOPT_STDERR, fopen('php://stderr', 'w'));
$reply = curl_exec($ch);
$info = curl_getinfo($ch);
var_dump($info);
if(curl_errno($ch))
echo 'Curl error: '.curl_error($ch);
curl_close($ch);
$reply = json_decode($reply);
printf('<img height="180" src="%s" >', $reply->data->link);
}
}
?>
I made this page, works perfectly on localhost but when I run it from my server it does not work, problem is I have no output at all, not even the curl_getinfo or errors. Dont know how to debug this since I can't get any info out of it.
Thank you hans for the suggestions, you were right, it was not mandatory to use base64, not in V3 API, it was on the previous versions, not anymore. Now it's much faster. This is my final code
if(!empty($_FILES['img']['tmp_name'])){
foreach ($_FILES['img']['tmp_name'] as $index => $tmpName) {
if( !empty( $tmpName ) && is_uploaded_file( $tmpName ) )
{
if ($handle = fopen($tmpName, "rb")) {
$data = stream_get_contents($handle, filesize($tmpName));
$client_id = "d5f619ef9aedf16";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.imgur.com/3/image.json');
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: Client-ID ' . $client_id));
curl_setopt($ch, CURLOPT_POSTFIELDS, array('image' => $data));
curl_setopt($ch, CURLOPT_VERBOSE, true);
$reply = curl_exec($ch);
if(curl_errno($ch))
echo 'Curl error: '.curl_error($ch);
curl_close($ch);
$reply = json_decode($reply);
$screens .= $reply->data->link . " ";
fclose($handle);
}
}
}
}
The reason why it was not uploading them images was upload_max_filesize and max_post_size, I've increased them and I had no problems.
you do several things wrong.
this code:
foreach ($_FILES['img']['tmp_name'] as $index => $tmpName) { will be executed even on GET requests, which contains no files, thus $_FILES['img'] does not exist, and you get an Undefined index: img error. furthermore, on GET requests, this undefined index bug returns NULL to foreach, and when you tell foreach() to loop a NULL, it gives you this error: Invalid argument supplied for foreach(). the fact that you haven't already caught up on this, proves that you're not checking the php error logs. this is the first thing you should do, when debugging a malfunctioning php script. - to fix both of these, wrap the foreach in if(!empty($_FILES['img']['tmp_name']){} - next, find your PHP error logs, and read those error reports. (usually you can find it in phpinfo() under error_log - or in case its emptystring, its your web servers' error log, eg for nginx with an empty php error_log php setting, its in nginx's error log (like /var/log/nginx/error.log )
next issue, $handle = fopen($tmpName, "r"); this will corrupt binary data (like images) on some systems (famously, windows), change it to rb for safely reading binary data (and image formats are binary)
next issue, you believe that fread() reads as many bytes as you request it to read, that is incorrect. fread will read UP TO as many bytes as requested, but can stop for many reasons before it has read the requested number of bytes. you'll either have to loop calling fread until it has read all the bytes, or better yet, use stream_get_contents, which will essentially do that fread() loop for you.
next issue, this line curl_setopt($ch, CURLOPT_STDERR, fopen('php://stderr', 'w')); is completely unnecessary, PHP's STDERR is libcurl's default STDERR anyway.
next issue, you don't fclose() $handle. this is ok for short running scripts (becuase the OS fclose() it for you when the script finishes), but the bigger your code grows, the longer the resource leak will be there, its a good programming habit to always close it, so do that.
next issue, i can't believe imgur actually wants a base64 encoded copy of the image, that is such a cpu & bandwidth & ram waste... the POST encoding they're using, multipart/form-data is fully binary safe, so there's no reason to base64 encode it... are you sure they want it base64 encoded? you AND them can save about 33% bandwidth by NOT using base64 encoding here.
given all the things you are doing wrong with the file operations, it'd be better to use the file_get_contents function - it reads the entire file, it opens the file in binary read mode (as opposed to your code, where you open it in TEXT mode, potentially corrupting the image as you read it), and it reads the entire file, not just the chunk of it that the first fread() call will read (which, if you're lucky, is the entire file, but if you're not lucky, is just the first chunk of it), and it does fclose() for you (which you forget to do)
Why dont you use imgur php sdk and simple implement it with below code:
require_once APPPATH."/third_party/imgur/vendor/autoload.php";
$pathToFile = '../path/to/file.jpg';
$imageData = [
'image' => $pathToFile,
'type' => 'file',
];
$client->api('image')->upload($imageData);

How to call "CURL" to call external URL

How to use "CURL" to call external URL since the url_fopen is disabled for security reasons. I want to open a pdf file. For security reason url_fopen function is disabled. So anyone can help me?
function Header()
{
$this->SetY(20);
$this->Image("images/logo-s.jpg", 120,0,80,20, "JPG", "www.example.com");
$this->Ln(4);
}
There are lots of answers for connecting, downloading or saving something to a URL by CURL function, but even if the CURL be disabled in your server you can still use stream_context_create, check this question
To do it with CURL try
$url = 'http://www.example.com/images/logo-s.jpg';
$path = '/path/to/images/logo-s.jpg';
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$data = curl_exec($ch);
curl_close($ch);
file_put_contents($path, $data); // to save it somewhere
First initialize a curl handler with:
$curl_handler = curl_init("http://www.linktomypdf.com/");
If you need to read it into a file:
$fp = fopen("mypdf.pdf", "w");
Now use curl_setopt() to set the option for curl_handler:
curl_setopt($curl_handler, CURLOPT_FILE, $fp);
First parameter is always curl_handler, second is which option you want to set , third is the value you want to set. So this call set CURLOPT_FILE to be $fp.
There are list of options you can find it here:
https://php.net/manual/en/function.curl-setopt.php
To make it easy to read the code:
$curl_handler = curl_init("http://www.linktomypdf.com/");
$fp = fopen("mypdf.pdf", "w");
curl_setopt($curl_handler, CURLOPT_FILE, $fp);
curl_exec($ch); //execute curl session
curl_close($ch); // close curl_handler
fclose($fp); // close file

Categories