Suppose there are 2 same images in different names. I want to upload these images & put them in different folder. Suppose, img1.jpg & a-img1.jpg are the images. Now img1.jpg will go on "files/images/" location & a-img1.jpg will go on "files/a-images/" location. I've successfully manage to upload images but it'll only go to one destination folder. This is my code,
$upload_errors = 0;
$images= $_FILES['img'];
$img_id = get_new_image_id();
$image_ok = true;
$queries = array();
$allowed_exts = array('jpg', 'png', 'jpeg', 'gif');
foreach ($images['tmp_name'] as $key => $val ) {
$fileName = $images['name'][$key];
$fileSize = $images['size'][$key];
$fileSize = round($fileSize/1024);
$fileTemp = $images['tmp_name'][$key];
$path_parts = pathinfo($fileName);
$fileExt = $path_parts['extension'];
$fileExt = strtolower($fileExt);
if($fileSize > 2*1024){
$image_ok = false;
}
if(!in_array($fileExt, $allowed_exts)){
$image_ok = false;
}
if($image_ok){
$upload_link = "files/images/".$img_id.".".$fileExt;
$tupload_link = "files/a-images/".$img_id.".".$fileExt;
move_uploaded_file($fileTemp, $upload_link);
move_uploaded_file($fileTemp, $tupload_link);
$img_id++;
}else{
$upload_errors++;
}
Is there any way to identify an image file like "a-img1.jpg"? I need this help badly. Tnx in advance!
Since you already moved the file a second move from the same source won't work. Maybe you should copy the file the second time.
You can use this function to see if the string starts with "a-":
function startsWith($haystack, $needle){
return strpos($haystack, $needle) === 0;
}
So you would do something like:
if(startsWith($img_id, "a-")){
$upload_link = "files/a-images/".$img_id.".".$fileExt;
}else{
$upload_link = "files/images/".$img_id.".".$fileExt;
}
move_uploaded_file($fileTemp, $upload_link);
Related
I got a task where I need to upload the same file name with numbers. For example if I upload file1 with the title "cv.pdf" then second file should be named as "cv.pdf(1)",the next one should be "cv.pdf(2)" and so on.
I have tried many ways but still not working out. Can some please help me out to meet the desired objective. This is my
upload.php
<?php
$json = array();
if(!empty($_FILES['upl_file'])){
$dir = "./uploads/";
$allowTypes = array('jpg', 'png', 'jpeg', 'gif', 'pdf', 'doc', 'docx');
$fileName = basename($_FILES['upl_file']['name']);
$filePath = $dir.$fileName;
$actual_name = pathinfo($filePath,PATHINFO_FILENAME);
$original_name = $actual_name;
$extension = pathinfo($filePath, PATHINFO_EXTENSION);
$i = 1;
while(file_exists("./uploads/".$actual_name.".".$extension))
{
$actual_name = (string)$original_name.$i;
$name = $actual_name.".".$extension;
$i++;
}
if(in_array($extension, $allowTypes)){
// Upload file to the server
if(move_uploaded_file($_FILES['upl_file']['tmp_name'], $filePath)){
$json = 'success';
} else {
$json = 'failed';
}
}
}
header('Content-Type: application/json');
echo json_encode($json);
?>
I think glob function is your savior here.
Istead of:
$i = 1;
while(file_exists("./uploads/".$actual_name.".".$extension))
{
$actual_name = (string)$original_name.$i;
$name = $actual_name.".".$extension;
$i++;
}
You should use:
$count = count(glob("./uploads/".$actual_name."*.".$extension));
//Check the * after the name
//EDIT: Before add the count, check if its not zero(0)
$actual_name = "{$name}".( $count > 0 ? "({$count})" : "").".{$extension}";
And last, but not least, you should change the final name of the file:
if(move_uploaded_file($_FILES['upl_file']['tmp_name'], $filePath))
//filePath has the old name
if(move_uploaded_file($_FILES['upl_file']['tmp_name'], $dir.$actual_name))
//newPath with count in the name
I'm creating an upload form that when uploading files will check to see if a file with the same name already exists in the directory. If a file with the same name is found, the script should increment the file by appending the file name with a number such as test1.txt test2.txt and so on until a match is not found. This is what I have come up with so far but wanted to see if there is a different approach I should take.
Also note, my filenames are already cleaned before they enter this part of the script so my filename and extension functions are simplified.
function filename($file){
return substr($file,0,strrpos($file,'.'));
}
function extension($file){
return strtolower(substr(strrchr($file,'.'),1));
}
$new_file = 'test.txt';
$dir = 'files';
$files = scandir($dir);
$exclude = array('.','..');
foreach($files as $file){
if(!in_array($file,$exclude)){
$file_array[] = $file;
}
}
$i = 1;
while(in_array($new_file,$file_array)){
$filename = filename($new_file);
$extension = extension($new_file);
if($i>1){
$num = strlen($filename);
$filename = substr($filename,0,-1);
$new_file = $filename.$i.'.'.$extension;
} else {
$new_file = $filename.$i.'.'.$extension;
}
echo $new_file.'<br>';
echo $i.'<br>';
$i++;
}
echo $new_file;
The file name is known but the file extension is unknown. The images in thier folders do have an extension but in the database their names do not.
Example:
$ImagePath = "../images/2015/03/06/"; (Folders are based on date)
$ImageName = "lake-sunset_3";
Does not work - $Ext is empty:
$Ext = (new SplFileInfo($ImagePath))->getExtension();
echo $Ext;
Does not work either - $Ext is empty:
$Ext = (new SplFileInfo($ImagePath.$ImageName))->getExtension();
echo $Ext;
Does not work either - $Ext is still empty:
$Ext = (new SplFileInfo($ImagePath,$ImageName))->getExtension();
echo $Ext;
$Ext should produce ".jpg" or ".jpeg" or ".png" etc.
So my question is simple: What am I doing wrong?
Now, this is a bit of an ugly solution but it should work. Make sure that all your files have unique names else you'll have several of the same file, which could lead to your program obtaining the wrong one.
<?php
$dir = scandir($imagePath);
$length = strlen($ImageName);
$true_filename = '';
foreach ($dir as $k => $filename) {
$path = pathinfo($filename);
if ($ImageName === $path['filename']) {
break;
}
}
$Ext = $path['extension'];
?>
Maybe this might help you (another brute and ugly solution)-
$dir = '/path/to/your/dir';
$found = array();
$filename = 'your_desired_file';
$files = scandir($dir);
if( !empty( $files ) ){
foreach( $files as $file ){
if( $file == '.' || $file == '..' || $file == '' ){
continue;
}
$info = pathinfo( $file );
if( $info['filename'] == $filename ){
$found = $info;
break;
}
}
}
// if file name is matched, $found variable will contain the path, basename, filename and the extension of the file you are looking for
EDIT
If you just want the uri of your image then you need to take care of 2 things. First directory path and directory uri are not the same thing. If you need to work with file then you must use directory path. And to serve static files such as images then you must use directory uri. That means if you need to check files exists or what then you must use /absolute/path/to/your/image and in case of image [site_uri]/path/to/your/image/filename. See the differences? The $found variable form the example above is an array-
$found = array(
'dirname' => 'path/to/your/file',
'basename' => 'yourfilename.extension',
'filename' => 'yourfilename',
'extension' => 'fileextension'
);
// to retrieve the uri from the path.. if you use a CMS then you don't need to worry about that, just get the uri of that directory.
function path2url( $file, $Protocol='http://' ) {
return $Protocol.$_SERVER['HTTP_HOST'].str_replace($_SERVER['DOCUMENT_ROOT'], '', $file);
}
$image_url = path2url( $found['dirname'] . $found['basename'] ); // you should get the correct image url at this moment.
You are calling a file named lake-sunset_3. It has no extension.
SplFileInfo::getExtension() is not designed to do what you are requesting it to do.
From the php site:
Returns a string containing the file extension, or an empty string if the file has no extension.
http://php.net/manual/en/splfileinfo.getextension.php
Instead you can do something like this:
$path = $_FILES['image']['name'];
$ext = pathinfo($path, PATHINFO_EXTENSION);
getExtension() only returns the extension from the given path, which in your case of course doesn't have one.
In general, this is not possible. What if there is a file lake-sunset_3.jpg and a file lake-sunset_3.png?
The only thing you can do is scan the directory and look for a file with that name but any extension.
You're trying to call an incomplete path. You could try Digit's hack of looking through the directory for for a file that matches the name, or you could try looking for the file by adding the extensions to it, ie:
$basePath = $ImagePath . $ImageName;
if(file_exists($basePath . '.jpg'))
$Ext = '.jpg';
else if(file_exists($basePath . '.gif'))
$Ext = '.gif';
else if(file_exists($basePath . 'png'))
$Ext = '.png';
else
$Ext = false;
Ugly hacks aside, the question begging to be asked is why are you storing them without the extensions? It would be easier to strip off the extension if you need to than it is try and find the file without the extension
l have used the function below but its allowing even pdf to be uploaded
and its not checking if its an image
function image_allowed($file_extn) {
$allowed = array('jpg','jpeg','gif','png');
$file_name = $_FILES['image']['image_name'];
$file_extn = strtolower(end(explode('.', $file_name)));
$file_temp = $_FILES['image']['tmp_name'];
if (in_array($allowed,$file_extn )=== true){
return true;
}else {
return false;
}
and l checked using the code below and l dont know were lam getting it wrong
if (image_allowed($_POST['image'])=== true) {
$errors[] = ' images only are allowed.';
and l would love to know any checks that l might have ommited here
While comparing extensions might do the trick, it's not very safe as it easy to fake an extension. I would advise to check the mime types of the files.
Option 1 - using finfo
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$file_type = finfo_file($finfo, "image.gif");
finfo_close($finfo);
Output for this case: image/gif
Just remember to change your $allowed array accordingly.
You can see a list of possible mime types for images at wikipedia.
Option 2 - Using exif-imagetype
exif_imagetype('image.gif')
Just notice that in that case your $allowed array should contain constants that represent possible return values. (For further information look at the manual - link above)
You can check your image type using pathinfo (http://php.net/manual/en/function.pathinfo.php):
$path_parts = pathinfo('/your/image/path/');
echo $path_parts['extension']; // Your extension...
In your function code:
function image_allowed($imagePath) {
$allowed = array('jpg','jpeg','gif','png');
$myExtension = pathinfo($imagePath);
if(in_array($myExtension['extension'], $allowed)
return true;
else
return false;
}
You need to use like this:
function image_allowed() {
$allowed = array('jpg','jpeg','gif','png');
$file_name = $_FILES['image']['name'];
$file_extn = strtolower(end(explode('.', $file_name)));
$file_temp = $_FILES['image']['tmp_name'];
if (in_array($file_extn,$allowed)=== true){
return true;
}
return false;
}
if (image_allowed()=== false) {
$errors[] = ' images only are allowed.';
}else{
//save image or something else
}
How can I separate multiple uploaded files ($new_file_name) out of foreach loop for sql query process? How to assign each files to its variable?
// manipulate uploaded images
if(isset($_FILES['files'])){
foreach($_FILES['files']['tmp_name'] as $key => $tmp_name){
$file_name = $key.'_'.$_FILES['files']['name'][$key];
$file_size = $_FILES['files']['size'][$key];
$file_tmp = $_FILES['files']['tmp_name'][$key];
$file_type = $_FILES['files']['type'][$key];
//explode fine name and extension
$ext_x = explode('.', $_FILES['files']['name'][$key]);
$ext = strtolower(end($ext_x));
$file_name = str_replace('.'.$ext, '', $_FILES['files']['name'][$key]);
//new file name
$output_dir = '../items/'.$list_id;
$new_file_name = rand(1, 999999).'.'.$ext;
$pathfile = $output_dir.'/'.$new_file_name;
// create directory if does not exist
if(is_dir($output_dir) == false){
mkdir($output_dir, 0700);
}
if(is_dir($pathfile) == false){
if(move_uploaded_file($file_tmp, $pathfile)){
//resize original image
WideImage::load($pathfile)->resize(300, 400)->saveToFile($pathfile);
//generate thumbnail
$split = explode('.', $new_file_name);
$thumb = $split[0].'_t.'.$split[1];
WideImage::load($pathfile)->resize(70, 70)->saveToFile($output_dir.'/'.$thumb);
}
}
}
}
//here I needed to get each of the uploaded images to update database (max 3 images)
//how to explode above $new_file_name into variable here?
$new_file_name1 = $new_file_name[0]; //and so on...
$q = $mysqli->query("UPDATE `listing` SET image1='".$new_file_name1."', image2='".$new_file_name2."', image3='".$new_file_name3."', thumbnail='".$thumb1."', WHERE list_id='".$list_id."' AND user_id='".$user_id."'") or die($mysqli->error);
I can get each of the file by
$var0 = $_FILES['files']['name'][0];
$var1 = $_FILES['files']['name'][1];
$var2 = $_FILES['files']['name'][2];
but I can't
$var0 = $new_file_name[0];
$var1 = $new_file_name[1];
$var2 = $new_file_name[2];
Thanks for advise!
Use this to set the name:
$new_file_name[] = rand(1, 999999).'.'.$ext;
and inside the for loop use:
end($new_file_name)
for the current file. E.g:
$pathfile = $output_dir.'/'.end($new_file_name);
The problem you are having is because in every iteration through the loop you setup the $new_file_name to a new random string. By using $new_file_name[] you are adding an element to $new_file_name which is then becoming an array. Using the end() functions returns the last element of the array so in the current iteration of the loop it will return the last added random string which corresponds to your current file;
EDIT:
// manipulate uploaded images
if(isset($_FILES['files'])){
foreach($_FILES['files']['tmp_name'] as $key => $tmp_name){
$file_name = $key.'_'.$_FILES['files']['name'][$key];
$file_size = $_FILES['files']['size'][$key];
$file_tmp = $_FILES['files']['tmp_name'][$key];
$file_type = $_FILES['files']['type'][$key];
//explode fine name and extension
$ext_x = explode('.', $_FILES['files']['name'][$key]);
$ext = strtolower(end($ext_x));
$file_name = str_replace('.'.$ext, '', $_FILES['files']['name'][$key]);
//new file name
$output_dir = '../items/'.$list_id;
$new_file_name[] = rand(1, 999999).'.'.$ext;
$pathfile = $output_dir.'/'.end($new_file_name);
// create directory if does not exist
if(is_dir($output_dir) == false){
mkdir($output_dir, 0700);
}
if(is_dir($pathfile) == false){
if(move_uploaded_file($file_tmp, $pathfile)){
//resize original image
WideImage::load($pathfile)->resize(300, 400)->saveToFile($pathfile);
//generate thumbnail
$split = explode('.', end($new_file_name));
$thumb = $split[0].'_t.'.$split[1];
WideImage::load($pathfile)->resize(70, 70)->saveToFile($output_dir.'/'.$thumb);
}
}
}
}
//Getting the variables
$new_file_name1 = $new_file_name[0]; //and so on...
$q = $mysqli->query("UPDATE `listing` SET image1='".$new_file_name1."', image2='".$new_file_name2."', image3='".$new_file_name3."', thumbnail='".$thumb1."', WHERE list_id='".$list_id."' AND user_id='".$user_id."'") or die($mysqli->error);
You could also use: $new_file_name[0] inside the SQL query.