Работа с загруженными файлами
CodeIgniter упрощает и повышает безопасность работы с файлами, загруженными через форму, по сравнению с непосредственным использованием массива PHP $_FILES. Он расширяет класс File и, таким образом, получает все его возможности.
Примечание
Это не то же самое, что класс загрузки файлов в предыдущих версиях CodeIgniter. Это предоставляет прямой интерфейс к загруженным файлам с несколькими небольшими функциями.
Доступ к файлам
Все файлы
При загрузке файлов они могут быть доступны в PHP через суперглобальный массив $_FILES. Этот массив имеет некоторые значительные недостатки при работе с несколькими файлами, загруженными одновременно, и имеет потенциальные уязвимости безопасности, о которых многие разработчики не знают. CodeIgniter помогает в обеих этих ситуациях, стандартизируя использование файлов через общий интерфейс.
К файлам можно получить доступ через текущий экземпляр IncomingRequest. Чтобы получить все файлы, которые были загружены с этим запросом, используйте getFiles(). Это вернёт массив файлов, представленных экземплярами CodeIgniter\HTTP\Files\UploadedFile.
$files = $this->request->getFiles();
Конечно, существует множество способов именования поля ввода файла, и все, что не является простым, может привести к странным результатам. Массив возвращается так, как вы ожидаете. При самом простом использовании один файл может быть отправлен так:
<input type="file" name="avatar" />
Что вернёт простой массив, как:
[
'avatar' => // UploadedFile instance
]
Если вы использовали нотацию массива для имени, ввод будет выглядеть примерно так:
<input type="file" name="my-form[details][avatar]" />
Возвращаемый массивом getFiles() массив будет выглядеть примерно так:
[
'my-form' => [
'details' => [
'avatar' => // UploadedFile instance
]
]
]
В некоторых случаях вы можете указать массив файлов для загрузки:
Upload an avatar: <input type="file" name="my-form[details][avatars][]" /> Upload an avatar: <input type="file" name="my-form[details][avatars][]" />
В этом случае возвращаемый массив файлов будет больше похож на:
[
'my-form' => [
'details' => [
'avatar' => [
0 => /* UploadedFile instance */,
1 => /* UploadedFile instance */
]
]
]
Один файл
Если вам нужно получить доступ к одному файлу, вы можете использовать getFile() для получения экземпляра файла напрямую. Это вернёт экземпляр CodeIgniter\HTTP\Files\UploadedFile:
Самый простой способ использования
При самом простом использовании один файл может быть отправлен так:
<input type="file" name="userfile" />
Что вернёт простой экземпляр файла так:
$file = $this->request->getFile('userfile');
Нотация массива
Если вы использовали нотацию массива для имени, ввод будет выглядеть примерно так:
<input type="file" name="my-form[details][avatar]" />
Для получения экземпляра файла:
$file = $this->request->getFile('my-form.details.avatar');
Несколько файлов
<input type="file" name="images[]" multiple />
В контроллере:
if ($imagefile = $this->request->getFiles()) {
foreach($imagefile['images'] as $img) {
if ($img->isValid() && ! $img->hasMoved()) {
$newName = $img->getRandomName();
$img->move(WRITEPATH.'uploads', $newName);
}
}
}
где images - цикл по имени поля формы
Если существует несколько файлов с одинаковым именем, вы можете использовать getFile() для получения каждого файла индивидуально: В контроллере:
$file1 = $this->request->getFile('images.0');
$file2 = $this->request->getFile('images.1');
Возможно, вам будет проще использовать getFileMultiple(), чтобы получить массив загруженных файлов с одинаковым именем:
$files = $this->request->getFileMultiple('images');
Другой пример:
Upload an avatar: <input type="file" name="my-form[details][avatars][]" /> Upload an avatar: <input type="file" name="my-form[details][avatars][]" />
В контроллере:
$file1 = $this->request->getFile('my-form.details.avatars.0');
$file2 = $this->request->getFile('my-form.details.avatars.1');
Примечание
использование getFiles() более уместно
Работа с файлом
После получения экземпляра UploadedFile вы можете получить информацию о файле безопасным способом, а также переместить файл в новое местоположение.
Проверка файла
Вы можете проверить, был ли файл фактически загружен по HTTP без ошибок, вызвав метод isValid():
if (! $file->isValid()) {
throw new \RuntimeException($file->getErrorString().'('.$file->getError().')');
}
Как видно из этого примера, если у файла была ошибка загрузки, вы можете получить код ошибки (целое число) и сообщение об ошибке с помощью методов getError() и getErrorString(). Следующие ошибки могут быть обнаружены с помощью этого метода:
- Размер файла превышает директиву upload_max_filesize в файле конфигурации.
- Размер файла превышает предел загрузки, заданный в форме.
- Файл был загружен только частично.
- Файл не был загружен.
- Файл не удалось записать на диск.
- Файл не удалось загрузить: отсутствует временная директория.
- Загрузка файла была остановлена расширением PHP.
Имена файлов
getName()
Вы можете получить исходное имя файла, предоставленное клиентом, с помощью метода getName(). Обычно это имя файла, отправленное клиентом, и ему нельзя доверять. Если файл был перемещен, это вернёт окончательное имя перемещённого файла:
$name = $file->getName();
getClientName()
Всегда возвращает исходное имя загруженного файла, отправленное клиентом, даже если файл был перемещен:
$originalName = $file->getClientName();
getTempName()
Чтобы получить полный путь временного файла, созданного во время загрузки, вы можете использовать метод getTempName():
$tempfile = $file->getTempName();
Другая информация о файле
getClientExtension()
Возвращает исходное расширение файла на основе имени файла, которое было загружено. Это НЕ надёжный источник. Для надёжной версии используйте guessExtension() вместо этого:
$ext = $file->getClientExtension();
getClientMimeType()
Возвращает MIME-тип файла, предоставленный клиентом. Это НЕ надёжная информация. Для надёжной версии используйте getMimeType() вместо этого:
$type = $file->getClientMimeType(); echo $type; // image/png
Перемещение файлов
Каждый файл может быть перемещён в новое местоположение с помощью соответствующего метода move(). Этот метод принимает директорию для перемещения файла в качестве первого параметра:
$file->move(WRITEPATH.'uploads');
По умолчанию используется исходное имя файла. Вы можете указать новое имя файла, передав его в качестве второго параметра:
$newName = $file->getRandomName(); $file->move(WRITEPATH.'uploads', $newName);
После удаления файла временный файл удаляется. Вы можете проверить, был ли файл уже перемещен, с помощью метода hasMoved(), который возвращает булево значение:
if ($file->isValid() && ! $file->hasMoved()) {
$file->move($path);
}
Перемещение загруженного файла может завершиться ошибкой HTTPException в нескольких случаях:
- файл уже был перемещён
- файл не был успешно загружен
- операция перемещения файла завершилась неудачно (например, недостаточно прав)
Сохранение файлов
Каждый файл может быть перемещён в новое местоположение с помощью соответствующего метода store().
При самом простом использовании один файл может быть отправлен так:
<input type="file" name="userfile" />
По умолчанию загруженные файлы сохраняются в директории writable/uploads. Будет создана папка YYYYMMDD и случайное имя файла. Возвращает путь к файлу:
$path = $this->request->getFile('userfile')->store();
Вы можете указать директорию для перемещения файла в качестве первого параметра. Новое имя файла, передав его как второй параметр:
$path = $this->request->getFile('userfile')->store('head_img/', 'user_name.jpg');
Перемещение загруженного файла может завершиться ошибкой HTTPException в нескольких случаях:
- файл уже был перемещён
- файл не был успешно загружен
- операция перемещения файла завершилась неудачно (например, недостаточно прав)
© 2014–2020 British Columbia Institute of Technology
Licensed under the MIT License.
https://codeigniter.com/user_guide/libraries/uploaded_files.html