how to give unique name to file in php in loop - php

I m just renaming file in directory....
...bt my files got duplicate...
due to duplicate .... some file get deleted...
I have an issue in my script...
bt i m unable to solve this..
my script---
for($i=2;$i<=count($worksheet);$i++)
{
$directory = $_SERVER['DOCUMENT_ROOT'].'/mesleep/uploaded_files/test/';
$sku = (!isset($worksheet[$i][1])) ? '' : addslashes(trim($worksheet[$i][1]));
$image_1 = (!isset($worksheet[$i][2])) ? '' : htmlentities(trim($worksheet[$i][2]));
rename($directory.$image_1,$directory.$sku.'_'.$i);
$image_2 = (!isset($worksheet[$i][3])) ? '' : htmlentities(trim($worksheet[$i][3]));
rename($directory.$image_2,$directory.$sku.'_'.$i);
}
how can i make my image name unique...

Try this http://php.net/manual/en/function.uniqid.php
It will help give unique strings.
$uniqueString = uniqid(random(),true);

There are many ways to do so :
You can add time() before name.
Example:
$imageName="XYZ.png";
$uniqueImageName=time().$imageName; //Add time stamp before name to give image a unique name
In case assign name in loop, concatenate extra value with increament.
Like :
for($i=1;$i<=$lengthOfLoop;$i++)
{
$imageName="XYZ.png";
$uniqueImageName=time().$i.$imageName; //Add time stamp before name to give image a unique name
}

Related

Getting File Name Details from Image File

I am looking for a way to grab details from a file name to insert it into my database. My issue is that the file name is always a bit different, even if it has a pattern.
Examples:
arizona-911545_1920.jpg
bass-guitar-913092_1280.jpg
eiffel-tower-905039_1280.jpg
new-york-city-78181_1920.jpg
The first part is always what the image is about, for example arizona, bass guitar, eiffel tower, new york city followed by a unique id and the width of the image.
What I am after would be extracting:
name id and width
So if I run for example getInfo('arizona-911545_1920.jpg');
it would return something like
$extractedname
$extractedid
$extractedwidth
so I could easily save this in my mysql database like
INSERT into images VALUES ('$extractedname','$extractedid','$extractedwidth')
What bothers me most is that image names can be longer, for example new-york-city-bank or even new-york-city-bank-window so I need a safe method to get the name, no matter how long it would be.
I do know how to replace the - between the name, that's not an issue. I am really just searching for a way to extract the details I mentioned above.
I would appreciate it if someone could enlighten me on how to solve this.
Thanks :)
One of the simplest way in this case is to use regexp, for example:
preg_match('/^(\D+)-(\d+)_(\d+)/', $filename, $matches);
// $matches[1] - name
// $matches[2] - id
// $matches[3] - width
This is the main Idea.
Let's pick a file first.
Filename will be "bass-guitar-913092_1280.jpg"
First of all we will Split this with explode, to dot( . ) in variable $Temp
This will give us an Array of bass-guitar-913092_1280 and jpg
We will choose to have the first Item of the array to continue since is the name we are interested in so we will get it with $Temp[0]
After this we will Split it Again this time to ( _ ).
Now we will have an array of bass-guitar-913092 and 1280
The Second value of the Array is what We need so we will pick it with $Temp[1]
The Last part is simple as the others, We will now Split the file name $Temp[0] with ( - ) We will get the Last value of it which is the id $Temp[count($Temp)-1] and we will remove this from the array list, and Connect everything else with implode and the delimeter we want
Now we can use also the Function ucwords to Capitalize every first letter of each word on the main name.
In the following code, there are 2 ways of getting the name, one with lowercase letters, and one with uppercase first letters of each word, uncomment what you want.
Edited Code as a Function
<?php
function ExtractFileInfo($fileName) {
$Temp = explode(".",$fileName);
$Temp = explode("_",$Temp[0]);
$width = $Temp[1];
$Temp = explode("-",$Temp[0]);
$id = $Temp[count($Temp)-1];
unset($Temp[count($Temp-1)]);
// If you want to have the name with lowercase letters Uncomment the Following:
//$name = implode(" ",$Temp);
// If you Want to Capitalize every first letter of the name Uncomment the Following:
//$name = ucwords(implode(" ",$Temp));
return array($name,$id,$width);
}
?>
This will return an Array of 3 Elements Name, Id and Width
Extracting the data you are looking for would be best via a regex pattern like the following:
(.+)-(\d+_(\d+))
Example here: https://regex101.com/r/oM5bS8/2
preg_match('(.+)-(\d+_(\d+))',"<filename>", $matches);
$extractedname = $matches[1];
$extractedid = $matches[2];
$extractedwidth = $matches[3];
EDIT - Just reread the question and you are looking for extraction techniques not how to post the image from a page to your backend. I will leave this here for reference.
When you post files via a form in html to a PHP backend there are few items that are needed.
1) You need to ensure that your form type is multi-part so that it knows to pass the files along.
<form enctype="multipart/form-data">
2) Your php backend needs to iterate over the files and save them accordingly.
Here is a sample of how to iterate over the files that are being submitted.
foreach($_FILES as $file) {
$n = $file['name'];
$s = $file['size'];
if (!$n) continue;
echo "File: $n ($s bytes)";
}

