Совсем недавно фреймворк Yii включили в репозиторий packagist.org. Новость очень хорошая, т.к. теперь можно использовать один менеджер зависимостей Composer для обновления и фреймворка, и дополнительных библиотек.
В этой статье мы рассмотрим пример создания несложного приложения на основе Yii, которое позволит загружать картинки и автоматически создавать их миниатюры. Задача тривиальная, но мне хотелось показать подключение дополнительных библиотек с помощью Composer, а в packagist как раз входит Imagine (очень удобная библиотека для работы с изображениями).
Код приложения с инструкцией по установке доступен на GitHub.
Теперь перейдём непосредственно к созданию приложения.
Шаг 1. Устанавливаем Composer.
Тут всё предельно просто. Для Windows есть инсталлятор. Если вы работаете в Linux или MacOS нужно будет выполнить несколько команд из консоли. И инсталлятор, и команды можно взять на официальном сайте.
Шаг 2. Создаём папку для приложения.
В моём случае это yii-composer
. Т.е. приложение доступно по адресу
http://localhost/yii-composer
Но, естественно, название и размещение может быть любым.
Шаг 3. Создаем composer.json
В этом файле содержатся названия компонентов, которые будет загружать Composer.
{ "require": { "yiisoft/yii": "dev-master", "imagine/Imagine": "dev-master" } }
Как видите, данные записаны в JSON формате. Здесь мы указываем менеджеру зависимостей, что нужно загрузить Yii фреймворк и библиотеку Imagine. Преимущество такого подхода заключается в том, что Composer сам отслеживает возможные зависимости. Т.е. когда разработчик библиотеки выкладывает её в репозиторий, он указывает необходимые условия для её работы (например, версию PHP), списки зависимостей и возможных конфликтов с другими библиотеками.
Шаг 4. Загружаем компоненты.
Для этого нужно выполнить команду:
composer install
или composer update
(если install
уже выполнялась, и вы изменяли composer.json
).
В результате Composer загрузит указанные пакеты, и мы получим следующую структуру папок.
Как видите, Composer создал папку vendor
и загрузил в неё библиотеку imagine и фреймворк.
Шаг 5. Создаем приложение.
Здесь мы используем стандартную утилиту yiic
. Я решил, что приложение должно находиться в папке public_html
, но вы можете использовать другую структуру папок.
В любом случае, алгоритм следующий.
Из папки /vendor/yiisoft/yii/framework
выполняем команду
yiic webapp ../../../../public_html
Вместо ../../../../public_html
можно указать свою папку для приложения.
Yiic создаст нужные файлы, и мы увидим результат по адресу.
http://localhost/yii-composer/public_html
Шаг 6. База данных.
Данные о картинках будем хранить в базе данных в таблице images со следующими полями:
id
– первичный ключ;
title
– название картинки;
url
– URL картинки.
После этого указываем параметры подключения в файлах protected/config/main.php
и protected/config/console.php
.
'db'=>array( 'connectionString' => 'mysql:host=localhost;dbname=yii-composer', 'emulatePrepare' => true, 'username' => 'root', 'password' => 'your_pass', 'charset' => 'utf8', ),
Шаг 7. Создаём модель, представление и контроллер.
Для этого в файле protected/config/main.php
раскомментируем модуль gii
и указываем какой-нибудь пароль.
Заходим в админку gii
/public_html/index.php?r=gii/default/login
Создаем с помощью гененратора модель (Images), контроллер (для модели Images) и представления.
На данном этапе посмотреть результат можно на странице
/index.php?r=images
На этом этапе я подробно не останавливаюсь, т.к. процедура хорошо описана в документации Yii.
Шаг 8. Настраиваем представление.
Нам нужно добавить в форму поле для загрузки файла и убирать поле url
(т.к. url
картинки будет генерироваться автоматически).
Добавляем поле для загрузки файла (файл views/images/_form.php
)
<?php $form=$this->beginWidget('CActiveForm', array( 'id'=>'images-form', 'enableAjaxValidation'=>false, 'htmlOptions'=>array( 'enctype'=>'multipart/form-data', ), )); ?> ... <div class="row"> <?php echo $form->labelEx($model,'image'); ?> <?php echo $form->fileField($model,'image'); ?> <?php echo $form->error($model,'image'); ?> </div>
Шаг 9. Подключаем библиотеки, загруженные с помощью Composer
Composer автоматически создаёт загрузчик (файл vendor/autoload.php
), который соответствует спецификации PSR-0. На практике это означает, что для того, чтобы использовать библиотеки, загруженные с помощью Composer, достаточно подключить загрузчик в файле index.php фреймворка.
Т.е. для данного примера добавляем в файл public_html/index.php
строку:
require_once('../vendor/autoload.php');
Теперь можно использовать Imagine. Например,
$imagine = new Imagine\Gd\Imagine();
Как видите, при создании объекта необходимо путь к классу Imagine начиная от папки vendor/imagine/lib
. Т.е. фактически вам без разницы, где именно Composer хранит библиотеки. Вы можете использовать примеры из документации к Imagine без какой-либо дополнительной настройки. Достигается это за счёт того, что Composer автоматически создаёт файл vendor/composer/autoload_namespaces.php
, который возвращает реальное размещение библиотек. В данном случае:
return array( 'Imagine' => $vendorDir . '/imagine/Imagine/lib/', );
Шаг 10. Добавляем обработчик загрузки файла в модель.
Для этого добавляем свойство $image
в класс Images
(файл protected/models/images.php
)
public $image;
Затем добавляем это поле в правила проверки данных модели
public function rules() { return array( array('title', 'length', 'max'=>255), array('title, image', 'required'), array('image', 'file', 'types'=>'jpg, jpeg, gif, png'), // The following rule is used by search(). // @todo Please remove those attributes that should not be searched. array('id, title, image', 'safe', 'on'=>'search'), ); }
В данном случае мы разрешаем загрузку файлов с расширениями jpg, jpeg, gif и png.
И добавляем следующие методы.
public function beforeSave() { $this->url = $this->image->getName(); return parent::beforeSave(); }
Этот метод сохраняет имя загруженного файла в поле url.
Следующий метод создаёт миниатюру.
public function createThumbs() { $imagine = new Imagine\Gd\Imagine(); $size = new Imagine\Image\Box(40, 40); $mode = Imagine\Image\ImageInterface::THUMBNAIL_INSET; $imagine->open(Yii::app()->params['uploadsDir'].$this->image->getName()) ->thumbnail($size, $mode) ->save(Yii::app()->params['uploadsDir'].$this->getThumbnailName()); }
В данном случае мы создаём миниатюру размером в 40px по большей стороне и сохраняем её в папку public_html/uploads
. Размещение папки указываем в параметрах (файл protected/config/main.php
).
Последний метод в модели формирует имя файла миниатюры (добавляет суффикс _40x40
к имени полноразмерной картинки).
public function getThumbnailName() { $parts = explode('.', $this->url); $parts[count($parts) - 2] .= '_40x40'; return implode('.', $parts); }
Шаг 11. Добавляем поддержку загрузки файла в контроллере.
Для этого в файле protected/controllers/ImagesController.php
изменяем метод actionCreate
$model->image=CUploadedFile::getInstance($model,'image'); if($model->save()){ if ($model->image->saveAs(Yii::app()->params['uploadsDir'].$model->image->getName())) { $model->createThumbs(); } $this->redirect(array('view','id'=>$model->id)); }
Здесь выполняется две проверки. Первая – при вызове save
– проверяется заполнение полей модели. При второй проверке проверяется, успешно ли сохранён оригинальный файл, и после этого создаётся миниатюра.
Шаг 12. Показываем картинки.
Для этого в файл представления protected/views/view.php
добавляем строки.
<?php echo CHtml::image(Yii::app()->baseUrl.'/uploads/'.$model->url, $model->title); echo CHtml::image(Yii::app()->baseUrl.'/uploads/'.$model->getThumbnailName(), $model->title); ?>
Естественно, на практике выводить миниатюру под картинкой, особого смысла нет. Но в этом примере дизайн странице не рассматриваем, поэтому я привёл только код, необходимый для отображения картинки.
Заключение.
Статья получилась довольно объёмной, но большая её часть – обычный код для работы с файлами. Подключение Composer сводится к подключению загрузчика. В результате у вас упрощается подключение дополнительных библиотек. Кроме того, в этом случае можно оставить в системе контроля версий только код приложения, т.к. любой разработчик всегда сможет получить нужные версии библиотек с помощью всего одной команды (composer install).
Ещё советую почитать статью Creating Yii applications with composer.
P.S. А для тех, кто интересуется разработкой с использованием Flash — FlashAdverts