Асинхронная загрузка файлов может быть проблемой в лучшие времена, но в сочетании с CodeIgniter это может быть особенно неприятно. Наконец-то я нашел способ, который не только работает последовательно, но и соответствует шаблону MVC. Читайте дальше, чтобы узнать как!
Кстати, вы можете найти несколько полезных плагинов CodeIgniter и скриптов кода на Envato Market, так что просмотрите, что вы можете найти для вашего следующего проекта.
Предисловие
В этом руководстве мы будем использовать PHP-фреймворк CodeIgniter , JavaScript-фреймворк jQuery и скрипт AjaxFileUpload .
Предполагается, что у вас есть практические знания о CodeIgniter и jQuery, но предварительные знания об AjaxFileUpload не требуются. Также предполагается, что у вас уже установлена установка CodeIgniter.
Для краткости загрузка некоторых библиотек / моделей / помощников была опущена. Их можно найти в поставляемом исходном коде, и это довольно стандартный материал.
Вам также понадобится база данных и таблица, называемые files . SQL для создания указанной таблицы:
|
1
2
3
4
5
|
CREATE TABLE `files` (
`id` int NOT NULL AUTO_INCREMENT PRIMARY KEY,
`filename` varchar(255) NOT NULL,
`title` varchar(100) NOT NULL
);
|
К концу урока ваша файловая структура должна выглядеть примерно так (исключая не измененные папки / файлы):
public_html /
— заявление/
—- контроллеры /
—— upload.php
—- модели /
—— files_model.php
—- взгляды/
—— upload.php
—— files.php
— css /
—- style.css
— файлы /
— JS /
—- AjaxFileUpload.js
—- site.js
Шаг 1 — Создание формы

