PHP 检查文件名是否正在使用,然后在上传时添加数字
PHP check if filename is in use and then add number on upload
我正在尝试制作一个 "send email" 表单,在发送电子邮件之前将文件上传到文件夹。文件的路径随后会显示在电子邮件中,但如果文件确实存在,我不希望它们被覆盖,但我想添加一个数字。
我编写了这个小代码,但它不起作用!
错误说:
Parse error: syntax error, unexpected '$name_of_uploaded_file' (T_VARIABLE) in /customers/8/5/6/HOMEPAGE/httpd.www/php/mailtest2.php on line 49
如果文件不存在,下面的脚本现在会上传文件。如果该文件确实存在,则什么也不会发生。脚本应该结束。
脚本已修改为不将“_1”添加到文件名并将文件保存在文件夹中的原因。现在它将文件保存在文件夹中并出现错误:复制上传文件时出错
有人可以向我解释我做错了什么吗?
现在显示所有代码来调试这个:
<?php
//Uploaded file 1
//Settings
$max_allowed_file_size = 2000; // size in KB
$allowed_extensions = array("jpg", "jpeg", "gif", "bmp", "pdf");
error_reporting(E_ALL);
//Upload folder
//name also used later on mail
$name = $_POST['name'];
$d = date('d.m.y');
$varfoldername = "../receivedfiles/$name$d/";
if(!is_dir($varfoldername)) {
mkdir($varfoldername , 0777 , true);
}
$upload_folder = $varfoldername;
//Get the uploaded file information
$name_of_uploaded_file =
basename($_FILES['uploaded_file']['name']);
//Validations
//----- Check if files exists and adds _X to it -----
$original_name_of_file = pathinfo($name_of_uploaded_file, PATHINFO_FILENAME);
$extension = pathinfo($name_of_uploaded_file, PATHINFO_EXTENSION);
$FileCounter = 0;
while (file_exists($varfoldername.$name_of_uploaded_file)) {
$FileCounter++;
$name_of_uploaded_file = $original_name_of_file . '_' . $FileCounter . '.' . $extension;
}
//copy the temp. uploaded file to uploads folder
$path_of_uploaded_file = $upload_folder . $name_of_uploaded_file;
$tmp_path = $_FILES["uploaded_file"]["tmp_name"];
if(is_uploaded_file($tmp_path))
{
if(move_uploaded_file ( $tmp_path,$path_of_uploaded_file ))
{
die("Error while copying the uploaded file");
}
}
//Validate size requirements
$size_of_uploaded_file =
$_FILES["uploaded_file"]["size"]/1024;//size in KBs
if($size_of_uploaded_file > $max_allowed_file_size )
{
die("Fejl: Filen er for stor");
}
//------ Validate the file extension -----
//get the file extension of the file
$type_of_uploaded_file =
substr($name_of_uploaded_file,
strrpos($name_of_uploaded_file, '.') + 1);
$allowed_ext = false;
for($i=0; $i<sizeof($allowed_extensions); $i++)
{
if(strcasecmp($allowed_extensions[$i],$type_of_uploaded_file) == 0)
{
$allowed_ext = true;
}
}
if(!$allowed_ext)
{
die("The uploaded file is not supported file type. \n Send venligst filer af følgende type: .implode(',',$allowed_extensions)");
}
$email = $_POST['email'];
$phone = $_POST['phone'];
$call = $_POST['call'];
$company = $_POST['company'];
$type = $_POST['type'];
$adress = $_POST['adress'];
$hesteid = $_POST['hesteid'];
$hestenavn = $_POST['hestenavn'];
$message = $_POST['message'];
$areacode = $_POST['areacode'];
$land = $_POST['land'];
$formcontent=" Fra: $company \n Navn: $name \n Adresse: $adress , $areacode \n Land: $land \n Telefon: $phone \n Ringes op: $call \n Type: $type \n Hoppens navn og ID: $hestenavn , $hesteid \n Besked: \n $message \n Vedhæftede filer: \n $path_of_uploaded_file";
$recipient = "simon@secret.dk";
$subject = "Besked fra hjemmesiden";
$mailheader = "Fra: $email \r\n";
mail($recipient, $subject, $formcontent, $mailheader) or die("Error!");
header('Location: thank_you.shtml');
?>
while (file_exists($varfoldername . $name_of_uploaded_file ))
也许您需要一个 $varfoldername . '/' . $name_of_uploaded_file
- 最好是您能给我们一个 var_dump 这两个变量。
您需要使用 .
字符连接(粘在一起)不同的 PHP 变量,因此:
while (file_exists($varfoldername$name_of_uploaded_file ))
会给你 return 一个解析错误,因为你需要告诉 PHP 你想将两个变量 串在一起 ,所以改用 .
并写:
while (file_exists($varfoldername.$name_of_uploaded_file))
您可能还需要在两个变量之间添加一个 /
目录分隔符,但这是一个与您当前问题没有直接关系的问题。但它对 print $varfoldername.$name_of_uploaded_file
很有用,看看它是否是正确的文件路径布局(具有所有 /
等)
进一步工作
Hi again I just modified the question. Found two stupid bugs. Now the script runs without error but doesn't add "_1" to the filename. – Simon Jensen
重新排列您的代码:
$FileCounter = 0;
$original_name_of_file = $name_of_uploaded_file;
while (file_exists($varfoldername.$name_of_uploaded_file)) {
$FileCounter++;
$name_of_uploaded_file = $original_name_of_file . '_' . $FileCounter . '.' . $extension;
}
这里发生了什么:
PHP 在 while 循环中覆盖 $name_of_uploaded_file
这样如果你有 file_1.txt
那么循环中的下一个文件名将是 file_1.txt_2.txt
你可以看到这个覆盖远非完美,你需要保存 Original 文件,然后用增量值覆盖原始文件,然后覆盖 .txt .
您的 $name_of_uploaded_file
的原始值未定义。
$FileCounter
为清楚起见,在写入字符串之前递增。
您的 $FileCounter++
代码将无法运行,因为您通过设置将 $FileCounter
定义为 string
在引号中。我已经删除了引号,所以它现在被 PHP 识别为一个整数。
您的 file_exists
呼叫 应该 不 被引号引起来 PHP 额外的、不必要的工作,而且经常会让你和你的 IDE 感到困惑。有效的引号是:
PHP Logic: I found a quote, I will start a string structure, oh, this
part looks like a variable, I will stop the string structure, then
concatenate this variable value into the string strucuture, then
continue the string, oh, another variable, I will stop the string
structure, and then concatenate the second variable into this string,
then continue. I found another quote so string finished.
这比清晰简洁地定义两个用 .
连接的变量要大得多。
完整代码:
$name = $_POST['name'];
$d = date('d.m.y');
/***
Ideally folders should NEVER be relative, always base them from the PHP server
root such as (example only), using $_SERVER['DOCUMENT_ROOT']:
$varfoldername = $_SERVER['DOCUMENT_ROOT']."/data/uploads/receivedfiles/".$name.$d."/";
***/
$varfoldername = "../receivedfiles/".$name.$d."/";
$upload_folder = $varfoldername;
$name_of_uploaded_file = basename($_FILES['uploaded_file']['name']);
$original_name_of_file = pathinfo($name_of_uploaded_file, PATHINFO_FILENAME);
$extension = pathinfo($name_of_uploaded_file, PATHINFO_EXTENSION);
$FileCounter = 0;
while (file_exists($varfoldername.$name_of_uploaded_file)) {
$FileCounter++;
$name_of_uploaded_file = $original_name_of_file . '_' . $FileCounter . '.' . $extension;
}
/***
Now $name_of_uploaded_file will have the numerical appendage as needed.
***/
if(move_uploaded_file( $tmp_path , $varfoldername.$name_of_uploaded_file )){
print "file uploaded!";
}
重要
不要使用copy
,而是使用PHP Move_upload_file :
if(!copy($tmp_path,$path_of_uploaded_file)){ ...
变成
if(move_uploaded_file ( $tmp_path , $path_of_uploaded_file )){ ...
当您可以从中创建一个可重复使用的对象时,就没有太多需要使用这个长方法了。
interface FileUploaderInterface
{
public function upload($path);
}
class FileUploader implements FileUploaderInterface
{
protected $File;
public function __construct($file)
{
$this->File = $file;
return $this;
}
public function upload($path)
{
if(file_exists($path.$this->File['name']))
{
$this->File["tmp_name"] = $this->File["name"] . '-' . time();
move_uploaded_file($this->File, $path . $this->File["name"]);
return false;
}
else
{
move_uploaded_file($this->File, $path . $this->File["name"]);
return true;
}
}
}
只需使用 require_once()
然后使用此代码即可使用:
$obj = new FileUploader($_FILES["fileToUpload"]);
if(!$obj->upload(dirname(__FILE__) . '/example/path/ect')) {
echo "File existed, we added the time onto the name";
}
我正在尝试制作一个 "send email" 表单,在发送电子邮件之前将文件上传到文件夹。文件的路径随后会显示在电子邮件中,但如果文件确实存在,我不希望它们被覆盖,但我想添加一个数字。
我编写了这个小代码,但它不起作用!
错误说:
Parse error: syntax error, unexpected '$name_of_uploaded_file' (T_VARIABLE) in /customers/8/5/6/HOMEPAGE/httpd.www/php/mailtest2.php on line 49
如果文件不存在,下面的脚本现在会上传文件。如果该文件确实存在,则什么也不会发生。脚本应该结束。
脚本已修改为不将“_1”添加到文件名并将文件保存在文件夹中的原因。现在它将文件保存在文件夹中并出现错误:复制上传文件时出错
有人可以向我解释我做错了什么吗?
现在显示所有代码来调试这个:
<?php
//Uploaded file 1
//Settings
$max_allowed_file_size = 2000; // size in KB
$allowed_extensions = array("jpg", "jpeg", "gif", "bmp", "pdf");
error_reporting(E_ALL);
//Upload folder
//name also used later on mail
$name = $_POST['name'];
$d = date('d.m.y');
$varfoldername = "../receivedfiles/$name$d/";
if(!is_dir($varfoldername)) {
mkdir($varfoldername , 0777 , true);
}
$upload_folder = $varfoldername;
//Get the uploaded file information
$name_of_uploaded_file =
basename($_FILES['uploaded_file']['name']);
//Validations
//----- Check if files exists and adds _X to it -----
$original_name_of_file = pathinfo($name_of_uploaded_file, PATHINFO_FILENAME);
$extension = pathinfo($name_of_uploaded_file, PATHINFO_EXTENSION);
$FileCounter = 0;
while (file_exists($varfoldername.$name_of_uploaded_file)) {
$FileCounter++;
$name_of_uploaded_file = $original_name_of_file . '_' . $FileCounter . '.' . $extension;
}
//copy the temp. uploaded file to uploads folder
$path_of_uploaded_file = $upload_folder . $name_of_uploaded_file;
$tmp_path = $_FILES["uploaded_file"]["tmp_name"];
if(is_uploaded_file($tmp_path))
{
if(move_uploaded_file ( $tmp_path,$path_of_uploaded_file ))
{
die("Error while copying the uploaded file");
}
}
//Validate size requirements
$size_of_uploaded_file =
$_FILES["uploaded_file"]["size"]/1024;//size in KBs
if($size_of_uploaded_file > $max_allowed_file_size )
{
die("Fejl: Filen er for stor");
}
//------ Validate the file extension -----
//get the file extension of the file
$type_of_uploaded_file =
substr($name_of_uploaded_file,
strrpos($name_of_uploaded_file, '.') + 1);
$allowed_ext = false;
for($i=0; $i<sizeof($allowed_extensions); $i++)
{
if(strcasecmp($allowed_extensions[$i],$type_of_uploaded_file) == 0)
{
$allowed_ext = true;
}
}
if(!$allowed_ext)
{
die("The uploaded file is not supported file type. \n Send venligst filer af følgende type: .implode(',',$allowed_extensions)");
}
$email = $_POST['email'];
$phone = $_POST['phone'];
$call = $_POST['call'];
$company = $_POST['company'];
$type = $_POST['type'];
$adress = $_POST['adress'];
$hesteid = $_POST['hesteid'];
$hestenavn = $_POST['hestenavn'];
$message = $_POST['message'];
$areacode = $_POST['areacode'];
$land = $_POST['land'];
$formcontent=" Fra: $company \n Navn: $name \n Adresse: $adress , $areacode \n Land: $land \n Telefon: $phone \n Ringes op: $call \n Type: $type \n Hoppens navn og ID: $hestenavn , $hesteid \n Besked: \n $message \n Vedhæftede filer: \n $path_of_uploaded_file";
$recipient = "simon@secret.dk";
$subject = "Besked fra hjemmesiden";
$mailheader = "Fra: $email \r\n";
mail($recipient, $subject, $formcontent, $mailheader) or die("Error!");
header('Location: thank_you.shtml');
?>
while (file_exists($varfoldername . $name_of_uploaded_file ))
也许您需要一个 $varfoldername . '/' . $name_of_uploaded_file
- 最好是您能给我们一个 var_dump 这两个变量。
您需要使用 .
字符连接(粘在一起)不同的 PHP 变量,因此:
while (file_exists($varfoldername$name_of_uploaded_file ))
会给你 return 一个解析错误,因为你需要告诉 PHP 你想将两个变量 串在一起 ,所以改用 .
并写:
while (file_exists($varfoldername.$name_of_uploaded_file))
您可能还需要在两个变量之间添加一个 /
目录分隔符,但这是一个与您当前问题没有直接关系的问题。但它对 print $varfoldername.$name_of_uploaded_file
很有用,看看它是否是正确的文件路径布局(具有所有 /
等)
进一步工作
Hi again I just modified the question. Found two stupid bugs. Now the script runs without error but doesn't add "_1" to the filename. – Simon Jensen
重新排列您的代码:
$FileCounter = 0;
$original_name_of_file = $name_of_uploaded_file;
while (file_exists($varfoldername.$name_of_uploaded_file)) {
$FileCounter++;
$name_of_uploaded_file = $original_name_of_file . '_' . $FileCounter . '.' . $extension;
}
这里发生了什么:
PHP 在 while 循环中覆盖
$name_of_uploaded_file
这样如果你有file_1.txt
那么循环中的下一个文件名将是file_1.txt_2.txt
你可以看到这个覆盖远非完美,你需要保存 Original 文件,然后用增量值覆盖原始文件,然后覆盖 .txt .您的
$name_of_uploaded_file
的原始值未定义。$FileCounter
为清楚起见,在写入字符串之前递增。您的
$FileCounter++
代码将无法运行,因为您通过设置将$FileCounter
定义为string
在引号中。我已经删除了引号,所以它现在被 PHP 识别为一个整数。您的
file_exists
呼叫 应该 不 被引号引起来 PHP 额外的、不必要的工作,而且经常会让你和你的 IDE 感到困惑。有效的引号是:
PHP Logic: I found a quote, I will start a string structure, oh, this part looks like a variable, I will stop the string structure, then concatenate this variable value into the string strucuture, then continue the string, oh, another variable, I will stop the string structure, and then concatenate the second variable into this string, then continue. I found another quote so string finished.
这比清晰简洁地定义两个用 .
连接的变量要大得多。
完整代码:
$name = $_POST['name'];
$d = date('d.m.y');
/***
Ideally folders should NEVER be relative, always base them from the PHP server
root such as (example only), using $_SERVER['DOCUMENT_ROOT']:
$varfoldername = $_SERVER['DOCUMENT_ROOT']."/data/uploads/receivedfiles/".$name.$d."/";
***/
$varfoldername = "../receivedfiles/".$name.$d."/";
$upload_folder = $varfoldername;
$name_of_uploaded_file = basename($_FILES['uploaded_file']['name']);
$original_name_of_file = pathinfo($name_of_uploaded_file, PATHINFO_FILENAME);
$extension = pathinfo($name_of_uploaded_file, PATHINFO_EXTENSION);
$FileCounter = 0;
while (file_exists($varfoldername.$name_of_uploaded_file)) {
$FileCounter++;
$name_of_uploaded_file = $original_name_of_file . '_' . $FileCounter . '.' . $extension;
}
/***
Now $name_of_uploaded_file will have the numerical appendage as needed.
***/
if(move_uploaded_file( $tmp_path , $varfoldername.$name_of_uploaded_file )){
print "file uploaded!";
}
重要
不要使用copy
,而是使用PHP Move_upload_file :
if(!copy($tmp_path,$path_of_uploaded_file)){ ...
变成
if(move_uploaded_file ( $tmp_path , $path_of_uploaded_file )){ ...
当您可以从中创建一个可重复使用的对象时,就没有太多需要使用这个长方法了。
interface FileUploaderInterface
{
public function upload($path);
}
class FileUploader implements FileUploaderInterface
{
protected $File;
public function __construct($file)
{
$this->File = $file;
return $this;
}
public function upload($path)
{
if(file_exists($path.$this->File['name']))
{
$this->File["tmp_name"] = $this->File["name"] . '-' . time();
move_uploaded_file($this->File, $path . $this->File["name"]);
return false;
}
else
{
move_uploaded_file($this->File, $path . $this->File["name"]);
return true;
}
}
}
只需使用 require_once()
然后使用此代码即可使用:
$obj = new FileUploader($_FILES["fileToUpload"]);
if(!$obj->upload(dirname(__FILE__) . '/example/path/ect')) {
echo "File existed, we added the time onto the name";
}