How can create a function for unique file name - php

I want to create a function which does rename the file and generate a unique name from its name, together with the user id. Below function is working properly but I'm not satisfied, kindly provide me the similar function.
if(is_array($file) and $file['name'] != '')
{
// getting unique file name
$file['name'] = getUniqueFilename($file);
$file_path = $file_root_path.$file['name'];
if(move_uploaded_file($file['tmp_name'], $file_path)){$filename = $file['name'];}
//
if($oldfile != ''){delete_file($file_root_path.$oldfile);}
return $filename;
} // if ends
else
{
return $oldfile;
} // else ends
function getUniqueFilename($file)
{
if(is_array($file) and $file['name'] != '')
{
// getting file extension
$fnarr = explode(".", $file['name']);
$file_extension = strtolower($fnarr[count($fnarr)-1]);
// getting unique file name
$file_name = substr(md5($file['name'].time()), 5, 15).".".$file_extension;
return $file_name;
} // ends for is_array check
else
{
return '';
} // else ends
} // ends

Use php uniqid() to generate unique ids http://php.net/manual/en/function.uniqid.php
function getUniqueFilename($file)
{
if(is_array($file) and $file['name'] != '')
{
// getting file extension
$file_extension = pathinfo($file['name'], PATHINFO_EXTENSION);
// getting unique file name
$file_name = uniqid().".".$file_extension;
while(file_exists('PATH_TO_WHERE_YOU_SAVE_FILE/'.$file_name)) {
$file_name = uniqid().".".$file_extension;
}
return $file_name;
} // ends for is_array check
else
{
return '';
} // else ends
} // ends

Take a hash of the file contents, e.g. with sha1_file. That guarantees a unique name for each unique file. If the same file gets uploaded a second time, it will generate the same hash, so you're not even storing duplicates of identical files.

Please use this code, that may help you
<?php
function tempdir($dir, $prefix='', $mode=0700)
{
if (substr($dir, -1) != '/') $dir .= '/';
do
{
$path = $dir.$prefix.mt_rand(0, 9999999);
} while (!mkdir($path, $mode));
return $path;
}
?>
Reference Link: http://www.php.net/manual/en/function.tempnam.php

You could create a filename with an [md5][1] hash salted with current [timestamp][2] and a random number.
Something like:
function getUniqueFilename($file)
{
do {
$name = md5(time().rand().$file['name']);
} while (file_exists($path.$name);
return $name;
}
Being path the folder where you want your file created

Related

PHP file_exists With Contents Instead of Name?

Is there a function built into PHP that acts like file_exists, but given file contents instead of the file name?
I need this because I have a site where people can upload an image. The image is stored in a file with a name determined by my program (image_0.png image_1.png image_2.png image_3.png image_4.png ...). I do not want my site to have multiple images with the same contents. This could happen if multiple people found a picture on the internet and all of them uploaded it to my site. I would like to check if there is already a file with the contents of the uploaded file to save on storage.
This is how you can compare exactly two files with PHP:
function compareFiles($file_a, $file_b)
{
if (filesize($file_a) == filesize($file_b))
{
$fp_a = fopen($file_a, 'rb');
$fp_b = fopen($file_b, 'rb');
while (($b = fread($fp_a, 4096)) !== false)
{
$b_b = fread($fp_b, 4096);
if ($b !== $b_b)
{
fclose($fp_a);
fclose($fp_b);
return false;
}
}
fclose($fp_a);
fclose($fp_b);
return true;
}
return false;
}
If you keep the sha1 sum of each file you accept you can simply:
if ($known_sha1 == sha1_file($new_file))
You can use a while loop to look look through the contents of all of your files. This is shown in the example below :
function content_exists($file){
$image = file_get_contents($file);
$counter = 0;
while(file_exists('image_' . $counter . '.png')){
$check = file_get_contents('image_' . $counter . '.png');
if($image === $check){
return true;
}
else{
$counter ++;
}
}
return false;
}
The above function looks through all of your files and checks to see if the given image matches an image that is already stored. If the image already exists, true is returned and if the image does not exist false is returned. An example of how you can use this function shown is below :
if(content_exists($_FILES['file']['tmp_name'])){
// upload
}
else{
// do not upload
}
You could store hashed files in a .txt file separated by a \n so that you could use the function below :
function content_exists($file){
$file = hash('sha256', file_get_contents($file));
$files = explode("\n", rtrim(file_get_contents('files.txt')));
if(in_array($file, $files)){
return true;
}
else{
return false;
}
}
You could then use it to determine whether or not you should save the file as shown below :
if(content_exists($_FILES['file']['tmp_name'])){
// upload
}
else{
// do not upload
}
Just make sure that when a file IS stored, you use the following line of code :
file_put_contents('files.txt', hash('sha256', file_get_contents($file)) . "\n");

SilverStripe UploadField file auto renaming

I have made a form on the front end to upload some images. My idea is to automatically rename all files uploaded into unique id's.
I have looked at the SilverStripe API and I do not see anything about that. UploadField API
Is this possible?
Here is my solution bellow, in Silverstripe 3.X we must extend UploadField with another class. Then copy the ''saveTemporaryFile'' function into it.
Just before ''try'', just have to add :
$ext = array_reverse(explode('.',$tmpFile['name'])); // explode filename into array, reverse array, first array key will then be file extension
$tmpFile['name'] = hash_hmac('sha256', $tmpFile['name'], '12345') . '.' . $ext[0];
Results :
class RandomNameUploadField extends UploadField {
protected function saveTemporaryFile($tmpFile, &$error = null) {
// Determine container object
$error = null;
$fileObject = null;
if (empty($tmpFile)) {
$error = _t('UploadField.FIELDNOTSET', 'File information not found');
return null;
}
if($tmpFile['error']) {
$error = $tmpFile['error'];
return null;
}
// Search for relations that can hold the uploaded files, but don't fallback
// to default if there is no automatic relation
if ($relationClass = $this->getRelationAutosetClass(null)) {
// Create new object explicitly. Otherwise rely on Upload::load to choose the class.
$fileObject = Object::create($relationClass);
}
$ext = array_reverse(explode('.',$tmpFile['name'])); // explode filename into array, reverse array, first array key will then be file extension
$tmpFile['name'] = hash_hmac('sha256', $tmpFile['name'], '12345') . '.' . $ext[0];
// Get the uploaded file into a new file object.
try {
$this->upload->loadIntoFile($tmpFile, $fileObject, $this->getFolderName());
} catch (Exception $e) {
// we shouldn't get an error here, but just in case
$error = $e->getMessage();
return null;
}
// Check if upload field has an error
if ($this->upload->isError()) {
$error = implode(' ' . PHP_EOL, $this->upload->getErrors());
return null;
}
// return file
return $this->upload->getFile();
}
}
Thanks #3dgoo to give me a part of the solution!
I don't now about a API but with some code I was able to do that.
You have two possibilities.
First using database.
Second using only code:
$directory = '/teste/www/fotos/';
$files = glob($directory . '*.jpg');
if ( $files !== false )
{
$filecount = count( $files );
$newid = $filecount+1;
$new_name = "foto_".$newid;
$target_file = $directory."/".$new_name;
move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $target_file);
}
else
{
$new_name = "foto_1";
$target_file = $directory."/".$new_name;
move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $target_file);
}
My example is for jpeg but you can look for hall types.