Настройте контроллер
Во-первых, нам нужно создать форму загрузки. Создайте новый контроллер с именем upload и в методе index отредактируйте представление view.
Ваш контроллер должен выглядеть так:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
|
class Upload extends CI_Controller
{
public function __construct()
{
parent::__construct();
$this->load->model(‘files_model’);
$this->load->database();
$this->load->helper(‘url’);
}
public function index()
{
$this->load->view(‘upload’);
}
}
|
Мы также загружаем модель файлов, поэтому мы можем использовать ее в наших методах. Лучшей альтернативой может быть автозагрузка в вашем реальном проекте.
Создать форму
Создайте свое представление, upload.php . Этот вид будет содержать нашу форму загрузки.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
<!doctype html>
<html>
<head>
<script src=»https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js»></script>
<script src=»<?php echo base_url()?>js/site.js»></script>
<script src=»<?php echo base_url()?>js/ajaxfileupload.js»></script>
<link href=»<?php echo base_url()?>css/style.css» rel=»stylesheet» />
</head>
<body>
<h1>Upload File</h1>
<form method=»post» action=»» id=»upload_file»>
<label for=»title»>Title</label>
<input type=»text» name=»title» id=»title» value=»» />
<label for=»userfile»>File</label>
<input type=»file» name=»userfile» id=»userfile» size=»20″ />
<input type=»submit» name=»submit» id=»submit» />
</form>
<h2>Files</h2>
<div id=»files»></div>
</body>
</html>
|
Не забудьте поместить ajaxfileupload.js в js /.
Как видите, мы загружаем наши скрипты вверху; jQuery, AjaxFileUpload и наш собственный файл js. Здесь будет наш собственный JavaScript.
Затем мы просто создаем стандартную форму HTML. В пустом файле #files находится наш список загруженных файлов.
Несколько простых CSS
Чтобы это не выглядело так плохо, давайте добавим немного базового CSS в наш файл style.css в css /.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
|
h1, h2 { font-family: Arial, sans-serif;
h2 { font-size: 20px;
label { font-family: Verdana, sans-serif;
input { padding: 3px 5px;
input[type=»file»] { padding-left: 0;
input[type=»submit»] { width: auto;
#files { font-family: Verdana, sans-serif;
#files strong { font-size: 13px;
#files a { float: right;
#files ul { list-style: none;
#files li { width: 280px;
|
Шаг 2 — Javascript
Создайте и откройте site.js в js /. Поместите следующий код:
$ (function () { $ ('# upload_file'). submit (function (e) { e.preventDefault (); $ .AjaxFileUpload ({ url: './ upload / upload_file /', secureuri: ложно, fileElementId: 'userfile', dataType: 'json', данные : { 'title': $ ('# title'). val () }, успех: функция (данные, статус) { if (data.status! = 'error') { $ ('# files'). html ('<p> Перезагрузка файлов ... </ p>'); refresh_files (); $ ( '# Название') Вал ( ''); } оповещения (data.msg); } }); вернуть ложь; }); });
JavaScript захватывает отправленную форму, и AjaxFileUpload вступает во владение. В фоновом режиме он создает iframe и передает данные через него.
Мы передаем значение заголовка в параметре data вызова AJAX. Если бы у вас было больше полей в форме, вы бы передали их здесь.
Затем мы проверяем наш возврат (который будет в JSON). Если ошибки не произошло, мы обновляем список файлов (см. Ниже), очищаем поле заголовка. В любом случае, мы предупреждаем ответное сообщение.
Шаг 3 — Загрузка файла
Контроллер
Теперь перейдем к загрузке файла. URL-адрес, на который мы загружаем, — это / upload / upload_file /, поэтому создайте новый метод в контроллере загрузки и поместите в него следующий код.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
public function upload_file()
{
$status = «»;
$msg = «»;
$file_element_name = ‘userfile’;
if (empty($_POST[‘title’]))
{
$status = «error»;
$msg = «Please enter a title»;
}
if ($status != «error»)
{
$config[‘upload_path’] = ‘./files/’;
$config[‘allowed_types’] = ‘gif|jpg|png|doc|txt’;
$config[‘max_size’] = 1024 * 8;
$config[‘encrypt_name’] = TRUE;
$this->load->library(‘upload’, $config);
if (!$this->upload->do_upload($file_element_name))
{
$status = ‘error’;
$msg = $this->upload->display_errors(», »);
}
else
{
$data = $this->upload->data();
$file_id = $this->files_model->insert_file($data[‘file_name’], $_POST[‘title’]);
if($file_id)
{
$status = «success»;
$msg = «File successfully uploaded»;
}
else
{
unlink($data[‘full_path’]);
$status = «error»;
$msg = «Something went wrong when saving the file, please try again.»;
}
}
@unlink($_FILES[$file_element_name]);
}
echo json_encode(array(‘status’ => $status, ‘msg’ => $msg));
}
|
Этот код загружается в библиотеку загрузки CodeIgniter с пользовательской конфигурацией. Для полной ссылки об этом, проверьте документы CodeIgniter .
Мы делаем простую проверку, чтобы определить, является ли заголовок пустым или нет. Если это не так, мы загружаем в библиотеку загрузки CodeIgniter. Эта библиотека выполняет большую часть проверки наших файлов для нас.
Далее мы пытаемся загрузить файл. в случае успеха мы сохраняем заголовок и имя файла (переданные через возвращенный массив данных).
Не забудьте удалить временный файл с сервера и отобразить JSON, чтобы мы знали, что произошло.
Модель
В соответствии с шаблоном MVC, наше взаимодействие с БД будет обрабатываться моделью.
Создайте files_model.php и добавьте следующий код:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
|
class Files_Model extends CI_Model {
public function insert_file($filename, $title)
{
$data = array(
‘filename’ => $filename,
‘title’ => $title
);
$this->db->insert(‘files’, $data);
return $this->db->insert_id();
}
}
|
Папка файлов
Мы также должны создать папку, в которую будут загружаться наши файлы. Создайте новый файл в своем веб-корне с именем files , убедившись, что он доступен для записи на сервере.
Шаг 4 — Список файлов

После успешной загрузки нам нужно обновить список файлов, чтобы отобразить изменения.
JavaScript
Откройте site.js и добавьте следующий код в конец файла, ниже всего остального.
функция refresh_files () { $ .Get ( './ загрузка / файлы /') .success (функция (данные) { $ ( '#') Файлы HTML (данные). }); }
Это просто вызывает URL и вставляет возвращенные данные в div с идентификатором файлов.
Нам нужно вызвать эту функцию при загрузке страницы, чтобы изначально показать список файлов. Добавьте это в функцию готовности документа вверху файла:
refresh_files ();
Контроллер
URL, который мы вызываем для получения списка файлов: / upload / files /, поэтому создайте новый метод с именем files и поместите его в следующий код:
|
1
2
3
4
5
|
public function files()
{
$files = $this->files_model->get_files();
$this->load->view(‘files’, array(‘files’ => $files));
}
|
Довольно небольшой метод, мы используем нашу модель для загрузки сохраненных в данный момент файлов и передачи ее в представление.
Модель
Наша модель обрабатывает поиск списка файлов. Откройте файл files_model.php и добавьте в get_files() .
|
1
2
3
4
5
6
7
|
public function get_files()
{
return $this->db->select()
->from(‘files’)
->get()
->result();
}
|
Все очень просто: выберите все файлы, хранящиеся в базе данных.
Вид
Нам нужно создать представление для отображения списка файлов. Создайте новый файл с именем files.php и вставьте следующий код:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
<?php
if (isset($files) && count($files))
{
?>
<ul>
<?php
foreach ($files as $file)
{
?>
<li class=»image_wrap»>
<a href=»#» class=»delete_file_link» data-file_id=»<?php echo $file->id?>»>Delete</a>
<strong><?php echo $file->title?></strong>
<br />
<?php echo $file->filename?>
</li>
<?php
}
?>
</ul>
</form>
<?php
}
else
{
?>
<p>No Files Uploaded</p>
<?php
}
?>
|
Это перебирает файлы и отображает заголовок и имя файла каждого из них. Мы также отображаем ссылку для удаления, которая включает атрибут данных идентификатора файла.
Удаление файла
В завершение мы добавим функциональность для удаления файла, также используя AJAX.
JavaScript
Добавьте следующее в функцию готовности документа:
$ ('. delete_file_link'). live ('click', function (e) { e.preventDefault (); if (подтвердите («Вы уверены, что хотите удалить этот файл?»)) { var link = $ (this); $ .Ajax ({ url: './upload/delete_file/' + link.data ('file_id'), dataType: 'json', успех: функция (данные) { files = $ (# files); if (data.status === "success") { link.parents ('li'). fadeOut ('fast', function () { $ (Это) .remove (); if (files.find ('li'). length == 0) { files.html ('<p> Файлы не загружены </ p>'); } }); } еще { оповещения (data.msg); } } }); } });
Всегда полезно получить подтверждение пользователя при удалении информации.
При нажатии на ссылку для удаления отображается окно подтверждения с вопросом, уверен ли пользователь. Если они есть, мы делаем вызов /upload/delete_file , и в случае успеха мы /upload/delete_file из списка.
Контроллер
Как и выше, URL, который мы вызываем, это /upload/delete_file/ , поэтому создайте метод delete_file и добавьте следующий код:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
|
public function delete_file($file_id)
{
if ($this->files_model->delete_file($file_id))
{
$status = ‘success’;
$msg = ‘File successfully deleted’;
}
else
{
$status = ‘error’;
$msg = ‘Something went wrong when deleteing the file, please try again’;
}
echo json_encode(array(‘status’ => $status, ‘msg’ => $msg));
}
|
Опять же, мы позволяем модели выполнять тяжелую работу, повторяя результаты.
Модель
Теперь мы находимся на последней части головоломки: наши последние два метода.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
|
public function delete_file($file_id)
{
$file = $this->get_file($file_id);
if (!$this->db->where(‘id’, $file_id)->delete(‘files’))
{
return FALSE;
}
unlink(‘./files/’ . $file->filename);
return TRUE;
}
public function get_file($file_id)
{
return $this->db->select()
->from(‘files’)
->where(‘id’, $file_id)
->get()
->row();
}
|
Поскольку мы передаем только идентификатор, нам нужно получить имя файла, поэтому мы создаем новый метод для загрузки файла. После загрузки мы удаляем запись и удаляем файл с сервера.
Вот и все, учебник завершен! Если вы запустите его, вы сможете загрузить файл, увидеть его, а затем удалить; все не покидая страницы.
Последние мысли
Очевидно, что взгляды могут быть полезны, но этот урок должен был дать вам достаточно, чтобы интегрировать это в ваш сайт.
Однако у этого метода есть несколько недостатков:
- Вы можете загружать только один файл за раз, но это легко исправить, используя сервис типа Uploadify .
- В скрипт не встроен индикатор выполнения.
- Мы могли бы уменьшить количество вызовов SQL, обновляя файлы
divпри загрузке файлов, вместо полной их замены.
Спасибо за прочтение!