Я использую это для прикрепления файлов к почте после загрузки их на свой сервер:
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; } }