Веб-разработка. Множественная загрузка файлов на CodeIngiter, jQuery

На днях мне понадобилось реализовать очень простое решение для загрузки неограниченного количества файлов. Скажу честно, перелопатил я кучу информации. Большинство решений были с чётко фиксированным количеством файлов (input type=»file»). Также были варианты с флеш-загрузчиками, но на мой взгляд это кривые решения. Хотя мне очень нравятся загрузчики как на Gmail или ВКонтакте.

Мое решение довольно олдскульно, но я бы не сказал, что оно не удобно. Наоборот, очень даже удобно и просто, как в плане дизайна так и реализации:
Веб-разработка. Множественная загрузка файлов на CodeIngiter, jQueryНа днях мне понадобилось реализовать очень простое решение для загрузки неограниченного количества файлов. Скажу честно, перелопатил я кучу информации. Большинство решений были с чётко фиксированным количеством файлов (input type=»file»). Также были варианты с флеш-загрузчиками, но на мой взгляд это кривые решения. Хотя мне очень нравятся загрузчики как на Gmail или ВКонтакте.

Мое решение довольно олдскульно, но я бы не сказал что оно не удобно. Наоборот, очень даже удобно и просто, как в плане дизайна так и реализации:
Веб-разработка. Множественная загрузка файлов на CodeIngiter, jQuery

Нам понадобится CodeIgniter 2.1, а также самая последняя версия jQuery. В качестве операционной системы я использую Mac OS Lion 10.7.2, редактор кода TextMate.

И так, фреймворк я расспоковал в папку Sites. Кстати, если вам не нравятся названия папок application и system, их можно легко переименовать. Заходим в корневой файл index.php и меняет эти значения:

$system_path = 'system';
$application_folder = 'application';

Я сделал так:

$system_path = 'framework';
$application_folder = 'app';

Теперь вам нужно просто переименовать эти папки и всё.

Заходим в папку app, затем в controller и создаём файл – upload.php. Это будет наш контроллер – Upload, пока сделаем один экшен:

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class Upload extends CI_Controller {
   
   public function __construct()
	{
		parent::__construct();
		
		$this->load->helper('form');
	}
	
	public function index()
	{
	   $this->load->view('upload_files');
	}
}

/* End of file post.php */
/* Location: ./application/controllers/upload.php */
?>

Контроллер создали, теперь добавим вьюшку к нему. Заходим в папку /app / views, и создаём файл upload_files.php:

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="utf-8">
	<title>Веб-разработка. Множественная загрузка файлов на CodeIngiter, jQuery</title>
	<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.min.js"></script>
	<style type="text/css">

	::selection{ background-color: #E13300; color: white; }
	::moz-selection{ background-color: #E13300; color: white; }
	::webkit-selection{ background-color: #E13300; color: white; }

	body {
		background-color: #fff;
		margin: 40px;
		font: 13px/20px normal Helvetica, Arial, sans-serif;
		color: #4F5155;
	}

	a {
		color: #003399;
		background-color: transparent;
		font-weight: normal;
	}

	h1 {
		color: #444;
		background-color: transparent;
		border-bottom: 1px solid #D0D0D0;
		font-size: 19px;
		font-weight: normal;
		margin: 0 0 14px 0;
		padding: 14px 15px 10px 15px;
	}

	code {
		font-family: Consolas, Monaco, Courier New, Courier, monospace;
		font-size: 12px;
		background-color: #f9f9f9;
		border: 1px solid #D0D0D0;
		color: #002166;
		display: block;
		margin: 14px 0 14px 0;
		padding: 12px 10px 12px 10px;
	}

	#body{
		margin: 0 15px 0 15px;
	}
	
	p.footer{
		text-align: right;
		font-size: 11px;
		border-top: 1px solid #D0D0D0;
		line-height: 32px;
		padding: 0 10px 0 10px;
		margin: 20px 0 0 0;
	}
	
	#container{
		margin: 10px;
		border: 1px solid #D0D0D0;
		border-radius: 5px;
		-webkit-box-shadow: 0 0 8px #D0D0D0;
	}
	</style>
</head>
<body>

<div id="container">
	<h1>Множественная загрузка файлов</h1>

	<div id="body">

      <?php echo form_open_multipart("/upload/add"); ?>

      <a href="#" class="ajax_link" id="add">Добавить файл</a>
      <br />
      <br />
      <div class="files">
         <?php echo form_upload("userfile_1"); ?>
      </div>

      <p><?php echo form_submit('submit', 'Загрузить файлы'); ?></p>
      <?php echo form_close(); ?>
	</div>

	<p class="footer">Page rendered in <strong>{elapsed_time}</strong> seconds</p>
</div>

</body>
</html>

Что бы можно было добавлять файлы для загрузки, напишем простой js-скрипт. В корне создайте папку public, внутри разместите файл – jquery.client.js со следующим кодом:

$(document).ready(function(){
 
	var i = $('input').size() + 1;
 
	$('#add').click(function() {
		$('<div><input type="file" class="field" id="userfile_'+ i +'" name="userfile_'+ i +'" /></div>').fadeIn('slow').appendTo('.files');
		i++;
	});
 
});

Добавим в head ссылку на наш скрипт:

<script type="text/javascript" src="../public/jquery.client.js"></script>

Окей, теперь запустите браузер и запустите наше веб-приложение. У меня адрес такой – http://192.168.1.103/~damir/upload/index.php/upload
Понажимайте на ссылку Добавить файл, и у вас должны появляться новые input-ы:
Веб-разработка. Множественная загрузка файлов на CodeIngiter, jQuery

Пока конечно загрузка не работает, довайте закончим наш контроллер. Создадим новый экшен:

public function add()
   {	
      // Папка в корне проекта, обязательно установите прова на чтение и запись
      $config['upload_path'] = './uploads';
      $config['allowed_types'] = 'gif|jpg|png';
      $config['max_size']	= '10000';

      // Менять название файла, выглядить как md5-хэш
      $config['encrypt_name']	= TRUE;

      $this->load->library('upload', $config);

      foreach ($_FILES as $key => $value)
      {
         if (!$this->upload->do_upload($key))
         {
         // Если во время загрузки были ошибки, 
         // их можно увидеть через метод $this->upload->display_errors();
         print_r ($this->upload->display_errors());
         }
         else 
         {
            // Информация о загруженом файле можно увидеть через метод $this->upload->data();
            print_r ($this->upload->data());
         }
      }
   }

Запустите приложение, и загрузите файлы. Все должно складыватся в папку uploads:
Веб-разработка. Множественная загрузка файлов на CodeIngiter, jQuery

Затем, после загрузки вы можете увидеть информацию о загруженных файлах:
Веб-разработка. Множественная загрузка файлов на CodeIngiter, jQuery

Дополнительно

  1. Документация по фреймворку CodeIgniter 2.1 на русском языке
  2. Описание класса File Uploading
  3. Бонус – описание класса Image Manipulation

Исходные коды веб-приложения «Upload» – [attachment=43]
Также исходные коды доступны на githubhttps://github.com/williamadama/Upload

Я на Google+