Download a File and Upload it with PHP and AJAX - php

I am developing a web application that uses JQuery AJAX and PHP to upload some data into my database.
One of the fields of the form to be submitted is an URL of a image (any address of the WEB). This image should be downloaded to my FTP server and then its new addrress would be inserted into the database.
How can I download an image from any URL and upload it to my FTP server?
Form:
<form id="form-id" method="post" action="insert.php" charset=utf-8">
<input type="text" name="title" id="title">
<input type="text" name="image-url" id="image-url">
<input type="submit" name="submit" id="submit">
</form>
JavaScript
$("#submit").live("click", function(event){
event.preventDefault();
$.ajax({
type : "POST",
url : "insert.php",
data : {
'title': valueTitle,
'image': valueImage
},
cache : false,
success : function(html) {
if (html == "success") {
//...
} else if (html == "ftp-error") {
//...
} else if (html == "sql-error") {
//...
}
}
});
});
insert.php
$title = $_REQUEST['title'];
$image = $_REQUEST['image'];
$imageInMyServer = downloadImageFromURLAndUploadFTP($image);
function downloadImageFromURLAndUploadFTP($image) {
//that is what I want to know how to do.
}
//sql query with $title and $imageInMyServer
Notes:
The file I want to download is not on my server. It is somewhere else in the Internet and I need to download it to my FTP server
No. I cannot use the first external URL in my SQL Query

Here is a great example on how to do FTP transfers in PHP. As far as downloading the file, you could use wget if you're on linux (using the exec() function).
exec('wget -q ' . $url . ' -0 /path/to/newfile');
Stealing a code snippet from that link I gave you, here is what your function might look like:
function downloadImageFromURLAndUploadFTP($image) {
// in your case it would be some img extension like .jpg, .gif, or .png
// you can check the extension of $image and use that if you want.
$newFile = '/path/to/newfile.ext';
exec('wget -q ' . $image . ' -0 ' . $newFile);
if (file_exists($newFile)) {
// set up connection and login
$connect = ftp_connect($ftpServer);
$login = ftp_login($connect, $ftpUser, $ftpPass);
// check connection
if (!$connect || !$login) {
die('FTP connection has failed!');
} else {
echo "Connected to {$ftpServer}, for user {$ftpUser}";
}
// upload the file
$fileNameOnFTPServer = 'whateverYouWantToNameIt.ext'; // arbitrary extension
$upload = ftp_put($connect, $fileNameOnFTPServer, $newFile, FTP_BINARY);
// check upload status
if (!$upload) {
echo "FTP upload has failed!";
} else {
echo "Uploaded {$image} to {$ftpServer} as {$fileNameOnFTPServer}";
}
ftp_close($connect);
}
}
Note: Sometimes file_exists() doesn't behave the way we intended when the path begins with /. For example /path/to/file might exist but file_exists() will think it doesn't unless you remove the beginning "/". One way to get around that is to check it like this:
file_exists(substr($newFile, 1))
Good luck!

An alternative solution if you do not have exec privileges is to use curl to grab the image, or you could use file_get_contents(), there are many ways, its just personal preference.
Ive put together what your script may look like, im sure you can improve it.
insert.php
<?php
if(isset($_POST['image']) && isset($_POST['title'])){
if(substr($_POST['image'],0,4)=='http'){
$image = curlgetimage($_POST['image']);
$info = pathinfo($_POST['image']);
if(isset($info['extension']) && ($info['extension']=='gif' || $info['extension']=='png' || $info['extension']=='jpg')){
$path='./temp/'.md5($_POST['image']).'.'.$info['extension'];
file_put_contents($path,$image);
if(ftp_put_image($path)===true){
//Do your database stuff, remember to escape..
unlink($path);
echo 'Success';
}else{
echo 'ftp-fail';
}
}else{
echo'File type not allowed';
}
}else{
echo'Must start with http://';
}
}else{
header('Location: http://www.example.com/');
}
function ftp_put_image($file){
if(!file_exists($file)){return false;}
$fp = fopen($file, 'r');
$conn_id = ftp_connect('ftp.yourhost.com'); //change
$login_result = ftp_login($conn_id,'username','password'); //change
$return=(ftp_fput($conn_id, $file, $fp, FTP_BINARY))?true:false;
ftp_close($conn_id);
fclose($fp);
return $return;
}
function curlgetimage($url) {
$header[] = 'Accept: image/gif, image/x-bitmap, image/jpeg, image/pjpeg';
$header[] = 'Connection: Keep-Alive';
$header[] = 'Content-type: application/x-www-form-urlencoded;charset=UTF-8';
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_USERAGENT, 'YourSpiderBot/0.01 (Bla Bla Robot; http://www.example.com; spider#example.com)'); //change
curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
curl_setopt($curl, CURLOPT_HEADER, 0);
curl_setopt($curl, CURLOPT_REFERER, $url);
curl_setopt($curl, CURLOPT_ENCODING, 'gzip,deflate');
curl_setopt($curl, CURLOPT_AUTOREFERER, true);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_TIMEOUT, 60);
$return = curl_exec($curl);
curl_close($curl);
return $return;
}
?>

