Multiple image upload, change name if image already exists - php

I have a code that changes image names like in the windows systems. If there is a image like cup.jpg, the code changes the name into cup0.jpg.
The problem however, is when I'm uploading many images from array and only some of the images already exist and need to get the name changed.
What changes need to be made for this to work with multiple files?
for($i=0; $i<count($_FILES['upload']['name']); $i++) {
$target_file = $target_dir . basename($_FILES["upload"]["name"][$i]);
$images[] = basename($_FILES['upload']['name'][$i]);
}
if (file_exists($target_file)) {
$i = 0;
echo " Image exists, changing name.";
while (file_exists($target_file)) {
$extension = pathinfo($target_file, PATHINFO_EXTENSION);
$filename = pathinfo($target_file, PATHINFO_FILENAME);
$new_filename = $filename . $i . $iterator . '.' . $extension;
$target_file = $target_dir . $new_filename;
$i++;
$images[] = $new_filename;
}
}
I tried adding a loop but the code doesn't work if the array consists of new images and already existing images so only some of the images would need their names changed.

Here are you go:
$images = array();
for($i=0; $i<count($_FILES['upload']['name']); $i++) {
getUniqueName(basename($_FILES["upload"]["name"][$i]),$images);
}
function getUniqueName ($name, &$images) {
$i = 0;
$extension = pathinfo($name, PATHINFO_EXTENSION);
$filename = pathinfo($name, PATHINFO_FILENAME);
while (in_array($name, $images)) {
$name = $filename . $i . '.' . $extension;
$i++;
}
/* Need to define $target_dir here */
$i=0;
while (file_exists($target_dir.$name)) {
$name = $filename . $i . '.' . $extension;
$i++;
}
$images[]= $target_dir.$name;
}

Related

How to standardize the naming of photos in a folder in php?

I have a folder containing several photos all in .jpg
The name they should all have is STYLE_COLOR-n.jpg for example K14700_7132-6.jpg because I made a script that deletes all the photos greater than -6.jpg.
My problem is that I have photos that are badly renamed, i.e. they have an underscore at the end instead of the dash like :
K14700_7132_6.jpg
Some also have a dash on both like this:
K14700-7132_6.jpg
And so my delete script doesn't work if the pictures don't all have the same rename...
Is it possible to automatically replace all the dashes and underscores that are bad to have this format on all my folder STYLE_COLOR-n.jpg?
<?php
$dir = 'C:/wamp64/www/divers/photos/';
$allFiles = scandir($dir);
foreach($allFiles as $file)
{
if (!in_array($file,array(".","..")))
{
$file = $dir.$file;
$filename = basename( $file ); //KA0710_7250-1.jpg
$underscore = explode("_", $filename);
// echo $underscore[0]."<br>"; //KA0710
$endstring = end($underscore);
// echo $endstring."<br>"; //7250-1.jpg
$underscore2 = explode("-", $endstring);
// echo $underscore2[1]."<br>"; //1.jpg
if ($underscore2[1] > 6)
{
unlink("$dir$filename");
echo 'File ' . $filename . ' has been deleted'."<br>";
}
else
{
}
}
}
echo "Deleted photos !";
?>
Sure, this is the part you'll add to that code:
$parts = preg_split("/[-_]+/", $filename);
$newfilename = strtoupper($parts[0].'_'.$parts[1]).'-'.$parts[2];
if ($newfilename !== $filename) {
rename($dir.$filename, $dir.$newfilename); // test this!
$filename = $newfilename;
}
Note - this will permanently rename files (that need it) so BEFORE you run this in production, please test for the old/new rename arguments just to be safe!
Here is the whole enchilada
<?php
$dir = 'C:/wamp64/www/divers/photos/';
$allFiles = scandir($dir);
foreach($allFiles as $file) {
if (!in_array($file,array(".",".."))) {
$file = $dir.$file;
$filename = basename( $file ); //KA0710_7250-1.jpg
// first fix the format
$parts = preg_split("/[-_]+/", $filename);
$newfilename = strtoupper($parts[0].'_'.$parts[1]).'-'.$parts[2];
if ($newfilename !== $filename) {
rename($dir.$filename, $dir.$newfilename); // test this!
$filename = $newfilename;
}
$underscore = explode("_", $filename);
$endstring = end($underscore);
// echo $endstring."<br>"; //7250-1.jpg
$underscore2 = explode("-", $endstring);
// echo $underscore2[1]."<br>"; //1.jpg
if ($underscore2[1] > 6) {
unlink("$dir$filename");
echo 'File ' . $filename . ' has been deleted'."<br>";
} else {
}
}
}
echo "Deleted photos !";
?>

