Copy image from URL, change name and save to folder - php

Im about to start on a PHP script to import csv database.
The csv has a column with urls to product images.
What I need to be able to do is get the image, check what type of file it is (jpg, png etc), change the name, save the file to a folder on the server and then insert the file name into the database.
The inserting into the database bit I can do, its the renaming of the file im confused with.
Is it possible to grab the info like you would when uploading a file, for example:
Uploading a file using a file input in a html form
$_FILES['file']['name'];
or
$_FILES['file']['type'];
If downloading a file, could this be possible
$downloaded_image['name'];
or
$downloaded_image['type'];
or is that totally off the mark?
I have never done this before, and most of the answers on stackoverflow don't quite answer my question so was hoping someone could point me in the right direction on how to do this.
EDITED/UPDATED:
Would something like this work to get the file attributes...
$image_id = '123456';
$the_image = file_get_contents($downloaded_image);
$image_name = $the_image['name'];
$image_type = $the_image['type'];
$new_name = $image_id . '.' . $image_type;
$img_path = '/images/';
$save_image = file_put_contents($img_path, $new_name);
if($save_image) {
echo 'image saved';
} else {
echo 'Not Saved';
}
Hopefully im making some sense.
UPDATE: here is the script as it is (still needs tidying up)
define('CSV_PATH','E:/xampp/htdocs/aff/csv-import/');
// path where your CSV file is located
$csv_file = CSV_PATH . "infotuts.csv"; // Name of your CSV file
$csvfile = fopen($csv_file, 'r');
$theData = fgets($csvfile);
$i = 0;
while (!feof($csvfile)) {
$csv_data[] = fgets($csvfile, 1024);
$csv_array = explode(",", $csv_data[$i]);
$insert_csv = array();
$insert_csv['test_id'] = $csv_array[0];
// $insert_csv['test_aw_id'] = $csv_array[1];
// $insert_csv['test_name'] = $csv_array[2];
$image_id = $csv_array[1];
$download_image = $csv_array[2];
// Store the original filename
$original_name = basename($download_image);
// Original extension by string manipulation
$original_extension = substr($original_name, strrpos($original_name, '.')); // ".jpg"
// An array to match mime types from finfo_file() with extensions
// Use of finfo_file() is recommended if you can't trust the input
// filename's extension
$types = array('image/jpeg' => '.jpg','image/png' => '.png','image/gif' => '.gif');
// Get the file and save it
$img = file_get_contents($download_image);
$stored_name = 'images/' . $image_id . $original_extension;
if ($img) {
file_put_contents($stored_name);
// Get the filesize if needed
$size = filesize($stored_name);
// If you don't care about validating the mime type, skip all of this...
// Check the file information
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mimetype = finfo_file($finfo, $stored_name);
// Lookup the type in your array to get the extension
if (isset($types[$mimetype])) {
// if the reported type doesn't match the original extension, rename the file
if ($types[$mimetype] != $original_extension) {
rename($stored_name, 'images/' . $image_id . $types[$mimetype]);
}
}
else {
// unknown type, handle accordingly...
}
finfo_close($finfo);
$query = "INSERT INTO test(test_id, test_aw_id, test_name) VALUES ('', '$image_id', '$stored_name')";
$n=mysqli_query($con, $query);
$i++;
}
else {
echo 'Could not get file';
}
}
fclose($csvfile);