Related

PHP checking if file exists on webp image not working

So i'm trying to check if there is a webp image format on the url retrieved from get_the_post_thumbnail_url()
This is not working how I would expect though.
Here is the code im working with:
if (!file_exists($thePostThumbUrl))
$thePostThumbUrl = str_replace("_result.webp", "." . $ext, $thePostThumbUrl);
if I echo the thumb url it gets the correct image with a .webp format
echo $thePostThumbUrl . '<br/ >';
Displays:
image url + _result.webp
I know the version of PHP im working with is PHP/5.6.30
Ok so as Akintunde suggested, the file_exists function wont work with the url of the image. So the code needed to be modified to use the server path instead.
This code does the trick:
$ext = pathinfo($thePostThumbUrl, PATHINFO_EXTENSION);
$thePostThumbPath = str_replace("http://localhost", "", $thePostThumbUrl);
if (!file_exists($_SERVER['DOCUMENT_ROOT'] . $thePostThumbPath)) {
$thePostThumbUrl = str_replace("_result.webp", "." . $ext, $thePostThumbUrl);
}
Thansk Akintunde for pointing me in the right direction :)
I wrote a function that checks whether a given image exists in webp format on the server:
function webpExists($img_src){
$env = array("YOUR_LOCAL_ENV", "YOUR_STAGING_ENV", "YOUR_PROD_ENV");
$img_src_webp = str_replace(array(".jpeg", ".png", ".jpg"), ".webp", $img_src);
$img_path = str_replace($env, "", $img_src_webp);
return file_exists($_SERVER['DOCUMENT_ROOT'] . $img_path);
}
You need to use CURL for this case because it's a URL.
Example:
function checkRemoteFile($url)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$url);
// don't download content
curl_setopt($ch, CURLOPT_NOBODY, 1);
curl_setopt($ch, CURLOPT_FAILONERROR, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
if(curl_exec($ch)!==FALSE)
{
return true;
}
else
{
return false;
}
}

retrieve file information from url using php

i am trying to retrieve information of file from the url containing the file. but how can i get the information of file before downloading it to my server.
i need file information like file size,file type etc
i had found the code to validate and download file but how to get information from it before downloading file actually to server
<?php
function is_url_exist($url)
{
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_NOBODY, true);
curl_exec($ch);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if($code == 200)
{
$status = "true";
}
curl_close($ch);
if ( $status == true)
{
$name = "abc.png";
if (file_put_contents("uploads/$name", file_get_contents($url)))
echo "file uploaded";
else
echo "error check upload link";
}
}
$url = "http://theonlytutorials.com/wp-content/uploads/2015/06/blog-logo1.png";
echo is_url_exist($url);
?>
you can get all information of remote file by get_headers function. Try following code to find out type, content length etc.
$url = "http://theonlytutorials.com/wp-content/uploads/2015/06/blog-logo1.png";
$headers = get_headers($url,1);
print_r($headers);
Know more about get_headers click http://php.net/manual/en/function.get-headers.php

LibCURL upload file from C++ to PHP - 411 length required

