Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

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

Обложка статьи, аватар, документ — файлы от посетителей приходят вместе с формой. В CodeIgniter загруженный файл — объект: его получают из запроса, проверяют правилами и переносят в папку хранения. Общедоступные файлы кладут в public/uploads, закрытые — в writable/uploads.

Форма

<!-- app/Views/posts/cover.php -->
<?= form_open_multipart('posts/cover') ?>
    <input type="file" name="cover">
 
    <button type="submit">Загрузить</button>
<?= form_close() ?>

form_open_multipart() выводит тег формы с атрибутом enctype="multipart/form-data". Без него файл на сервер не попадёт.

Маршруты

// app/Config/Routes.php
$routes->get('posts/cover', 'Posts::cover');
$routes->post('posts/cover', 'Posts::upload');

Метод cover() только выводит шаблон: return view('posts/cover');.

Получение и сохранение

// app/Controllers/Posts.php
public function upload()
{
    $file = $this->request->getFile('cover');
 
    if (! $file->isValid()) {
        return redirect()->back()->with('message', $file->getErrorString());
    }
 
    $name = $file->getRandomName();
    $file->move(FCPATH . 'uploads', $name);
 
    return redirect()->back()->with('message', "Файл сохранён: $name");
}

getFile('cover') возвращает объект файла по имени поля. getRandomName() создаёт случайное имя с прежним расширением, move() переносит файл. FCPATH — путь к папке public, поэтому файл окажется в public/uploads. Выберите картинку и отправьте форму — в папке появится файл вида 1709371200_a3f9c2.jpg.

Проверка

Перед сохранением файл проверяют правилами, как обычные поля. Добавьте в начало метода upload():

$rules = [
    'cover' => 'uploaded[cover]|is_image[cover]|max_size[cover,2048]|ext_in[cover,jpg,jpeg,png,webp]',
];
 
if (! $this->validate($rules)) {
    return redirect()->back()->withInput();
}

Теперь текстовый файл или картинка больше двух мегабайт будут отклонены.

ПравилоЧто проверяет
uploaded[cover]Файл действительно загружен
max_size[cover,2048]Размер не больше 2048 КБ
is_image[cover]Файл — картинка
ext_in[cover,jpg,png]Расширение из списка
mime_in[cover,image/png,image/jpeg]Тип содержимого из списка

Вывод картинки

Имя файла сохраняют в записи статьи, а в шаблоне строят адрес функцией base_url():

<img src="<?= base_url('uploads/' . esc($post['cover'], 'url')) ?>" alt="Обложка">

Методы файла

МетодЧто возвращает
getClientName()Имя файла на компьютере посетителя
getRandomName()Случайное имя с расширением
getMimeType()Тип содержимого
getSizeByUnit('kb')Размер в килобайтах
isValid()Загрузка прошла без ошибок
store('invoices')Сохраняет файл в writable/uploads/invoices

Файлы из writable/uploads недоступны по прямому адресу. Отдаёт их контроллер после проверки прав: return $this->response->download($path, null);.

Частая ошибка

Сохранять файл под именем от посетителя — getClientName() — опасно: имя может быть shell.php или содержать ../. Файл с расширением .php в папке public сервер выполнит как программу. Имя создавайте через getRandomName(), список расширений ограничивайте правилом ext_in, а тип проверяйте по содержимому правилом is_image или mime_in.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.