By retrieving the file with file_get_contents(), you won't get any particularly useful information about its format. It carries no metadata similar to that found in $_FILES for upload.
If the image URLs are expected to be a full filename with an extension, and you trust the extension to be correct, you may use that as your type. However, finfo_file() with the FILEINFO_MIME_TYPE option will probe the file to return its mime type, as in image/jpeg or image/png.
So your workflow will be to:
Retrieve the image with file_get_contents()
Save it to your local filesystem with its new name
Call finfo_file() to retrieve its mime type
Update your database with the desired details.
Example:
// Assume this URL for $download_image from your CSV
$download_image = 'http://example.com/images/img1.jpg';
$image_id = 12345;
// Store the original filename
$original_name = basename($download_image); // "img1.jpg"
// Original extension by string manipulation
$original_extension = substr($original_name, strrpos($original_name, '.')); // ".jpg"
// An array to match mime types from finfo_file() with extensions
// Use of finfo_file() is recommended if you can't trust the input
// filename's extension
$types = array(
'image/jpeg' => '.jpg',
'image/png' => '.png',
'image/gif' => '.gif'
// Other types as needed...
);
// Get the file and save it
$img = file_get_contents($download_image);
$stored_name = 'images/' . $image_id . $original_extension;
if ($img) {
file_put_contents($stored_name, $img);
// Get the filesize if needed
$size = filesize($stored_name);
// If you don't care about validating the mime type, skip all of this...
// Check the file information
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mimetype = finfo_file($finfo, $stored_name);
// Lookup the type in your array to get the extension
if (isset($types[$mimetype])) {
// if the reported type doesn't match the original extension, rename the file
if ($types[$mimetype] != $original_extension) {
rename($stored_name, 'images/' . $image_id . $types[$mimetype]);
}
}
else {
// unknown type, handle accordingly...
}
finfo_close($finfo);
// Now save all the extra info you retrieved into your database however you normally would
// $mimetype, $original_name, $original_extension, $filesize
}
else {
// Error, couldn't get file
}
If you want to get the mimetype string from the extension you already have, and aren't validating the type with finfo, you can flip the $types to swap keys with values.
if (in_array($original_extension), $types) {
$mimetype = array_flip($types)[$original_extension];
}

<?php
include_once('includes/functions.php');
define('CSV_PATH','E:/xampp/htdocs/aff/csv-import/');
$csv_file = CSV_PATH . "infotuts.csv";
$csvfile = fopen($csv_file, 'r');
$theData = fgets($csvfile);
$i = 0;
while (!feof($csvfile)) {
$csv_data[] = fgets($csvfile, 1024);
$csv_array = explode(",", $csv_data[$i]);
$insert_csv = array();
$insert_csv['test_id'] = $csv_array[0];
$insert_csv['test_aw_id'] = $csv_array[1];
$insert_csv['test_name'] = $csv_array[2];
$image_id = $insert_csv['test_aw_id'];
$download_image = $insert_csv['test_name'];
$original_name = basename($download_image);
$original_extension = substr($original_name, strrpos($original_name, '.')); // ".jpg"
$types = array('image/jpeg' => '.jpg','image/png' => '.png','image/gif' => '.gif');
$img = file_get_contents($download_image);
$stored_name = $image_id . $original_extension;
$stored_name = trim($stored_name);
if ($img) {
file_put_contents($stored_name, $img);
//$size = filesize($stored_name);
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mimetype = finfo_file($finfo, $stored_name);
if (isset($types[$mimetype])) {
if ($types[$mimetype] != $original_extension) {
rename($stored_name, 'E:/xampp/htdocs/aff/images/products/' . $stored_name);
}
}
else {
}
finfo_close($finfo);
$query = "INSERT INTO test(test_id, test_aw_id, test_name) VALUES ('', '$image_id', '$stored_name')";
$n=mysqli_query($con, $query);
$i++;
}
else {
echo 'Could not get file';
}
}
fclose($csvfile);
echo "File data successfully imported to database!!";
mysqli_close($con);
?>

Related

uncaught exception: could not open file

