phpMailer附件

时间:2011-06-12 14:58:49

标签: php attachment phpmailer

我正在使用它将文件上传到我的服务器后附加到邮件:

for ($i = 0; $i <= 2; $i++)
{
    $mail->AddAttachment($locatie.$_FILES['uploaded'.$i]['name'], $_FILES['uploaded'.$i]['name']);
}

添加附件是可选的,但如果没有上传文件则会出错:无法访问文件

如何防止出现此错误?

7 个答案:

答案 0 :(得分:6)

请先在此处查看如何处理文件上传:

Handling file uploads

您需要引用临时文件名。这需要获取实际文件名,而不仅仅是文件名。

$_FILES['userfile']['tmp_name']

因此,请访问$_FILES['userfile']['name']以获取附件的书面文件名,并$_FILES['userfile']['tmp_name']指定上传的实际文件(数据)。

大致进入你的代码,incl. a validation你应该做的就是验证它实际上是文件上传:

for ($i = 0; $i <= 2; $i++)
{
    # ignore file that have not been uploaded
    if (empty($_FILES['uploaded'.$i])) continue;

    # get the data of the file
    $fileName = $_FILES['uploaded'.$i]['name'];
    $filePath = $_FILES['uploaded'.$i]['tmpname'];

    # add only if the file is an upload
    is_uploaded_file($filePath) 
      && $mail->AddAttachment($filePath, $fileName)
      ;
}

谨慎提及

您的代码将两个作业混合在一起。这使您难以调试和改进 - 并处理文件/系统问题和安全性等问题。

我建议你采用一种不同的方法:一步一步走。在您的情况下,1。)处理文件上传并收集您需要的数据,2。)添加这些附件。

您可以通过查看PHP手册来改进第一部分。如果您想支持上传多个文件,建议您根据页面Uploading multiple files中给出的建议进行定位。然后处理文件上传并形成一个数组,其中包含客户端计算机上的文件名和每个条目的服务器系统上的路径。

// see PHP Manual for multi file uploads, this is based on it
$validAttachments = array();
foreach($_FILES['userfile']['name'] as $index => $fileName)
{
    $filePath = $_FILES['userfile']['tmp_name'][$index];
    if(is_uploaded_file($filePath))
    {
        $attachment = new stdClass;
        $attachment->fileName = $fileName;
        $attachment->filePath = $filePath;
        $validAttachments[] = $attachment;
    }        
}

如果该部分中已存在错误,则表示它与文件上载过程有关。这是未经测试的代码,因此只是说明方向。

在第二步中,您可以迭代这样的数组并添加附件:

foreach($validAttachments as $attachment)
{
    $mail->AddAttachment($attachment->filePath, $attachment->fileName);
}

然后,您可以更好地检查不同部分中的错误,而不会将一个问题与另一个问题混在一起。

答案 1 :(得分:1)

在添加附件之前,您应该检查上传的文件是否存在,例如与fopen

答案 2 :(得分:1)

解决方案

for ($i = 0; $i <= 2; $i++)
{
    if (file_exists($locatie.$_FILES['uploaded'.$i]['tmp_name'])) {
        $mail->AddAttachment($locatie.$_FILES['uploaded'.$i]['tmp_name'], $_FILES['uploaded'.$i]['name']);
    }
}

更新

您使用$locatie.$_FILES['uploaded'.$i]['name']代替$locatie.$_FILES['uploaded'.$i]['tmp_name']作为要加载的文件。上传文件时,会使用临时名称重命名该文件并将其放在临时文件夹中。这就是你得到它的地方,这就是你需要用$locatie.$_FILES['uploaded'.$i]['tmp_name']

引用它的原因

答案 3 :(得分:1)

我已经能够使用计数器来解决这个问题:

$locatie = 'uploads/';
$upload_count = -1;

    for ($i = 0; $i <= 2; $i++)
    {
        if($_FILES['uploaded'.$i]['type'] != 'application/octet-stream')  // Geen php files
        {
            $folder = $locatie.basename($_FILES['uploaded'.$i]['name']) ;           
            if(move_uploaded_file($_FILES['uploaded'.$i]['tmp_name'], $folder))
            {
                $upload_count ++;
            }
        }

附件的循环:

for ($i = 0; $i <= $upload_count; $i++)
{
    $mail->AddAttachment($locatie.$_FILES['uploaded'.$i]['name'], $_FILES['uploaded'.$i]['name']);
}

答案 4 :(得分:0)

同意@patapizza,但在你检查文件系统之前(你应该做什么),你也可以检查$ _FILES之类的

for ($i = 0; $i < count($_FILES); $i++){
    // only iterate over the number of files you actually have
}

答案 5 :(得分:0)

在添加附件之前,您需要检查该文件是否实际上传/存在。像

这样的东西
for ($i = 0; $i <= 2; $i++)
{
    if (file_exists($locatie.$_FILES['uploaded'.$i]['tmp_name'])) {
        $mail->AddAttachment($locatie.$_FILES['uploaded'.$i]['tmp_name'], $_FILES['uploaded'.$i]['name']);
    }
}

答案 6 :(得分:0)

不确定这是否完全符合您的要求,但这是我附加多个上传文件并保留原始文件名的方式。用户的错误处理/消息传递不会给UPLOAD_ERR_NO_FILE带来错误,因为文件上传是可选字段,但仍处理foreach循环中的每个输入字段。

foreach ($_FILES["userfile"]["error"] as $key => $error) 
    {
      if ($error == UPLOAD_ERR_OK) {
        $tmp_name = $_FILES["userfile"]["tmp_name"][$key];
        $name = $_FILES["userfile"]["name"][$key];
        $mailer->AddAttachment($tmp_name, $name);
        }

      $name = $_FILES["userfile"]["name"][$key];
      switch($error){
      case UPLOAD_ERR_INI_SIZE: echo $errmsg1.$name.$errmsg2;
break;
      case UPLOAD_ERR_FORM_SIZE: echo $errmsg1.$name.$errmsg2;
break;     
      case UPLOAD_ERR_PARTIAL:  echo $errmsg1.$name.$errmsg2; 
break;
      case UPLOAD_ERR_NO_FILE: 
      break; 
      case UPLOAD_ERR_NO_TMP_DIR: echo $errmsg1.$name.$errmsg2;
break; 
      case UPLOAD_ERR_CANT_WRITE: echo $errmsg1.$name.$errmsg2;
break;
      case UPLOAD_ERR_EXTENSION: echo $errmsg1.$name.$errmsg2;
break;
      } 
}