how to update multiple images in laravel?

i want store the images for product the product having multiple images the problem is that i want to update the images problem is images are updated but the entry never goes to database. instead it stores same entry two times.
if($request->hasfile('image')) { //here i got images
$file = $request->file('image');
$file_count= count($file); //for updating multiple images
for ($i=0; $i < $file_count; $i++) {
$imagesize = $file[$i]->getClientSize();
$imageexten = $file[$i]->getClientOriginalExtension();
$product_image_count = count($request->productimagename);
for ($i=0; $i < $product_image_count; $i++) {
if($file_count != 1) {
$new_name = $request->productimagename[$i].$i.".".$imageexten;
} else {
$new_name = $request->productimagename[$i].".".$imageexten;
}
$product_image_path ='images/frontendimage/product_image/'.$new_name;
Image::make($file[$i])->save($product_image_path);
foreach ($product->images as $key => $value) {
product_image::find($value->id)->where('product_id','=',$product->id)
->update(['image_name'=> $new_name,'image_url'=>$product_image_path,
'modified_by'=>Auth::user()->id]);
}
}
}
}
if ($request->has('unit_images'))
{
$promotion = [];
foreach ($request->file('unit_images') as $key => $file) {
$filenameWithExt = $file->getClientOriginalName();
$filename = pathinfo($filenameWithExt, PATHINFO_FILENAME);
$extension = $file->getClientOriginalExtension();
$fileNameToStore = uniqid() . '.' . $extension;
$path = $file->storeAs("$directory/unit_images/$b/$unit_num", $fileNameToStore, 'public');
$this->validate($request, [
'images' => 'dimensions:min_width=250,min_height=250'
]);
$b_id = $request->building_name;
$unitimg = UnitImage::where('unit_id', '=', $unit_store_id)->get();
$new=strlen($unitimg);
if ($new!='2') {
foreach ($unitimg as $get2) {
$get2->delete();
}
$nn=New UnitImage();
$nn->images = $path;
$nn->unit_id = $unit_store_id;
$nn->save();
}
if ($new=='2') {
$nn = New UnitImage();
$nn->images = $path;
$nn->unit_id = $unit_store_id;
$nn->save();
}
}
}
Input Field -
<input type="file" name="images[]" class="form-control" multiple required />
Controller -
$imagesName = array();
$imagesPath = array();
if($files=$request->file('images')){
foreach (Input::file('images') as $file) {
$name = strtolower($file->getClientOriginalName());
$name = preg_replace('/\s+/', '_', $name);
$img = Image::make($file);
$path = 'your/path/'.$name;
$img->save($path);
$imagesName[] = $name;
$imagesPath[] = $path;
}
}
This will upload multiple images to your server and you will get uploaded image names from $imagesName[] and path from $imagesPath[].
Now you can use those according to your BD structure.

PHP fileupload giving all filenames from array

