Приложение phpMailer - PullRequest
       47

Приложение phpMailer

2 голосов
/ 12 июня 2011

Я использую это для прикрепления файлов к письму после загрузки их на мой сервер:

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

Добавление вложений необязательно, но если файлы не загружены, выдает ошибку: Не удалось получить доступ к файлу

Как я могу предотвратить эту ошибку показа?

Ответы [ 7 ]

6 голосов
/ 12 июня 2011

Смотрите здесь, как сначала обработать загрузку файлов:

Обработка загрузки файлов

Вам необходимо обратиться к временному имени файла. Это необходимо для получения фактического имени файла, а не только имени файла.

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

Таким образом, введите $_FILES['userfile']['name'] для письменного имени файла вложения и $_FILES['userfile']['tmp_name'], чтобы указать фактический файл (данные) загрузки.

Грубо говоря, введите в свой код вкл. проверку , которую вы также должны сделать, чтобы убедиться, что это на самом деле загрузка файла:

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. Если вы хотите поддержать загрузку нескольких файлов, я предлагаю вам ориентироваться на предложения, приведенные на странице Загрузка нескольких файлов . Затем обработайте загрузку файла и сформируйте массив, содержащий имя файла на клиентском компьютере и путь в системе сервера для каждой записи.

// 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 голос
/ 13 июня 2011

Мне удалось решить эту проблему с помощью счетчика:

$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']);
}
1 голос
/ 12 июня 2011

Решение

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']

1 голос
/ 12 июня 2011

Перед добавлением вложения необходимо проверить, существует ли загруженный файл, например, с fopen.

0 голосов
/ 25 января 2013

Не уверен, что это именно то, что вы хотите, но я прикрепил несколько загруженных файлов и сохранил оригинальные имена файлов из веб-формы.Обработка ошибок / обмен сообщениями для пользователя не приведет к ошибке для 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;
      } 
}
0 голосов
/ 12 июня 2011

Перед добавлением вложения необходимо проверить, был ли этот файл действительно загружен / существует.Что-то вроде

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']);
    }
}
0 голосов
/ 12 июня 2011

Соглашаясь с @patapizza, но прежде чем проверять файловую систему (что вы должны сделать в любом случае), вы также можете просто проверить наличие $ _FILES, например

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