php save image with specific file name not overwriting each other

I hope someone can help me with this php code.
At the moment its just saving an image with the file name "img.png" to the server but with every time a new canvas screenshot is taken the image is just overwritten.
My aim is to create a new unique (like numbered chronological by time taken) file name for the images with every new screenshot and save it on the server.
Here the php code so far:
$data = $_REQUEST['base64data'];
echo $data;
$image = explode('base64,',$data);
file_put_contents('img.png', base64_decode($image[1]));
Thank you.
regards
Try
$filename = 'img_'.date('Y-m-d-H-s').'.png';
file_put_contents($filename, base64_decode($image[1]));
This will save your file with a filename containing the current date and time, e.g.
img_2013-09-19-21-50.png
Try using a session variable to increment a counter like so:
<?php
session_start();
if(!isset($_SESSION['counter'])){
$_SESSION['counter'] = 0;
}
$_SESSION['counter']++;
$data = $_REQUEST['base64data'];
echo $data;
$image = explode('base64,',$data);
file_put_contents('img'.$_SESSION['counter'].'.png', base64_decode($image[1]));
?>
There's several ways to do it, but the easiest is just to add a timestamp/datestamp to the image name. Format the name as you want.
$img_name = 'img'.date('YmdHisu').'.png'; // Date & time with microseconds
$img_name = 'img'.time().'.png'; // unix timestamp
Leave the base64data structure use this one it will work fine.
$fileName = preg_replace('#[^a-z.0-9]#i', '', $fileName);
$image = explode(".", $fileName);
It will give a random number to each image file.
either create a UID using uniqid() function for the filename or create a folder with the name of the username who is uploading the file and leave the original filename. The disadvantage of the first one is that you will have to save the original filename somewhere to show to the user.
https://stackoverflow.com/a/4371988/2701758
**
/* simply for local time first give your continent then '/' then your country's
capital.
*/
date_default_timezone_set('Asia/Dhaka');
$now = new DateTime();
$now = $now->format("Y-m-d H:i:s.u");
$new_name = $now.$image;
/*what you want to add just write with dot,such
$new_name = 'img'.$now.$image;
*/
**

php check if file exist: check only portion

