How to rename an uploaded file so that it is unique? - php

I have an upload form on a site that uploads multiple files to a server, and also sends me an email.
It is written in php, with the main file part being the following:
if (isset($_FILES) && (bool) $_FILES) {
$files = array();
$ext_error = "";
// Define allowed extensions
// blahblahblah checking
// Store attached files in uploads folder
$server_file = dirname(__FILE__) . "/uploads/" . $path_part['basename'];
move_uploaded_file($temp_name, $server_file);
array_push($files, $server_file);
Nowadays, people upload pictures from a cell phone and often they are all named the same file name: image.jpg (or something similar) - so they get overwritten.
I would like to append a counter on to each multiple file (like 1,2,3...) name so they are uploaded and sent with unique names, even though the client sends them as same name.
Something like:
if (isset($_FILES) && (bool) $_FILES) {
$files = array();
$ext_error = "";
// Define allowed extensions
// counter= counter++;
// newFilename=oldFileName+String(counter);
// doRestStuffNewFileName();
// blahblahblah checking
// Store attached files in uploads folder
$server_file = dirname(__FILE__) . "/uploads/" . $path_part['basename'];`
`move_uploaded_file($temp_name, $server_file);`
array_push($files, $server_file);`
How can I modify it as such in php?
ok new comments:
I would like:
for int i=0;i<files[attached];i++;
fileName=files[i]
newFileName=filename+String(Integer(i));
uploadWithNewFileName();
writeToServerWithNewFileName();
This is php current code:
if (isset($_FILES) && (bool) $_FILES) {
$files = array();
$ext_error = "";
foreach ($_FILES as $name => $file) {
if (!$file['name'] == "") {
$file_name = $file['name'];
$size += $file['size'];
$temp_name = $file['tmp_name'];
$path_part = pathinfo($file_name);
$ext = $path_part['extension'];
// Store attached files in uploads folder
$server_file = dirname(__FILE__) . "/uploads/" . $path_part['basename'];
move_uploaded_file($temp_name, $server_file);
array_push($files, $server_file);
}
}
Why doesnt this work:
if (isset($_FILES) && (bool) $_FILES) {
$files = array();
$ext_error = "";
counter =0; //My code
foreach ($_FILES as $name => $file) {
counter++; //My code
if (!$file['name'] == "") {
$file_name = $file['name'];
$size += $file['size'];
$temp_name = $file['tmp_name'];
$path_part = pathinfo($file_name) + counter; //My code
$ext = $path_part['extension'];
// Store attached files in uploads folder
$server_file = dirname(__FILE__) . "/uploads/" . $path_part['basename'];
move_uploaded_file($temp_name, $server_file);
array_push($files, $server_file);
}
}

Related

How to upload same file name with auto increment in PHP?

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

PHP Multiple file upload then attach inline to email via PHPMailer

I'm having a spot of bother with PHPMailer and have searched high and low for this information but nada.
Basically I have a form where the user can upload multiple images which are then saved to a folder on my server, then I need to send an email with the images attached inline at the bottom of the email via PHPMailer.
I can get it to put the first image as inline but the rest of the images do not appear..
Some code:
require '../PHPMailer/PHPMailerAutoload.php';
$mail = new PHPMailer;
if(count($_FILES['upload']['name']) > 0){
//Loop through each file
for($i=0; $i<count($_FILES['upload']['name']); $i++) {
//Get the temp file path
$tmpFilePath = $_FILES['upload']['tmp_name'][$i];
//Make sure we have a filepath
if($tmpFilePath != ""){
//save the filename
$shortname = $_FILES['upload']['name'][$i];
//save the url and the file
$filePath = "../reports/".$id."/" . date('d-m-Y-H-i-s').'-'.$_FILES['upload']['name'][$i];
//Upload the file into the temp dir
if(move_uploaded_file($tmpFilePath, $filePath)) {
$files[] = $shortname;
//insert into db
//use $shortname for the filename
//use $filePath for the relative url to the file
$mail->AddEmbeddedImage($filePath, $shortname, $shortname);
$atts = '<img src="cid:'.$shortname.'">';
}
}
}
}
$mail->Body .= $atts;
Solution:
$dir2 = opendir('../reports/'.$id); // Open the directory containing the uploaded files.
$files = array();
while ($files[] = readdir($dir2));
rsort($files);
closedir($dir2);
foreach ($files as $file) {
if ($file != "." && $file != ".." && $file != 'resources' ){
$withoutExt = preg_replace('/\\.[^.\\s]{3,4}$/', '', $file);
$url = '../reports/'.$id.'/'.$file;
$mail->AddEmbeddedImage($url, $withoutExt);
$mail->Body .= '<img src="cid:'.$withoutExt.'">';
}
}

PHP file upload is creating filenames starting with "PHP" and with .tmp extension

I am using PHP (Symfony2) in my project which has image upload feature. Inside controller:
if ($request->isXmlHttpRequest() && $request->isMethod('POST')) {
$index=(int)$request->request->get('index');
$image_file = $request->files->get('shop_bundle_managementbundle_posttype')['images'][$index]['file'];
$image= new Image();
$image->setFile($image_file);
$image->setSubDir('hg');
$image->upload();
$em->persist($image);
$em->flush();
}
I use a class UploadFileMover that handle the file upload. I didn't write the following code but as I understand, an MD5 hash will be created from the original file name and used as filename. But the instance of UploadedFile contains a file name like "PHP"+number.tmp, not the original as stored in computer filesystem.
class UploadFileMover {
public function moveUploadedFile(UploadedFile $file, $uploadBasePath,$relativePath)
{
$originalName = $file->getFilename();
$targetFileName = $relativePath . DIRECTORY_SEPARATOR . $originalName;
$targetFilePath = $uploadBasePath . DIRECTORY_SEPARATOR . $targetFileName;
$ext = $file->getExtension();
$i=1;
while (file_exists($targetFilePath) && md5_file($file->getPath()) != md5_file($targetFilePath)) {
if ($ext) {
$prev = $i == 1 ? "" : $i;
$targetFilePath = $targetFilePath . str_replace($prev . $ext, $i++ . $ext, $targetFilePath);
} else {
$targetFilePath = $targetFilePath . $i++;
}
}
$targetDir = $uploadBasePath . DIRECTORY_SEPARATOR . $relativePath;
if (!is_dir($targetDir)) {
$ret = mkdir($targetDir, umask(), true);
if (!$ret) {
throw new \RuntimeException("Could not create target directory to move temporary file into.");
}
}
$file->move($targetDir, basename($targetFilePath));
return str_replace($uploadBasePath . DIRECTORY_SEPARATOR, "", $targetFilePath);
}
}
This class is instanciated when an image is uploaded. In other words, I have an Entity Image that has a method upload. Inside entity class:
public function upload()
{
if (null === $this->getFile()) {
return;
}
$uploadFileMover = new UploadFileMover();
$this->path = $uploadFileMover->moveUploadedFile($this->file, self::getUploadDir(),$this->subDir);
$this->file = null;
}
I var_dumped the filename all across the different steps but I cannot figure out where it is transformed to PHP16653.tmp.
Can it be related to an APACHE related configuration? Your help is appreciated. I really did a lot of research for similar issue in the web to no avail.
The problem was created by the line:
$originalName = $file->getFilename();
Use:
$originalName = $file->getClientOriginalName();
instead.

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 change name of uploaded file without changing extension

i'd like to change the name of uploaded file to md5(file_name).ext, where ext is extension of uploaded file. Is there any function which can help me to do it?
$filename = basename($_FILES['file']['name']);
$extension = pathinfo($filename, PATHINFO_EXTENSION);
$new = md5($filename).'.'.$extension;
if (move_uploaded_file($_FILES['file']['tmp_name'], "/path/{$new}"))
{
// other code
}
Use this function to change the file name to md5 with the same extension
function convert_filename_to_md5($filename) {
$filename_parts = explode('.',$filename);
$count = count($filename_parts);
if($count> 1) {
$ext = $filename_parts[$count-1];
unset($filename_parts[$count-1]);
$filename_to_md5 = implode('.',$filename_parts);
$newName = md5($filename_to_md5). '.' . $ext ;
} else {
$newName = md5($filename);
}
return $newName;
}
<?php
$filename = $_FILES['file']['name'];
$extension = pathinfo($filename, PATHINFO_EXTENSION);
$new = rand(0000,9999);
$newfilename=$new.$filename.$extension;
if (move_uploaded_file($_FILES['file']['tmp_name'],$newfilename))
{
//advanced code
}
?>
Find below php code to get file extension and change file name
<?php
if(isset($_FILES['upload_Image']['name']) && $_FILES['upload_Image']['name']!=='') {
$ext = substr($_FILES['upload_Image']['name'], strpos($_FILES['upload_Image']['name'],'.'), strlen($_FILES['upload_Image']['name'])-1);
$imageName = time().$ext;
$normalDestination = "Photos/Orignal/" . $imageName;
move_uploaded_file($_FILES['upload_Image']['tmp_name'], $normalDestination);
}
?>
This one work
<?php
// Your file name you are uploading
$file_name = $HTTP_POST_FILES['ufile']['name'];
// random 4 digit to add to our file name
// some people use date and time in stead of random digit
$random_digit=rand(0000,9999);
//combine random digit to you file name to create new file name
//use dot (.) to combile these two variables
$new_file_name=$random_digit.$file_name;
//set where you want to store files
//in this example we keep file in folder upload
//$new_file_name = new upload file name
//for example upload file name cartoon.gif . $path will be upload/cartoon.gif
$path= "upload/".$new_file_name;
if($ufile !=none)
{
if(copy($HTTP_POST_FILES['ufile']['tmp_name'], $path))
{
echo "Successful<BR/>";
//$new_file_name = new file name
//$HTTP_POST_FILES['ufile']['size'] = file size
//$HTTP_POST_FILES['ufile']['type'] = type of file
echo "File Name :".$new_file_name."<BR/>";
echo "File Size :".$HTTP_POST_FILES['ufile']['size']."<BR/>";
echo "File Type :".$HTTP_POST_FILES['ufile']['type']."<BR/>";
}
else
{
echo "Error";
}
}
?>

Categories