Renaming filenames and immediately reading files having issues in php

I have pdf files which are report cards of students.The report card names format is <student full name(which can have spaces)><space><studentID>.I need to download files.For this I have used the following code.
if(file_exists($folder_path.'/') && is_dir(folder_path)) {
$report_files = glob(folder_path.'/*'.'_*\.pdf' );
if(count($report_files)>0)
{
$result_data = '';
$result_data = rename_filenamespaces($report_files);
var_dump($result_data);//this shows the edited filename
foreach ($result_data as $file) {
if (strpos($file,$_GET['StudentID']) !== false) {
//code for showing the pdf docs to download
}
}
}
}
//function for renaming if filename has spaces
function rename_filenamespaces($location)
{
$new_location = $location;
foreach ($location as $file) {
//check file has spaces and filename has studentID
if((strpos($file," ")!==false)&& (strpos($file,$_GET['StudentID']) !== false))
{
$new_filename = str_replace(" ","-",$file);
rename($file,$new_filename);
$new_location = $new_filename;
}
}
return $new_location;
}
The variable $result_data gives me the filename without spaces,but the for each loop is showing Warning:Invalid argument supplied for foreach(). But the filename is changed in the server directory immediately after running the function. This warning shows only for first time. I am unable to solve this.
$new_location = $new_filename;
$new_location is a array
$new_filename is a string
You have to use $new_location[$index]
or try
foreach ($new_location as &$file) {
...
...
$file = $new_filename;

Using file_exists() to check for similar file names to prevent overwriting/duplicates?

I am writing an application in PHP where the user submits a form of data and a file name is chosen based off of the data, like so:
$filename = "./savelocation/".$name."_".$identification."_".$date.'.txt';
I am trying to use the file_exists() function to check to see if a file with the same name exists. If it does, the final name is changed to prevent overwriting the submitted form data. Here is my implementation:
$file = "./savelocation/".$name."_".$identification."_".$date.'.txt';
$file = preg_replace('/\s+/', '', $file);
$filepath = "./savelocation/".$name."_".$identification."_".$date.'.txt';
if(file_exists($filepath))
{
$file = "./savelocation/"."INVALIDFILE".'.txt';
}
This prevents people from overwriting applications by changing the name to a single file which acts as the 'default file' in which it doesn't matter if it is overwritten. However, I know this is wrong. My logic was that the if statement would return true, which would execute the code inside of the statement changing the file name to the 'default file'. Is this even a good way to prevent duplicate submissions?
Try this...if there is a match on the file name, break from the loop and redirect
$userFile = $name."_".$identification."_".$date.'.txt;
$fileArray = glob('./savelocation/*');
$arrCount = count($fileArray);
$i = 1;
$msg = null;
foreach ($fileArray as $FA) {
$fileSubstring = str_replace("\.\/savelocation\/", "", $FA);
if ($i > $arrCount) {
break;
} else if ($userFile === $fileSubstring) {
$msg = 'repeat';
break;
} else null;
$i++;
}
if (isset($msg)) header('location: PageThatChastisesUser.php');
Alternatively, if you tweak your code a bit to change your file name, this should work:
if(file_exists($file)) {
$file = str_replace("\.txt", "duplicate\.txt", $file);
}
Change the file name in a way that identifies itself to you as a duplicate.
Here's one way of doing it:
$file = "./savelocation/".$name."_".$identification."_".$date.'.txt';
$file = preg_replace('/\s+/', '', $filen);
$filepath = "./savelocation/".$name."_".$identification."_".$date.'.txt';
$i = 1;
while(file_exists($filepath))
{
$filepath = "./savelocation/".$name."_".$identification."_".$date.'_'.$i.'.txt';
$i++;
}

swfupload destroy session? php

hy, i need a little help here:
i use SWFupload to upload images!
in the upload function i make a folder call $_SESSION['folder'] and all the files i upload are in 1 array call $_SESSION['files'] after uploads finish i print_r($_SESSION) but the array is empty? why that?
this is my upload.php:
if($_FILES['image']['name']) {
list($name,$error) = upload('image','jpeg,jpg,png');
if($error) {$result = $error;}
if($name) { // Upload Successful
$result = watermark($name);
print '<img src="uploads/'.$_SESSION['dir'].'/'.$result.'" />';
} else { // Upload failed for some reason.
print 'noname'.$result;
}
}
function upload($file_id, $types="") {
if(!$_FILES[$file_id]['name']) return array('','No file specified');
$isimage = #getimagesize($_FILES[$file_id]['tmp_name']);
if (!$isimage)return array('','Not jpg');
$file_title = $_FILES[$file_id]['name'];
//Get file extension
$ext_arr = split("\.",basename($file_title));
$ext = strtolower($ext_arr[count($ext_arr)-1]); //Get the last extension
//Not really uniqe - but for all practical reasons, it is
$uniqer = substr(md5(uniqid(rand(),1)),0,10);
//$file_name = $uniqer . '_' . $file_title;//Get Unique Name
//$file_name = $file_title;
$file_name = $uniqer.".".$ext;
$all_types = explode(",",strtolower($types));
if($types) {
if(in_array($ext,$all_types));
else {
$result = "'".$_FILES[$file_id]['name']."' is not a valid file."; //Show error if any.
return array('',$result);
}
}
if((!isset($_SESSION['dir'])) || (!file_exists('uploads/'.$_SESSION['dir']))){
$dirname = date("YmdHis"); // 20010310143223
$pathtodir = $_SERVER['DOCUMENT_ROOT']."/ifunk/uploads/";
$newdir = $pathtodir.$dirname;
if(!mkdir($newdir, 0777)){return array('','cannot create directory');}
$_SESSION['dir'] = $dirname;
}
if(!isset($_SESSION['files'])){$_SESSION['files'] = array();}
//Where the file must be uploaded to
$folder = 'uploads/'.$_SESSION['dir'].'/';
//if($folder) $folder .= '/'; //Add a '/' at the end of the folder
$uploadfile = $folder.$file_name;
$result = '';
//Move the file from the stored location to the new location
if (!move_uploaded_file($_FILES[$file_id]['tmp_name'], $uploadfile)) {
$result = "Cannot upload the file '".$_FILES[$file_id]['name']."'"; //Show error if any.
if(!file_exists($folder)) {
$result .= " : Folder don't exist.";
} elseif(!is_writable($folder)) {
$result .= " : Folder not writable.";
} elseif(!is_writable($uploadfile)) {
$result .= " : File not writable.";
}
$file_name = '';
} else {
if(!$_FILES[$file_id]['size']) { //Check if the file is made
#unlink($uploadfile);//Delete the Empty file
$file_name = '';
$result = "Empty file found - please use a valid file."; //Show the error message
} else {
//$_SESSION['files'] = array();
$_SESSION['files'][] .= $file_name;
chmod($uploadfile,0777);//Make it universally writable.
}
}
return array($file_name,$result);
}
SWFUpload doesn't pass the session ID to the script when you upload, so you have to do this yourself. Simply pass the session ID in a get or post param to the upload script, and then in your application do this before session_start:
if(isset($_REQUEST['PHPSESSID'])) {
session_id($_REQUEST['PHPSESSID']);
}
you must pass the session ID to the upload file used by swfupload.
more details here

Categories