I'm attempting to write a file to a server from my local machine using LibCURL, C++, and php, and I am running into an error, instead of the form completing, I am getting the error message "411 length required".
I am working from this example
http://curl.haxx.se/libcurl/c/postit2.html
This is my php form which I have verified as working
<!DOCTYPE HTML>
<html>
<head>
</head>
<body>
<form method="post" enctype="multipart/form-data" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">
Enter file: <input type="file" name="sendfile" size="40">
<input type="submit" value="send" name="submit">
</form>
<?php
echo “request method: " . $_SERVER[REQUEST_METHOD];
if( "$_SERVER[REQUEST_METHOD]" == "POST" || "$_SERVER[REQUEST_METHOD]" == "PUT")
{
echo "Success <br>";
if( $_FILES['sendfile']['name'] != "" )
{
$target_dir = "test/";
$target_file = $target_dir . basename($_FILES["sendfile"]["name"]);
if (move_uploaded_file($_FILES["sendfile"]["tmp_name"], $target_file))
{
echo "The file ". basename( $_FILES["sendfile"]["name"]). " has been uploaded.";
}
else
{
echo "Sorry, there was an error uploading your file.";
}
}
else
{
die("No file specified!");
}
}
?>
</body>
</html>
And this is the libcurl code which is pretty faithful to the example apart from the 3 lines in the set upload file section. This is something which I tried based on a different example.
//setup
curl_global_init(CURL_GLOBAL_ALL);
handle = curl_easy_init();
post = NULL;
last = NULL;
header_list = NULL;
uploadFile = NULL;
curl_easy_setopt(handle, CURLOPT_NOPROGRESS, ofGetLogLevel() <= OF_LOG_VERBOSE ? 0 : 1);
curl_easy_setopt(handle, CURLOPT_SSL_VERIFYPEER, true);
curl_easy_setopt(handle, CURLOPT_VERBOSE, ofGetLogLevel() <= OF_LOG_VERBOSE);
curl_easy_setopt(handle, CURLOPT_CAINFO, ofToDataPath("cacert.pem").c_str());
curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, content_writer);
curl_easy_setopt(handle, CURLOPT_WRITEDATA, &content);
curl_easy_setopt(handle, CURLOPT_HEADERFUNCTION, header_writer);
curl_easy_setopt(handle, CURLOPT_WRITEHEADER, &header);
//seturl
curl_easy_setopt(handle, CURLOPT_URL, “link to hosted php file on server”);
//add form field
curl_formadd(&post, &last, CURLFORM_COPYNAME, "sendfile", CURLFORM_FILE, “filepath on my local system”, CURLFORM_END);
//set upload file
FILE* uploadFile = fopen(“filepath on my local system”, "rb");
curl_easy_setopt(handle, CURLOPT_UPLOAD, 1);
curl_easy_setopt(handle, CURLOPT_READDATA, uploadFile);
//perform
CURLcode ret = curl_easy_setopt(handle, CURLOPT_VERBOSE, ofGetLogLevel() <= OF_LOG_VERBOSE);
ret = curl_easy_setopt(handle, CURLOPT_NOPROGRESS, ofGetLogLevel() <= OF_LOG_VERBOSE ? 0 : 1);
ret = curl_easy_setopt(handle, CURLOPT_HTTPPOST, post);
ret = curl_easy_perform(handle);
curl_formfree(post);
post = NULL;
fclose(uploadFile);
uploadFile = NULL;
I have tried adding a header with the string "Content-Length: 0" and "Content-Length: 44000" (the size of the test jpg) but neither change the error.
there are similar questions on here but only one is using c++ which is this one
error 411 Length Required c++, libcurl PUT request
but it doesn't quite fit my situation and doesn't provide any answers either.
Set CURLOPT_INFILESIZE like so:
curl_easy_setopt(handle, CURLOPT_INFILESIZE, 44000);

PHP Get metadata of remote .mp3 file (from URL)