I've been looking in this for a day or two now.
When I upload multiple files to this script, "$finalfilename" give's me back multiple filenames from the second file.
Here's my code:
include ($_SERVER['DOCUMENT_ROOT'] . "/config/config.php");
$valid_extensions = array(
'jpeg',
'jpg',
'png',
'gif',
'bmp'
); // valid extensions
$path = $_SERVER['DOCUMENT_ROOT'] . '/assets/uploads/'; // upload directory
$uploadOK = 1;
$album = strip_tags($_POST['newPostForm-Album']);
$i = 0;
foreach($_FILES['NEW-POST-FORM_IMAGES']['name'] as $file)
{
$imgname = $_FILES['NEW-POST-FORM_IMAGES']['name'][$i];
$tmpname = $_FILES['NEW-POST-FORM_IMAGES']['tmp_name'][$i];
$timestamp = time();
$extension = strtolower(pathinfo($imgname, PATHINFO_EXTENSION));
$newfilename = sha1(time() . $i);
$finalfilename = $newfilename . "." . $extension;
if ($_FILES['NEW-POST-FORM_IMAGES']["size"][$i] > 500000)
{
echo "Sorry, your file is too large.";
$uploadOk = 0;
}
if ($uploadOK)
{
if (in_array($extension, $valid_extensions))
{
$path = $path . strtolower($finalfilename);
if (move_uploaded_file($tmpname, $path))
{
// mysqli_query($con, "INSERT INTO posts VALUES('', '$album', '$finalfilename', '$timestamp')");
echo $_FILES['NEW-POST-FORM_IMAGES']['name'][$i];
}
else
{
echo "error!";
}
}
}
$imgname = "";
$tmpname = "";
$timestamp = "";
$extension = "";
$newfilename = "";
$finalfilename = "";
$i++;
}
As you can see, I tried resetting all the strings at the end before adding $i.
UPDATE
I tried using $file instead of $_FILES (echo $file['name'][$i];)
This gives me back this warning:
Illegal string offset 'name' in
also the output of the second file ($finalfilename) gives me 'filename'.extention'filename'.extention
ea5816965b01dae0b19072606596c01efc015334.jpeg21aa3008f90c89059d981bdc51b458ca1954ab46.jpg
Wich need to be separated.
I need to only get the filename of each file seperatly.
Thank you!
Problem is in $path variable.
Put $path = $_SERVER['DOCUMENT_ROOT'] . '/assets/uploads/'; into the loop. You can remove variable reseting from the end too.
foreach ($_FILES['NEW-POST-FORM_IMAGES']['name'] as $file) {
$path = $_SERVER['DOCUMENT_ROOT'] . '/assets/uploads/';
$imgname = $_FILES['NEW-POST-FORM_IMAGES']['name'][$i];
$tmpname = $_FILES['NEW-POST-FORM_IMAGES']['tmp_name'][$i];
$timestamp = time();
$extension = strtolower(pathinfo($imgname, PATHINFO_EXTENSION));
$newfilename = sha1(time() . $i);
$finalfilename = $newfilename . "." . $extension;
if ($_FILES['NEW-POST-FORM_IMAGES']["size"][$i] > 500000)
{
echo "Sorry, your file is too large.";
$uploadOk = 0;
}
if ($uploadOK)
{
if (in_array($extension, $valid_extensions))
{
$path = $path . strtolower($finalfilename);
if (move_uploaded_file($tmpname, $path))
{
// mysqli_query($con, "INSERT INTO posts VALUES('', '$album', '$finalfilename', '$timestamp')");
echo $_FILES['NEW-POST-FORM_IMAGES']['name'][$i];
}
else
{
echo "error!";
}
}
}
$i++;
}
There are more thing to update, instead of foreach for/while would be better here, or using foreach in else way (use $file in the loop body), etc. Moving $path into loop is easiest way how to fix your problem.

Php Upload multiple files and rename it if not equal at foreach

Im trying to upload multiple files example:
foreach ($_FILES["images"]["error"] as $key => $error)
{
if ($error == UPLOAD_ERR_OK)
{
$name = $_FILES["images"]["name"][$key];
move_uploaded_file( $_FILES["images"]["tmp_name"][$key], $_SERVER['DOCUMENT_ROOT'].'/var/uploads/'.$product_id . "/" . $_FILES['images']['name'][$key]);
}
}
Ok now the files are in the server as 1.jpg, 2.jpg, 3.jpg, 4.jpg, 5.jpg.. till 24.jpg
Then now Im doing a for each for check if the files that I upload got the name that I want if not rename it.
$directory = $_SERVER['DOCUMENT_ROOT'].'/var/uploads/' . $product_id . "/";
$files = glob($directory . "*.jpg");
foreach($files as $i => $name)
{
$newname = sprintf($directory . "%d.jpg", $i+1);
if ($newname != $i + 1)
{
rename($name, $newname);
}
}
The problem now is that when I rename them I got this result
Why 2.jpg, 3.jpg , 4.jpg till 9.jpg disapear?
Thank you in advance!
Try this..
$directory = $_SERVER['DOCUMENT_ROOT'].'/var/uploads/' . $product_id . "/";
$i = 1;
while (false !== ($file = readdir($directory)))
{
// check extension
if (strtolower(pathinfo($file, PATHINFO_EXTENSION)) == 'jpg')
{
$newName = $i . '.jpg';
rename($file, $newName);//rename file
$i++;
}
}
closedir($directory)
I found the answer :)
$directory = $_SERVER['DOCUMENT_ROOT'].'/var/uploads/' . $product_id . "/";
$files = glob($directory . "*.jpg");
$i = 1;
foreach($files as $e => $name)
{
$newname = $directory . $i . ".jpg";
if($name != $newname)
{
rename($name, $newname);
}
else
{
return 0;
}
$i++;
}

