Вложение phpMailer

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

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

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

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

См. Здесь, как сначала обрабатывать файлы:

Загрузка файлов

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

 $_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); } 

Затем вы можете лучше проверить наличие ошибок в разных частях, не смешивая одну проблему с другой.

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

Решение

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

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

 $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']); } 

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

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

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

 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']); } } 

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