Curl caching a downloaded image? - php

I have a script that tails a log file for a song change event. When that happens a Tweet is auto generated and sent to Twitter. Problem is that, I recently updated my script so that it also includes the album art with the Tweet. I am downloading the image using curl, posting the media, then removing the file for the next Tweet. What is throwing me off is that when the image displayed in the Tweet is for the previous song playing and not the current one. I want to know if I download a file using curl, then use php unlink command, would that same image be downloaded again? Here is my code below.
// Analyze prepared tweet for issues with length
$tweeted = ($front . $fixedArtistNow . $hyphen . " " . $fixedTitleNow . $tag);
if (strlen($tweeted) <= 140) {
try {
// $path = ("/home/soundcheck/public_html/images/artwork.png");
// if(unlink($path));
// Grab album art from the song that is currently playing
$fresh = date("y-m-d-G-i-s");
$ch = curl_init('http://soundcheck.xyz:8000/playingart? sid=1?'.$fresh);
var_dump($ch);
$fp = fopen('/home/soundcheck/public_html/images/artwork.png', 'wb');
curl_setopt($fp, CURLOPT_FRESH_CONNECT, TRUE);
curl_setopt($fp, CURLOPT_FORBID_REUSE, TRUE);
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_exec($ch);
curl_close($ch);
fclose($fp);
// copy("/home/soundcheck/public_html/images/artwork.png","/home/soundcheck/public_html/images/album.png");
// $twitter->send($front . $fixedArtistNow . $hyphen . " " . $fixedTitleNow . $tag);
$media1 = $twitter->upload('media/upload', ['media' => '/home/soundcheck/public_html/images/artwork.png']);
// $media2 = $connection->upload('media/upload', ['media' => '/path/to/file/kitten2.jpg']);
$parameters = [
'status' => $tweeted,
'media_ids' => implode(',', [$media1->media_id_string]),
];
$result = $twitter->post('statuses/update', $parameters);
// unlink("/home/soundcheck/public_html/images/artwork.png");
The url I am getting the image from never changes but the image does if that makes any difference. If anyone knows a better way to download the album art, please let me know. Thanks!

Related

What is the best way to serve an image via PHP in Laravel

What is the best way to load images via a controller in laravel
Hey Everyone, I'm working on a function to save all images from an external source, to reduce their size and eventually show them again via a new link. Everything works perfectly, only I asked myself if it was possible to load the images faster from the Laravel application. The moment I load it from the external source it takes 60 milliseconds and when it is loaded from the Laravel application 400 milliseconds.
public function index($id)
{
$filelocation = 'img/';
if (file_exists($filelocation . '' . $id)) {
$im = file_get_contents($filelocation . '' . $id);
header('content-type: image');
echo $im;
} else {
define('WEBSERVICE', 'http://api.resmush.it/ws.php?img=');
$s = 'http://www.example.com/hires/' . $id;
$o = json_decode(file_get_contents(WEBSERVICE . $s));
if (isset($o->error)) {
die('Error');
}
$ch = curl_init($o->dest);
$fp = fopen($filelocation . '' . $id, 'wb');
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_exec($ch);
curl_close($ch);
fclose($fp);
// Load image
$im = file_get_contents($filelocation . '' . $id);
header('content-type: image');
echo $im;
}
Is there a good way to speed up the application, without using a more powerful server? (
All feedback is welcome :)

Best bulk image download practise using curl?

I have a script running for a Laravel 5.4 webapplication that is supposed to download a big amount of images (10k). I'm wondering what the best way to handle this would be. I currently grab the base64_encode() data from the remote image and write it to a local folder with the function file_put_contents(). This works fine but some images can take more than 10 seconds to download/write, image that times a 10 thousand. Fair enough these images are rather big but I would like to see this process happen faster and thus I am asking for advice!
My current process is like this;
I read a JSON file containing all the image links I have to
download.
I convert the JSON data to an array with json_decode() and I loop through all the links with a foreach() loop and let curl handle the rest.
All the relevant parts of the code look like this:
<?php
// Defining the paths for easy access.
$__filePath = public_path() . DIRECTORY_SEPARATOR . "importImages" . DIRECTORY_SEPARATOR . "images" . DIRECTORY_SEPARATOR . "downloadList.json";
$__imagePath = public_path() . DIRECTORY_SEPARATOR . "importImages" . DIRECTORY_SEPARATOR . "images";
// Decode the json array into an array readable by PHP.
$this->imagesToDownloadList = json_decode(file_get_contents($__filePath));
// Let's loop through the image list and try to download
// all of the images that are present within the array.
foreach ($this->imagesToDownloadList as $IAN => $imageData) {
$__imageGetContents = $this->curl_get_contents($imageData->url);
$__imageBase64 = ($__imageGetContents) ? base64_encode($__imageGetContents) : false;
if( !file_put_contents($__imagePath . DIRECTORY_SEPARATOR . $imageData->filename, base64_decode($__imageBase64)) ) {
return false;
}
return true;
}
And the curl_get_contents functions looks like this:
<?php
private function curl_get_contents($url)
{
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
$data = curl_exec($ch);
curl_close($ch);
return $data;
}
I hope someone could englighten me with possible improvements that I could apply on the current way I'm handling this mass-download.

Upload script returning blank data

I have the Uploadify jQuery plugin set up on my site to manage file uploads. Within the onUploadSuccess event, I have this code:
'onUploadSuccess' : function(file, data, response) {
console.log("Upload complete for file " + file.name + ". Script returned: " + data);
}
This is meant to show me whatever the upload script spits out. Now, usually the response is something like this:
Upload complete for file test.jpg. Script returned:
{"status":1,"file":{"id":"v8rwlxj3","name":"test.jpg"}}
The upload script is first accepting the file, then uploading it to Rapidshare using cURL like so:
// Move uploaded file
move_uploaded_file($_FILES['Filedata']['tmp_name'], $targetDir . '/' . $id);
// Get the RapidShare server to upload to
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://api.rapidshare.com/cgi-bin/rsapi.cgi?sub=nextuploadserver');
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
if(!$uploadServer = trim(curl_exec($ch))) {
error('nextuploadserver failed');
}
if(strstr($uploadServer, 'ERROR:')) {
error('nextuploadserver failed');
}
// Upload the file to RapidShare
$uploadID = mt_rand(1000000000, 9999999999);
$url = 'http://rs' . $uploadServer . '.rapidshare.com/cgi-bin/rsapi.cgi?uploadid=' . $uploadID;
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
$postFields = array('sub' => 'upload',
'login' => 'login',
'password' => 'password',
'uploadid' => $uploadID,
'filename' => $_FILES['Filedata']['name'],
'filecontent' => '#' . $targetDir . '/' . $id);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postFields);
if(!$resp = curl_exec($ch)) {
error('upload call failed');
}
when it's uploaded, the upload script spits out a JSON response like so:
// Output
echo json_encode(array('status' => 1, 'file' => array('id' => $id, 'name' => $uploadDetails[1])));
This works fine for smaller files. When I upload my 30MB test file however, I get this response:
Upload complete for file 30mb.txt. Script returned:
At first I thought PHP was hitting the max execution time, but I have this at the top of my script:
set_time_limit(21600); // 6 hours
And besides, I'd see the PHP error being returned. But it's just not returning anything. What could cause this? Thanks.
Are you sure your upload_max_filesize is set to above 30M? That one has caused me some headaches in the past.
PHP may be not hitting time limit, but ajax may be reaching connection timeout while waiting for the response.
Remove uploadid post parameter. Uploadid parameter with resume upload.
Yes nice answer, although it was in comment but helped me.
http://www.uploadify.com/documentation/uploadify/successtimeout/
set successTimeout to some high value. lets say 1 hour.

PHP - Run function for each file in a directory passing two parameters

I should start by saying I have no php experience what so ever, but I know this script can't be that ambitious.
I'm using Wordpress' metaWeblog API to batch the creation of several hundred posts. Each post needs a discrete title, a description, and url's for two images, the latter being custom fields.
I have been successful producing one post by manually entering data into the following file;
<?php // metaWeblog.Post.php
$BLOGURL = "http://path/to/your/wordpress";
$USERNAME = "username";
$PASSWORD = "password";
function get_response($URL, $context) {
if(!function_exists('curl_init')) {
die ("Curl PHP package not installed\n");
}
/*Initializing CURL*/
$curlHandle = curl_init();
/*The URL to be downloaded is set*/
curl_setopt($curlHandle, CURLOPT_URL, $URL);
curl_setopt($curlHandle, CURLOPT_HEADER, false);
curl_setopt($curlHandle, CURLOPT_HTTPHEADER, array("Content-Type: text/xml"));
curl_setopt($curlHandle, CURLOPT_POSTFIELDS, $context);
/*Now execute the CURL, download the URL specified*/
$response = curl_exec($curlHandle);
return $response;
}
function createPost(){
/*The contents of your post*/
$description = "post description";
/*Forming the content of blog post*/
$content['title'] = $postTitle;
$content['description'] = $description;
/*Pass custom fields*/
$content['custom_fields'] = array(
array( 'key' => 'port_thumb_image_url', 'value' => "$imagePath" ),
array( 'key' => 'port_large_image_url', 'value' => "$imagePath" )
);
/*Whether the post has to be published*/
$toPublish = false;//false means post will be draft
$request = xmlrpc_encode_request("metaWeblog.newPost",
array(1,$USERNAME, $PASSWORD, $content, $toPublish));
/*Making the request to wordpress XMLRPC of your blog*/
$xmlresponse = get_response($BLOGURL."/xmlrpc.php", $request);
$postID = xmlrpc_decode($xmlresponse);
echo $postID;
}
?>
In an attempt to keep this short, here is the most basic example of the script that iterates through a directory and is "supposed" to pass the variables $postTitle, and $imagePath and create the posts.
<?php // fileLoop.php
require('path/to/metaWeblog.Post.php');
$folder = 'foldername';
$urlBase = "images/portfolio/$folder";//truncate path to images
if ($handle = opendir("path/to/local/images/portfolio/$folder/")) {
/*Loop through files in truncated directory*/
while (false !== ($file = readdir($handle))) {
$info = pathinfo($file);
$file_name = basename($file,'.'.$info['extension']); // strip file extension
$postTitle = preg_replace("/\.0|\./", " ", $file_name); // Make file name suitable for post title !LEAVE!
echo "<tr><td>$postTitle</td>";
$imagePath = "$urlBase/$file";
echo " <td>$urlBase/$file</td>";
createPost($postTitle, $imagePath);
}
closedir($handle);
}
?>
It's supposed to work like this,
fileLoop.php opens the directory and iterates through each file
for each file in the directory, a suitable post title(postTitle) is created and a url path(imagePath) to the server's file is made
each postTitle and imagePath is passed to the function createPost in metaWeblog.php
metaWeblog.php creates the post and passes back the post id to finish creating the table row for each file in the directory.
I've tried declaring the function in fileLoop.php, I've tried combining the files completely. It either creates the table with all files, or doesn't step through the directory that way. I'm missing something, I know it.
I don't know how to incorporate $POST_ here, or use sessions as I said I'm very new to programming in php.
You need to update your declaration of the createPost() function so that it takes into account the parameters you are attempting to send it.
So it should be something like this:
function createPost($postTitle, $imagePath){
/*The contents of your post*/
$description = "post description";
...
}
More information about PHP function arguments can be found on the associated manual page.
Once this has been remedied you can use CURL debugging to get more information about your external request. To get more information about a CURL request try setting the following options:
/*Initializing CURL*/
$curlHandle = curl_init();
/*The URL to be downloaded is set*/
curl_setopt($curlHandle, CURLOPT_URL, $URL);
curl_setopt($curlHandle, CURLOPT_HEADER, false);
curl_setopt($curlHandle, CURLOPT_HTTPHEADER, array("Content-Type: text/xml"));
curl_setopt($curlHandle, CURLOPT_POSTFIELDS, $context);
curl_setopt($curlHandle, CURLOPT_HEADER, true); // Display headers
curl_setopt($curlHandle, CURLOPT_VERBOSE, true); // Display communication with server
/*Now execute the CURL, download the URL specified*/
$response = curl_exec($curlHandle);
print "<pre>\n";
print_r(curl_getinfo($ch)); // get error info
echo "\n\ncURL error number:" .curl_errno($ch); // print error info
echo "\n\ncURL error:" . curl_error($ch);
print "</pre>\n";
The above debug example code is from eBay's help pages.
It should show you if Wordpress is rejecting the request.

Multiple file uploads with cURL

I'm using cURL to transfer image files from one server to another using PHP. This is my cURL code:
// Transfer the original image and thumbnail to our storage server
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_VERBOSE, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_URL, 'http://' . $server_data['hostname'] . '.localhost/transfer.php');
curl_setopt($ch, CURLOPT_POST, true);
$post = array(
'upload[]' => '#' . $tmp_uploads . $filename,
'upload[]' => '#' . $tmp_uploads . $thumbname,
'salt' => 'q8;EmT(Vx*Aa`fkHX:up^WD^^b#<Lm:Q'
);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
$resp = curl_exec($ch);
This is the code in transfer.php on the server I'm uploading to:
if($_FILES && $_POST['salt'] == 'q8;EmT(Vx*Aa`fkHX:up^WD^^b#<Lm:Q')
{
// Save the files
foreach($_FILES['upload']['error'] as $key => $error)
{
if ($error == UPLOAD_ERR_OK)
{
move_uploaded_file($_FILES['upload']['tmp_name'][$key], $_FILES['upload']['name'][$key]);
}
}
}
All seems to work, apart from one small logic error. Only one file is getting saved on the server I'm transferring to. This is probably because I'm calling both images upload[] in my post fields array, but I don't know how else to do it. I'm trying to mimic doing this:
<input type="file" name="upload[]" />
<input type="file" name="upload[]" />
Anyone know how I can get this to work? Thanks!
here is your error in the curl call...
var_dump($post)
you are clobbering the array entries of your $post array since the key strings are identical...
make this change
$post = array(
'upload[0]' => '#' . $tmp_uploads . $filename,
'upload[1]' => '#' . $tmp_uploads . $thumbname,
'salt' => 'q8;EmT(Vx*Aa`fkHX:up^WD^^b#<Lm:Q'
);
The code itself looks ok, but I don't know about your move() target directory. You're using the raw filename as provided by the client (which is your curl script). You're using the original uploaded filename (as specified in your curl script) as the target of the move, with no overwrite checking and no path data. If the two uploaded files have the same filename, you'll overwrite the first processed image with whichever one got processed second by PHP.
Try putting some debugging around the move() command:
if (!move_uploaded_file($_FILES['upload']['tmp_name'][$key], $_FILES['upload']['name'][$key])) {
echo "Unable to move $key/";
echo $_FILES['upload']['tmp_name'][$key];
echo ' to ';
echo $_FILES['upload']['name'][$key];
}
(I split the echo onto multiple lines for legibility).

Categories