so i'm trying to upload to uploadcare cdn and i get this error: Uncaught Exception: couldn't open file "ce3577f708f527ff570e0d21acb39c62.jpg"
$description = $_POST['uploaddesc'];
list($width,$height) = getimagesize($_FILES['uploadimage']['tmp_name']);
$extensions = array('image/jpeg','image/jpg','image/gif', 'image/png', 'image/tiff');
$move = 'uploads/';
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$extension = pathinfo($_FILES['uploadimage']['name']);
if(!$_FILES['uploadimage']['tmp_name']){
$errors[]="Please choose an image";
}
if(empty($description)){
$errors[]='Please choose a description for the image';
}
//IF IMAGE IS UPLOADED..
if($_FILES['uploadimage']['tmp_name']){
$mime = finfo_file($finfo, $_FILES['uploadimage']['tmp_name']);
// IF MIME FAILES OR GETIMAGESIZE IS NULL (meaning its no an image)
if(!getimagesize($_FILES['uploadimage']['tmp_name']) && !in_array($_FILES['uploadimage']['tmp_name'],$mime)){
$errors[]='Please choose an image';
unset($_FILES['uploadimage']['tmp_name']);
}
if(empty($errors)){
$randString = md5(time()); //encode the timestamp - returns a 32 chars long string
$fileName = $_FILES["uploadimage"]["name"]; //the original file name
$splitName = explode(".", $fileName); //split the file name by the dot
$fileExt = end($splitName); //get the file extension
$newFileName = strtolower($randString.'.'.$fileExt); //join file name and ext.
if(move_uploaded_file($_FILES['uploadimage']['tmp_name'], $move . $newFileName)){
$description = $_POST['uploaddesc'];
$user->insertArt($description, 'uploads/' . $newFileName, $user->getUsername($_SESSION['username']));
$file = $api->uploader->fromPath('uploads/' . $newFileName);
$file->store();
//throw new ErrorException('MEMORY USAGE ' . memory_get_peak_usage());
}
}
}
i have fixed it. i had to use realpath('uploads/' . $newfilename);

Saving Multiple File path to mysql using PHP

Good Day. I have a php script that move multiple file in my directory..
$filepath = 'uploads/';
if (isset($_FILES['file'])) {
$file_id = $_POST['file_id'];
$count = 0;
foreach($_FILES['file']['tmp_name'] as $k => $tmp_name){
$name = $_FILES['file']['name'][$k];
$size = $_FILES['file']['size'][$k];
if (strlen($name)) {
$extension = substr($name, strrpos($name, '.')+1);
if (in_array(strtolower($extension), $file_formats)) { // check it if it's a valid format or not
if ($size < (2048 * 1024)) { // check it if it's bigger than 2 mb or no
$filename = uniqid()."-00000-". $name;=
$tmp = $_FILES['file']['tmp_name'][$k];
if (move_uploaded_file($tmp_name, $filepath . $filename)) {
$id = $file_id;
$file_path_array = array();
$files_path = $filepath . $filename;
$file_extension = $extension;
foreach($file_name as $k_file_path => $v_file_path){
$file_path_array[] = $v_file_path;
}
foreach($file_extension as $k_file_extension){
$file_extension_array[] = $v_file_extension;
}
$file_path = json_encode($files_path);
$file_name = str_replace("\/", "/",$file_path);
var_dump($file_name);
$update = $mysqli->query("UPDATE detail SET file_path='$file_name' WHERE id='$id'");
} else {
echo "Could not move the file.";
}
} else {
echo "Your file is more than 2MB.";
}
} else {
echo "Invalid file format PLEASE CHECK YOU FILE EXTENSION.";
}
} else {
echo "Please select FILE";
}
}
exit();
}
this is my php script that move file to 'uploads/' directory and i want to save the path to my database. i try to dump the $file_name and this is my example path how to save that to my database.. ? any suggestions ?
NOTE: i already move the file to uploads/ directory and i only want to save the path to my database
string(46) "uploads/5638067602b48-00000-samplePDF.pdf"
string(46) "uploads/5638067602dee-00000-samplePDF1.pdf"
string(46) "uploads/5638067602f8d-00000-samplePDF2.pdf"
if you must store them in one field..
inside the loop
$file_name_for_db[]=$file_name;
outside the loop:
$update = $mysqli->query("UPDATE detail SET file_path='".json_encode($file_name_for_db)."' WHERE id='$id'");
there is serialize() instead of json_encode() if you prefer

How to check the file type of the file upload in HTML form?