I am trying to get song name / artist name / song length / bitrate etc from a remote .mp3 file such as http://shiro-desu.com/scr/11.mp3 .
I have tried getID3 script but from what i understand it doesn't work for remote files as i got this error: "Remote files are not supported - please copy the file locally first"
Also, this code:
<?php
$tag = id3_get_tag( "http://shiro-desu.com/scr/11.mp3" );
print_r($tag);
?>
did not work either.
"Fatal error: Call to undefined function id3_get_tag() in /home4/shiro/public_html/scr/index.php on line 2"
As you haven't mentioned your error I am considering a common error case undefined function
The error you get (undefined function) means the ID3 extension is not enabled in your PHP configuration:
If you dont have Id3 extension file .Just check here for installation info.
Firstly, I didn’t create this, I’ve just making it easy to understand with a full example.
You can read more of it here, but only because of archive.org.
https://web.archive.org/web/20160106095540/http://designaeon.com/2012/07/read-mp3-tags-without-downloading-it/
To begin, download this library from here: http://getid3.sourceforge.net/
When you open the zip folder, you’ll see ‘getid3’. Save that folder in to your working folder.
Next, create a folder called “temp” in that working folder that the following script is going to be running from.
Basically, what it does is download the first 64k of the file, and then read the metadata from the file.
I enjoy a simple example. I hope this helps.
<?php
require_once("getid3/getid3.php");
$url_media = "http://example.com/myfile.mp3"
$a=getfileinfo($url_media);
echo"<pre>";
echo $a['tags']['id3v2']['album'][0] . "\n";
echo $a['tags']['id3v2']['artist'][0] . "\n";
echo $a['tags']['id3v2']['title'][0] . "\n";
echo $a['tags']['id3v2']['year'][0] . "\n";
echo $a['tags']['id3v2']['year'][0] . "\n";
echo "\n-----------------\n";
//print_r($a['tags']['id3v2']['album']);
echo "-----------------\n";
//print_r($a);
echo"</pre>";
function getfileinfo($remoteFile)
{
$url=$remoteFile;
$uuid=uniqid("designaeon_", true);
$file="temp/".$uuid.".mp3";
$size=0;
$ch = curl_init($remoteFile);
//==============================Get Size==========================//
$contentLength = 'unknown';
$ch1 = curl_init($remoteFile);
curl_setopt($ch1, CURLOPT_NOBODY, true);
curl_setopt($ch1, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch1, CURLOPT_HEADER, true);
curl_setopt($ch1, CURLOPT_FOLLOWLOCATION, true); //not necessary unless the file redirects (like the PHP example we're using here)
$data = curl_exec($ch1);
curl_close($ch1);
if (preg_match('/Content-Length: (\d+)/', $data, $matches)) {
$contentLength = (int)$matches[1];
$size=$contentLength;
}
//==============================Get Size==========================//
if (!$fp = fopen($file, "wb")) {
echo 'Error opening temp file for binary writing';
return false;
} else if (!$urlp = fopen($url, "r")) {
echo 'Error opening URL for reading';
return false;
}
try {
$to_get = 65536; // 64 KB
$chunk_size = 4096; // Haven't bothered to tune this, maybe other values would work better??
$got = 0; $data = null;
// Grab the first 64 KB of the file
while(!feof($urlp) && $got < $to_get) { $data = $data . fgets($urlp, $chunk_size); $got += $chunk_size; } fwrite($fp, $data); // Grab the last 64 KB of the file, if we know how big it is.
if ($size > 0) {
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RESUME_FROM, $size - $to_get);
curl_exec($ch);
}
// Now $fp should be the first and last 64KB of the file!!
#fclose($fp);
#fclose($urlp);
}
catch (Exception $e) {
#fclose($fp);
#fclose($urlp);
echo 'Error transfering file using fopen and cURL !!';
return false;
}
$getID3 = new getID3;
$filename=$file;
$ThisFileInfo = $getID3->analyze($filename);
getid3_lib::CopyTagsToComments($ThisFileInfo);
unlink($file);
return $ThisFileInfo;
}
?>

How do I temporarily store facebook profile picture?