PHP Rename File name if Exists Append Number to End

I'm trying to rename the file name of an image when it's uploaded if it exists, say if my file name is test.jpg and it already exists I want to rename it as test1.jpg and then test2.jpg and so on. With the code I've written its changing my file name like so test1.jpg and then test12.jpg any advice on fixing this would be great thank!
PHP
$name = $_FILES['picture']['name'];
$actual_name = pathinfo($name,PATHINFO_FILENAME);
$extension = pathinfo($name, PATHINFO_EXTENSION);
$i = 1;
while(file_exists('tmp/'.$actual_name.".".$extension))
{
$actual_name = (string)$actual_name.$i;
$name = $actual_name.".".$extension;
$i++;
}
Here's a minor modification that I think should do what you want:
$actual_name = pathinfo($name,PATHINFO_FILENAME);
$original_name = $actual_name;
$extension = pathinfo($name, PATHINFO_EXTENSION);
$i = 1;
while(file_exists('tmp/'.$actual_name.".".$extension))
{
$actual_name = (string)$original_name.$i;
$name = $actual_name.".".$extension;
$i++;
}
Inspired from #Jason answer, i created a function which i deemed shorter and more readable filename format.
function newName($path, $filename) {
$res = "$path/$filename";
if (!file_exists($res)) return $res;
$fnameNoExt = pathinfo($filename,PATHINFO_FILENAME);
$ext = pathinfo($filename, PATHINFO_EXTENSION);
$i = 1;
while(file_exists("$path/$fnameNoExt ($i).$ext")) $i++;
return "$path/$fnameNoExt ($i).$ext";
}
Example:
$name = "foo.bar";
$path = 'C:/Users/hp/Desktop/ikreports';
for ($i=1; $i<=10; $i++) {
$newName = newName($path, $name);
file_put_contents($newName, 'asdf');
}
New version (2022):
function newName2($fullpath) {
$path = dirname($fullpath);
if (!file_exists($fullpath)) return $fullpath;
$fnameNoExt = pathinfo($fullpath,PATHINFO_FILENAME);
$ext = pathinfo($fullpath, PATHINFO_EXTENSION);
$i = 1;
while(file_exists("$path/$fnameNoExt ($i).$ext")) $i++;
return "$path/$fnameNoExt ($i).$ext";
}
Usage:
for ($i=1; $i<=10; $i++) {
$newName = newName2($fullpath);
file_put_contents($newName, 'asdf');
}
There are several ways for renaming image in PHP before uploading to the server.
appending timestamp, unique id, image dimensions plus random number etc.You can see them all here
First, Check if the image filename exists in the hosted image folder otherwise upload it. The while loop checks if the image file name exists and appends a unique id as shown below ...
function rename_appending_unique_id($source, $tempfile){
$target_path ='uploads-unique-id/'.$source;
while(file_exists($target_path)){
$fileName = uniqid().'-'.$source;
$target_path = ('uploads-unique-id/'.$fileName);
}
move_uploaded_file($tempfile, $target_path);
}
if(isset($_FILES['upload']['name'])){
$sourcefile= $_FILES['upload']['name'];
tempfile= $_FILES['upload']['tmp_name'];
rename_appending_unique_id($sourcefile, $tempfile);
}
Check more image renaming tactics
I checked SO and found a nice C# answer here, so I ported it for PHP:
['extension' => $extension] = pathinfo($filePath);
$count = 0;
while (file_exists($filePath) === true) {
if ($count === 0) {
$filePath = str_replace($extension, '[' . ++$count . ']' . ".$extension", $filePath);
} else {
$filePath = str_replace("[$count].$extension", '[' . ++$count . ']' . ".$extension", $filePath);
}
}

Categories