Here is the file upload code. It works in such a way that it accepts all the image extensions. But it needs to validate the file type (video, word doc etc). I need it to only upload images. For an example what happens now is that when I select a word document and submit my form, it shows a bunch of errors, inserts the record but not the file. What should happen is that, if the file is anything other than an image, it should not let the user insert the record. Should get an error message saying to check the file type when the form is submitted. Please assist me in achieving this.
if( isset($_FILES['img']) )
{
//resizing the image
$image = new SimpleImage();
$image->load($_FILES['img']['tmp_name']);
$image->resizeToHeight(180);
$info = pathinfo($_FILES['img']['name']);
$file = 'uploads/' . basename($_FILES['img']['name'],'.'.$info['extension']) . '.png';
if ($image->save($file))
{
if($fp = fopen($file , 'rb'))
{
$data = fread($fp, filesize($file));
//encoding the the image only to text so can be stored in DB
$data = base64_encode($data);
fclose($fp);
}
}
else
{
$error = '<p id="failed">Invalid Image</p>';
}
You need to check MIME type on the image, something like that:
if (isset($_FILES['img'])) {
$file = $_FILES['img'];
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mime = finfo_file($finfo, $file['tmp_name']);
finfo_close($finfo);
if (strpos($mime, 'image') === false) {
die('The submitted file is not an image!');
}
// Uploading code..
}
If mime string has 'image' in it, then it's image. Hope that will help.
In older PHP versions you can use mime_content_type. However if you have PHP > 5.3 you should use the finfo_* functions
You should also check is_uploaded_file() rather than isset()
if( is_uploaded_file( $_FILES['img']['tmp_name'] ) ) {
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$type = finfo_file( $_FILES['img']['tmp_name'] );
if( $type == 'image/gif' ) { // for example
// do stuff
}
}

file rename while uploading

I have a problem here im trying to upload a file
first time it is moving the filename from temp it its respective directory,
but again i try ot upload the aa different file with the same name it should rename the
first time uploaded file
with date_somefilename.csv and give the filename to its original state
for example a file test.csv ,im uploading it for first time it will upload to
corresponding directory as
test.csv,when i upload a different csv file with same name test.csv
I need to get the
test.csv (latest uploaded file)
06222012130209_test.csv(First time uploaded file)
The code is below
$place_file = "$path/$upload_to/$file_name";
if (!file_exists('uploads/'.$upload_to.'/'.$file_name))
{
move_uploaded_file($tmp, $place_file);
}else{
move_uploaded_file($tmp, $place_file);
$arr1 = explode('.csv',$file_name);
$todays_date = date("mdYHis");
$new_filename = $todays_date.'_'.$arr1[0].'.csv';
echo $str_cmd = "mv " . 'uploads/'.$upload_to.'/'.$file_name . " uploads/$upload_to/$new_filename";
system($str_cmd, $retval);
}
See comments in code.
$place_file = "$path/$upload_to/$file_name";
if (!file_exists($place_file)) {
move_uploaded_file($tmp, $place_file);
} else {
// first rename
$pathinfo = pathinfo($place_file);
$todays_date = date("mdYHis");
$new_filename = $pathinfo['dirname'].DIRECTORY_SEPARATOR.$todays_date.'_'.$pathinfo['basename'];
rename($place_file, $new_filename)
// and then move, not vice versa
move_uploaded_file($tmp, $place_file);
}
DIRECTORY_SEPARATOR is php constant. Value is '/' or '\', depending of operation system.
pathinfo() is php function, that return information about path: dirname, basename, extension, filename.
What about...
$place_file = "$path/$upload_to/$file_name";
if (file_exists($place_file)) {
$place_file = date("mdYHis")."_".$file_name;
}
if (!move_uploaded_file($tmp, $place_file)) {
echo "Could not move file";
exit;
}
I would not add a date to the file if it already exists. Instead I would just add a number to the end of it. Keep it simple.
$counter = 0;
do {
// destination path path
$destination = $path.'/'.$upload_to.'/';
// get extension
$file_ext = end(explode('.', $file_name));
// add file_name without extension
if (strlen($file_ext))
$destination .= substr($file_name, 0, strlen($file_name)-strlen($file_ext)-1);
// add counter
if ($counter)
$destination .= '_'.$counter;
// add extension
if (strlen($file_ext))
$destination .= $file_ext;
$counter++;
while (file_exists($destination));
// move file
move_uploaded_file($tmp, $destination);
$target = "uploads/$upload_to/$file_name";
if (file_exists($target)) {
$pathinfo = pathinfo($target);
$newName = "$pathinfo[dirname]/" . date('mdYHis') . "_$pathinfo[filename].$pathinfo[extension]";
rename($target, $newName);
}
move_uploaded_file($tmp, $target);
Beware though: Security threats with uploads.
how about something like this?
<?php
$tmp = '/tmp/foo'; // whatever you got out of $_FILES
$desitnation = '/tmp/bar.xyz'; // wherever you want that file to be saved
if (file_exists($desitnation)) {
$file = basename($destination)
$dot = strrpos($file, '.');
// rename existing file to contain its creation time
// "/temp/bar.xyz" -> "/temp/bar.2012-12-12-12-12-12.xyz"
$_destination = dirname($destination) . '/'
. substr($file, 0, $dot + 1)
. date('Y-m-d-H-i-s', filectime($destination))
. substr($file, $dot);
rename($destination, $_destination);
}
move_uploaded_file($tmp, $destination);

how do i send a timestamped image name to mysql with PHP

Below I have included my code that uploads multiple images to a folder and the path to mysql. I am brand new so please excuse me for such a silly question but I can not figure where to start with sending this timestamp or $fileName value to mysql.
<?php
require_once('storescripts/connect.php');
mysql_select_db($database_phpimage,$phpimage);
$uploadDir = 'upload/';
if(isset($_POST['upload']))
{
foreach ($_FILES as $file)
{
$fileName = $file['name'];
$tmpName = $file['tmp_name'];
$fileSize = $file['size'];
$fileType = $file['type'];
if ($fileName != ""){
$filePath = $uploadDir;
$fileName = str_replace(" ", "_", $fileName);
//Split the name into the base name and extension
$pathInfo = pathinfo($fileName);
$fileName_base = $pathInfo['fileName'];
$fileName_ext = $pathInfo['extension'];
//now we re-assemble the file name, sticking the output of uniqid into it
//and keep doing this in a loop until we generate a name that
//does not already exist (most likely we will get that first try)
do {
$fileName = $fileName_base . uniqid() . '.' . $fileName_ext;
} while (file_exists($filePath.$fileName));
$result = move_uploaded_file($tmpName, $filePath.$fileName);
}
if(!get_magic_quotes_gpc())
{
$fileName = addslashes($fileName);
$filePath = addslashes($filePath);
}
$fileinsert[]=$filePath;
}
$cat=$_POST['cat'];//this is the category the product is stored in
$about=$_POST['about'];//this is some general information about the item
$price=$_POST['price'];//the price of the item
$item=$_POST['item'];//the name of the item
$name1=basename($_FILES['image01'][$fileName]);//the file name of the first actual jpg
$name2=basename($_FILES['image02'][$fileName]);//the file name of the sencond actual jpg
$name3=basename($_FILES['image03'][$fileName]);//the file name of the third actual jpg
$name4=basename($_FILES['image04'][$fileName]);//the file name of the fourth actual jpg
$query = "INSERT INTO image (mid, cid, about, price, item, name1, name2, name3, name4) ".
"VALUES ('','$cat','$about','$price','$item','$name1','$name2','$name3','$name4')";
mysql_query($query) or die('Error, query failed : ' . mysql_error()); }
?>
If I understand your question correctly, you need to change:
$fileinsert[]=$filePath;
to:
$fileinsert = array(); // initialize the variable before the loop
...
$fileinsert[]=$filePath.$fileName; // or just $fileName if you don't need the path in the DB
and then you need to change:
$name1=basename($_FILES['image01'][$fileName]);//the file name of the first actual jpg
$name2=basename($_FILES['image02'][$fileName]);//the file name of the sencond actual jpg
$name3=basename($_FILES['image03'][$fileName]);//the file name of the third actual jpg
$name4=basename($_FILES['image04'][$fileName]);//the file name of the fourth actual jpg
to:
$name1=$fileinsert[0];
$name2=$fileinsert[1];
$name3=$fileinsert[2];
$name4=$fileinsert[3];
Something like that should do it.

Categories