Hey guys i'm trying to build a little app that pulls in the users profile picture, allows them to manipulate the image and then publish the modified image to their profile pictures album (ideally set as their profile pic, but i don't think this is possible???).
The problem I'm having is that the javascript i'm using to alter the image will not work unless the image is local
i.e. <img src="http://profile.ak.fbcdn.net/hprofile-ak-snc4/[some_user_id].jpg" /> will not work, but <img src="img/image.jpg" /> will...
Is there any way of achieving this?
The method I am using to get hold of the user picture is this:
To connect to facebook:
<?php
require_once 'library/facebook.php';
$app_id = "###";
$app_secret = "###";
$facebook = new Facebook(array(
'appId' => $app_id,
'secret' => $app_secret,
'cookie' => true
));
if(is_null($facebook->getUser()))
{
header("Location:{$facebook->getLoginUrl(array('req_perms' => 'user_status,publish_stream,user_photos'))}");
exit;
}
Then to display the image:
<?php
$aResponse = $facebook->api('/me', array(
'fields' => 'picture',
'type' => 'large'
));
echo "<img src='".$aResponse["picture"]."' />";
?>
Many thanks!
Write yourself a proxy image server which which takes the the image you want to manipulate as a query parameter and just outputs the image content. It's a little slower than directly accessing the user's picture, but if you get creative you could cache that image locally to make subsequent loads faster.
a simple way to do this would be something like this:
front end:
<img src="image_server.php?img=<?= urlencode($aResponse['picture']); ?>">
back end:
<?php
if (!empty($_GET['img']))
{
//make sure this is a file on the facebook content delivery network
//and not our /etc/passwd or database connection config, or something
//else completely malicious.
if (preg_match("#^https?://profile\.ak\.fbcdn\.net/#i", $_GET['img']))
{
$img_path = $_GET['img'];
}
else
{
//do something with someone that entered a bad image, probably just
//display a "no image" image.
die('bad user. bad.');
}
readfile($img_path);
exit;
}
else
{
//no image was specified. output an anonymous/no image image.
die('an image file must be specified.');
}
You might want to get a little more complex than that...but that's the basic gist.
note: The php code assumes you have fopen wrappers enabled in your php.ini (so you can include web urls).
Thanks Jim for your response, I had seen someone doing something very similar to that, but again (just my luck) I was having problems with it. Anyway the way I managed to solve it was:
function save_image($inPath,$outPath)
{ //Download images from remote server
$in= fopen($inPath, "rb");
$out= fopen($outPath, "wb");
while ($chunk = fread($in,8192))
{
fwrite($out, $chunk, 8192);
}
fclose($in);
fclose($out);
}
// This is just pulling the user id to use for the filename
$id = $get_id['id'];
save_image($aResponse['picture'],'tmp/'.$id.'.jpg');
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
function curl_redir_exec($ch)
{
static $curl_loops = 0;
static $curl_max_loops = 20;
if ($curl_loops++ >= $curl_max_loops)
{
$curl_loops = 0;
return FALSE;
}
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$data = curl_exec($ch);
#list($header, $data) = #explode("\n\n", $data, 2);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($http_code == 301 || $http_code == 302)
{
$matches = array();
preg_match('/Location:(.*?)\n/', $header, $matches);
$url = #parse_url(trim(array_pop($matches)));
if (!$url)
{
//couldn't process the url to redirect to
$curl_loops = 0;
return $data;
}
$last_url = parse_url(curl_getinfo($ch, CURLINFO_EFFECTIVE_URL));
if (!$url['scheme'])
$url['scheme'] = $last_url['scheme'];
if (!$url['host'])
$url['host'] = $last_url['host'];
if (!$url['path'])
$url['path'] = $last_url['path'];
$new_url = $url['scheme'] . '://' . $url['host'] . $url['path'] . (#$url['query']?'?'.$url['query']:'');
return $new_url;
} else {
$curl_loops=0;
return $data;
}
}
function get_right_url($url) {
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
return curl_redir_exec($curl);
}
$url = 'http://graph.facebook.com/' . $fbid . '/picture?type=large';
$file_handler = fopen('/img/avatar/'.$fbid.'.jpg', 'w');
$curl = curl_init(get_right_url($url));
curl_setopt($curl, CURLOPT_FILE, $file_handler);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_exec($curl);
curl_close($curl);
fclose($file_handler);
// Happy Coding

Categories