in php we can check if file exist using
if(file_exists("destination/"))
{
condition
}
but what I wanted to do is...
for example I already have this file on my destination
hello_this_is_filename(2).doc
how would I know if there is a file in that directory having a name containing a character
hello_this_is_filename
I wanted to search that way because... if there is exists on that directory, what will I do is... renaming the file into
hello_this_is_filename(3).doc
I also need to count the existence of my search so I know what number I'm going to put like
(3), (4), (5) and so on
any help?
Use glob.
if (count(glob("destination/hello_this_is_filename*.doc"))) {
//...
}
Leveraging Marc B's suggestion and xdazz, I would do something as follows:
<?php
$files = glob("destination/hello_this_is_filename*");
if (count($files)) {
sort($files);
// last one contains the name we need to get the number of
preg_match("([\d+])", end($files), $matches);
$value = 0;
if (count($matches)) {
// increment by one
$value = $matches[0];
}
$newfilename = "destination/hello_this_is_filename (" . ++$value . ").doc";
?>
Sorry this is untested, but thought it provides others with the regexp work to actually do the incrementing...

Create Files Automatically using PHP script

I have a project that needs to create files using the fwrite in php. What I want to do is to make it generic, I want to make each file unique and dont overwrite on the others.
I am creating a project that will record the text from a php form and save it as html, so I want to output to have generated-file1.html and generated-file2.html, etc.. Thank you.
This will give you a count of the number of html files in a given directory
$filecount = count(glob("/Path/to/your/files/*.html"));
and then your new filename will be something like:
$generated_file_name = "generated-file".($filecount+1).".html";
and then fwrite using $generated_file_name
Although I've had to do a similar thing recently and used uniq instead. Like this:
$generated_file_name = md5(uniqid(mt_rand(), true)).".html";
I would suggest using the time as the first part of the filename (as that should then result in files being listed in chronological/alphabetic order, and then borrow from #TomcatExodus to improve the chances of the filename being unique (incase of two submissions being simultaneous).
<?php
$data = $_POST;
$md5 = md5( $data );
$time = time();
$filename_prefix = 'generated_file';
$filename_extn = 'htm';
$filename = $filename_prefix.'-'.$time.'-'.$md5.'.'.$filename_extn;
if( file_exists( $filename ) ){
# EXTREMELY UNLIKELY, unless two forms with the same content and at the same time are submitted
$filename = $filename_prefix.'-'.$time.'-'.$md5.'-'.uniqid().'.'.$filename_extn;
# IMPROBABLE that this will clash now...
}
if( file_exists( $filename ) ){
# Handle the Error Condition
}else{
file_put_contents( $filename , 'Whatever the File Content Should Be...' );
}
This would produce filenames like:
generated_file-1300080525-46ea0d5b246d2841744c26f72a86fc29.htm
generated_file-1300092315-5d350416626ab6bd2868aa84fe10f70c.htm
generated_file-1300109456-77eae508ae79df1ba5e2b2ada645e2ee.htm
If you want to make absolutely sure that you will not overwrite an existing file you could append a uniqid() to the filename. If you want it to be sequential you'll have to read existing files from your filesystem and calculate the next increment which can result in an IO overhead.
I'd go with the uniqid() method :)
If your implementation should result in unique form results every time (therefore unique files) you could hash form data into a filename, giving you unique paths, as well as the opportunity to quickly sort out duplicates;
// capture all posted form data into an array
// validate and sanitize as necessary
$data = $_POST;
// hash data for filename
$fname = md5(serialize($data));
$fpath = 'path/to/dir/' . $fname . '.html';
if(!file_exists($fpath)){
//write data to $fpath
}
Do something like this:
$i = 0;
while (file_exists("file-".$i.".html")) {
$i++;
}
$file = fopen("file-".$i.".html");

Counting sent files

I have an multiple input sending files and I need guard this images with another name inside my folder called 'home';
So the pictures filing with the name home1.jpg, home2.jpg, etc
So, here is my code:
$file = $_FILES['Filedata'];
$filename_home = "";
$img_array = array($filename);
foreach($img_array as $key=>$value){
$filename_home.="home".$key.".jpg";
}
But this doesn't producing the result.
Any help, will be appreciate
Where does $filename come from? It looks like you want to use $file instead.

Categories