I have created two file php. The first one for send a file through curl utilizing the chunking method. And a second one for receiving the file.
What I need is to send a chunked file with curl and receive it. However, I am not really sure that the code in this two pages does what I need.
This is the code in the first page (send.php).
<?php
function curlPutThrottle($ch, $fh, $length = false)
{
if (!$length)
{
$length = 4096;
}
return fread($fh, $length);
}
$target_url = "http://localhost/save.php?filename=test2.zip";
$cFile = fopen ('./test.zip', "r");
$size = filesize('./test.zip');
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $target_url);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_PUT, true);
// Let curl know that we are sending an entity body
curl_setopt($ch, CURLOPT_UPLOAD, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1);
// Let curl know that we are using a chunked transfer encoding
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Transfer-Encoding: chunked'));
curl_setopt($ch, CURLOPT_READFUNCTION, 'curlPutThrottle');
curl_setopt($ch, CURLOPT_INFILE, $cFile);
curl_setopt($ch, CURLOPT_INFILESIZE, $size);
$result=curl_exec ($ch);
curl_close ($ch);
echo $result;
?>
And this is the code in save.php.
<?php
function file_get_contents_chunked($filename, $chunk_size, $callback) {
$handle = fopen($filename, 'r');
if (feof($handle)) {
return 0;
} else {
while (!feof($handle)) {
call_user_func_array($callback, array(fread($handle, $chunk_size)));
}
fclose($handle);
return 1;
}
}
if ($_SERVER['REQUEST_METHOD'] == 'PUT') {
$count = 0;
$file = fopen('./'.$_GET['filename'], 'wb+');
$res = file_get_contents_chunked('php://input', 8192, function ($chunk) use (&$file) {
global $count;
fwrite($file, $chunk);
$count++;
});
if (!$res)
echo "file not received";
else
echo "file received ".$count;
} else {
echo 'Not a PUT request!!!';
}
?>
Is this code in these two pages correct for sending a chunked file through curl? Or is it incomplete in some way?
And, if is it incomplete what I need to send a chunked file correctly using curl?
Thanks at all for your help in this.
Related
in my code, I am making curl call and after getting response I am calling current file if proper response does not get. like this,
<?php
include 'fauxapi_client.php';
$obj = new Fauxapi_client;
$url=$obj->base_url.'/Fauxapi_client/device_version_update';
$version = trim(file_get_contents('/usr/local/www/version.txt'));
$iso_version = trim(file_get_contents('/usr/local/www/iso_version.txt'));
$temp = array('device_ip'=>$obj->current_device_ip,'version'=>$version,'iso_version'=>$iso_version);
$temp = http_build_query($temp);
$headers[] = 'Content-Type: application/x-www-form-urlencoded; charset=utf-8';
$ch = curl_init();
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT ,0);
curl_setopt($ch, CURLOPT_TIMEOUT, 40);
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $temp);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER,$headers);
$output = curl_exec ($ch);
curl_close ($ch);
if ($output === false) {
echo 'Curl Call Fail';
}
else{
$response = json_decode($output,true);
if (isset($response['data']['next_version'])) {
file_put_contents('/usr/local/www/version.txt', trim($response['data']['next_version']));
if (floatval($response['data']['max_updatable_version']) > floatval($response['data']['next_version'])) {
shell_exec("/usr/local/bin/php /usr/local/www/version_update.php");
}
}
else{
echo 'next_version is not in response ';
}
}
var_dump($output);
?>
in the above code
shell_exec("/usr/local/bin/php /usr/local/www/version_update.php");
is a current file call.
when I echo something there it will echo but not calling a current file. so, how to call current file there?
Are you sure the extra space after php? bin/php /
And if /usr/local/bin/php /usr/local/www/version_update.php is current file you can use __FILE__ instead it.
And please make sure sufficient permissions.
I have a product feed which automatically downloads as a csv when I put the url in a browser.
I want to write a php script to get the data from the url,parse it,get what data I require and create a new csv.
The problem i am facing is when I use curl or file_get_contents() I get an empty array.
Update:
the new CSV file is empty
$feed = 'https:/www.url/feeds/feed.csv';
$path = "./newfile.csv";
function download_page($path,$feed){
$fp = fopen ($path, 'w+');
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$feed);
curl_setopt($ch, CURLOPT_FAILONERROR,1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION,1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_TIMEOUT, 50);
curl_setopt($ch, CURLOPT_FILE, $fp);
$retValue = curl_exec($ch);
curl_close($ch);
fclose($fp);
return $retValue;
}
CURLOPT_FILE changes the output from STDOUT to a file, but then CURLOPT_RETURNTRANSFER tells it not to output anything. Use one or the other:
function download_page($path,$feed){
$ch = curl_init($feed);
curl_setopt($ch, CURLOPT_FAILONERROR,1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION,1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_TIMEOUT, 50);
$retValue = curl_exec($ch);
curl_close($ch);
if($retValue === false) {
return false;
} else {
file_put_contents($path, $retValue);
return true;
}
}
$feed = 'https:/www.url/feeds/feed.csv';
$path = "./newfile.csv";
download_page($path,$feed);
Incidentally, this could be done with much less code, though you may have less flexibility to catch 404 errors and whatnot:
function download_page($path,$feed)
{
$result = file_get_contents($feed);
return $result ? file_put_contents($path, $result) : false;
}
I have got an image url from facebook:
https://fbcdn-sphotos-e-a.akamaihd.net/hphotos-ak-prn1/s720x720/156510_443901075651849_1975839315_n.jpg
I need to save this in my local. when i used file_get_contents it gave error failed to open stream. when i open image in the browser it is showing fine. I just understand how to do it.
infact i used curl in the following way and got no response at all
$url = https://fbcdn-sphotos-e-a.akamaihd.net/hphotos-ak-prn1/s720x720/156510_443901085651849_1975839315_n.jpg;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, 0);
$response = curl_exec($ch);
curl_close($ch);
$filename = 'ex'.$src['photo_id'].'.jpg';
$imgRes = imagecreatefromstring($response);
imagejpeg($imgRes, $filename, 70);
header("Content-Type: image/jpg");
imagejpeg($imgRes, NULL, 70);
It's because you are requesting an secure URL and your server probably doesn't support it without configuration. You can either use CURL to request the URL with a valid certificate or just try and request it without SSL:
<?php
$file = 'http://url/to_image.jpg';
$data = file_get_contents($file);
header('Content-type: image/jpg');
echo $data;
You need to tell cURL that you don't wan't to verify the SSL connection.
The following is tested and works.
$url = "https://******";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // ignore SSL verifying
curl_setopt($ch, CURLOPT_HEADER, 0);
$response = curl_exec($ch);
curl_close($ch);
header("Content-Type: image/jpg");
echo $response;
It's most likely that Facebook requires a valid User-Agent string and is denying your request because file_get_contents doesn't send one when accessing remote files.
You could use this:
if( $f = fsockopen($host="fbcdn-sphotos-e-a-.akamaihd.net",80)) {
fputs($f,"GET /hphotos-ak-prn1/........ HTTP/1.0\r\n"
."Host: ".$host."\r\n"
."User-Agent: My Image Downloader\r\n\r\n");
$ret = "";
$headers = true;
while(!feof($f)) {
$line = fgets($f);
if( $headers) {
if( trim($line) == "") $headers = false;
}
else $ret .= $line;
}
fclose($f);
file_put_contents("mylocalfile.png",$ret);
}
I wrote the PHP function below to download files and it works as expected.
However, when I try to download this file:
$url = 'http://javadl.sun.com/webapps/download/GetFile/1.7.0_02-b13/windows-i586/jre-7u2-windows-i586-iftw.exe';
download($url);
... no content is written to the file. And I can't figure out why. The file is created, the call to curl_exec returns true, but the output file remains empty. The file can be downloaded in the browser just fine and the function successfully downloads other files. It's just this file (host?) that I'm having problem with.
Any help is appreciated.
function download($url)
{
$outdir = 'C:/web/www/download/';
// open file for writing in binary mode
if (!file_exists($outdir)) {
if (!mkdir($outdir)) {
echo "Could not create download directory: $outdir.\n";
return false;
}
}
$outfile = $outdir . basename($url);
$fp = fopen($outfile, 'wb');
if ($fp == false) {
echo "Could not open file: $outfile.\n";
return false;
}
// create a new cURL resource
$ch = curl_init();
// The URL to fetch
curl_setopt($ch, CURLOPT_URL, $url);
// The file that the transfer should be written to
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_HEADER, false);
$header = array(
'Connection: keep-alive',
'User-Agent: Mozilla/5.0',
);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
// downloading...
$downloaded = curl_exec($ch);
$error = curl_error($ch);
curl_close($ch);
fclose($fp);
if (!$downloaded) {
echo "Download failed: $error\n";
return false;
} else {
echo "File successfully downloaded\n";
return $outfile;
}
}
That url redirects to another. You need to set CURLOPT_FOLLOWLOCATION to 1 for that to work.
Try Adding;
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
//then after curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($curl, CURLOPT_BINARYTRANSFER, true);
Check some sample: http://www.php.net/manual/en/function.curl-exec.php#84774
I am trying to get a file size of remote file "compiler-latest.zip" (googlecode.com) using cURL without actually downloading it, here is my PHP code:
$url = 'http://closure-compiler.googlecode.com/files/compiler-latest.zip';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_NOBODY, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); // optional
curl_setopt($ch, CURLOPT_MAXREDIRS, 10); // optional
curl_setopt($ch, CURLOPT_TIMEOUT, 60); // optional
$result = curl_exec($ch);
$filesize = curl_getinfo($ch, CURLINFO_CONTENT_LENGTH_DOWNLOAD);
curl_close($ch);
print 'Filesize: ' . $filesize . '<br><br>';
print_r($result);
But, I get "HTTP/1.1 404 Not Found" status with a file size (1379 bytes) of this error 404 document.
So, if I set (CURLOPT_NOBODY, 0) it downloads file and returns its correct file size (currently 3820320 bytes). My question is how to get a correct file size of "compiler-latest.zip" file without downloading it?
IMPORTANT: this code works as expected with any other url outside of googlecode.com.
Use get_headers function:
<?php
$headers = get_headers('http://closure-compiler.googlecode.com/files/compiler-latest.zip');
$content_length = -1;
foreach ($headers as $h)
{
preg_match('/Content-Length: (\d+)/', $h, $m);
if (isset($m[1]))
{
$content_length = (int)$m[1];
break;
}
}
echo $content_length;
And how to get a file size, when content-length missing?