
В качестве примера, создам тестовое расширение (пакет), в него включу достаточно функционала, чтобы продемонстрировать основные моменты которые могут понадобиться в создании расширений для yii-2. Так, расширение у нас будет в виде модуля со своим контроллером, моделью и видом. Оно будет взаимодействовать с базой данных, поэтому используем миграции. Создадим класс автозагрузки, для установки основных параметров расширения в процессе начальной загрузки приложения, таким образом мы зарегистрируем сам модуль непосредственно в этом классе, а так же зададим правила маршрутизации там же, что снимет с устанавливаемого данное расширение человека дополнительные его настройки. Фактически пользователю понадобится выполнить всего 2 команды в консоли:
- установить расширение;
- выполнить миграцию.
Так же покажу как автоматически подключить assets файлы расширения – CSS или JS.
В качестве результата своей работы, расширение будет выводить данные из БД на отдельной странице.
Назовем расширение «mytest» и его структура будет такова:

При разработке своего расширения с нуля, в yii2 можно пользоваться помощником для создания начальных файлов, таких как composer.json, README.md.
Перейти в помощник можно набрав в адресной строке:
http://NAME/gii/extension
а если не включено ЧПУ URL, то:
http://NAME/web/index.php?r=gii/default/view&id=extension

В данном помощнике нужно заполнить несколько обязательных полей согласно изображения. Прежде всего Вам нужно иметь аккаунт на GitHub, название которого необходимо прописать в поле Vendor Name (у меня klisl). Это будет корневой каталог в котором будут создаваться папки каждого из ваших расширений, название которых прописывается в поле Package Name. Стоит отметить, что разработчики данного фреймворка рекомендуют использовать префикс «yii2-» в названии расширений (пакетов), являющихся расширениями Yii-2. Поэтому я указал yii2-mytest.
В поле Namespace нужно указать пространство имен вашего расширения чтобы автозагрузчик Composer смог отыскать файлы и чтобы название классов расширения не конфликтовали с одноименными классами других расширений и самого фреймворка. Лучше всего пространство имен указывать как название вашего аккаунта на GitHub\название расширения (пакета) без приставки «yii2-».
В качестве типа указывается расширение или же библиотека (содержащая классы), а в качестве лицензии обычно выбирается MIT, что значит бесплатно распространяется и используется кем угодно без ограничений на свой страх и риск.
Отправив заполненную форму помощника, по-умолчанию, у вас создастся 3 файла в папке runtime\tmp-extensions. Это файлы, которые изначально находятся в vendor\yiisoft\yii2-gii\generators\extension\default и потом копируются туда с подставленными значениями из формы.
Лично я данным помощником не пользуюсь и обычно беру за основу одно из других своих расширений. Вы можете взять за основу тестовое расширение, которое будет создано в демонстративных целях в данной статье. Ссылка на архив будет в конце статьи.
Помощник создания расширений в yii2 предполагает сразу после создания начальных файлов в временной папке runtime\tmp-extensions синхронизацию их с удаленным репозиторием типа GitHub и дальнейшей работой вплотную с помощью git. Я же расширения для фреймворков создаю как отдельные приложения. Например используя Опенсервер, в данном случае, я бы создал каталог klisl на уровне других приложений и в нем уже папки расширений:
W:\domains\klisl\yii2-mytest
Таким образом работаю над расширением локально и выгружаю на GitHub уже более-менее сформированное расширение с одновременной регистрацией его на Packagist (если планируется сделать свое расширение доступным для общественности) для окончательного тестирования.
Созданное таким способом расширение необходимо подключить к проекту в котором вы будете его тестировать, но об этом ниже.
Создание файлов расширения.
Создадим теперь файл composer.json нашего расширения.
Опять же, можно создать данный файл в интерактивном режиме используя консоль и команду
composer initПеред этим нужно перейти в корневой каталог расширения.
Если Composer установлен не глобально, то вместо
composer
нужно писать
php composer.phar
Данные тонкости не относятся к теме этой статьи.
Будет предложено ввести данные по названию проекта, автору, предложено сразу вписать нужные зависимости.
Все файлы composer.json имеют одни и те же поля и структуру, поэтому опять же, можно просто взять за основу другой подобный файл. Для нашего тестового расширения он будет выглядеть так:
{ "name": "klisl/yii2-mytest", "description": "Package", "type": "yii2-extension", "keywords": [ "yii2", "test" ], "license": "MIT", "authors": [ { "name": "Ivan Ivanov", "email": "ivan@ukr.net", "homepage": "https://github.com/klisl/yii2-mytest", "role": "Developer" } ], "minimum-stability": "stable", "require": { "yiisoft/yii2": "~2.0.0" }, "extra": { "bootstrap": "klisl\\mytest\\Bootstrap" }, "autoload": { "psr-4": { "klisl\\mytest\\": "src" } } }Немного подробностей.
В основном файле расширения «composer.json» нужно указать тип пакета:
"type": "yii2-extension",чтобы пакет можно было распознать как расширение Yii во время установки.
Когда пользователь запустит команду для установки расширения, файл vendor/yiisoft/extensions.php будет автоматически обновлён, чтобы включить информацию о новом расширении. Из этого файла приложение Yii может узнать, какие расширения установлены (информацию о установленных расширениях можно получить с помощью вызова yii\base\Application::extensions).
В объекте "require" указываются зависимости вашего пакета. Например стоит указать:
"require": { "yiisoft/yii2": "~2.0.0" },т.к. если расширение для фреймворка yii2, то и работать без него оно не может.
Важным моментом для многих расширений является возможность выполнить определенный код в процессе начальной загрузки приложения, еще до выполнения кода контроллера и прочего. Например если понадобится внедрить свои правила маршрутизации, контроллеры… В Yii2 для этого используется так называемый класс начальной загрузки. Класс начальной загрузки должен реализовывать интерфейс yii\base\BootstrapInterface. Пример класса автозагрузки я создам в нашем тестовом расширении, чтобы продемонстрировать данную возможность. На данном этапе нужно только его подключить в composer.json расширения, что сделано в поле
"extra": { "bootstrap": "klisl\\mytest\\Bootstrap" },
А в поле
"autoload": { "psr-4": { "klisl\\mytest\\": "src" } }я указал, что для автозагрузки классов расширения с пространством имен klisl\mytest нужно искать их в каталоге src. При этом применяется стандарт кодирования PSR-4, согласно которому используется пространство имен классов и файлы классов имеют названия соответствующие названиям находящихся в них классов. Подробнее https://zenwalker.me/blog/php-psr-0-vs-psr-4
С основным файлом расширения закончили. Так же, если вы планируете сделать ваше расширение общедоступным, следует создать файл README.md описывающий как устанавливать и использовать ваш пакет. Данный файл можно сформировать автоматически непосредственно при создании нового репозитория для вашего расширения на GitHub и потом отредактировать или же скопировать код другого подобного файла. Пример можно посмотреть в архиве с файлами тестового расширения.
Теперь создадим остальные файлы расширения согласно изображения его структуры и разместим в соответствующих папках.
Для демонстрации подключения стилей или скриптов создадим такой файлик:
Файл assets/css/style.css
.block{ max-width: 1170px; margin: 0 auto; } .red { color: red; }
Далее, двигаясь сверху вниз по изображению структуры нашего расширения создаем его контроллер:
Файл src/controllers/TestController.php
<?php namespace klisl\mytest\controllers; use Yii; use yii\web\Controller; use klisl\mytest\models\Tests; class TestController extends Controller { public $layout = 'main'; public function actionIndex() { // регистрируем ресурсы: \klisl\mytest\TestsAssetsBundle::register($this->view); $datas = Tests::find()->all(); return $this->render('index',[ 'datas' => $datas ]); } }
Для всех классов в каталоге src не забываем указывать обозначенное в файле composer.json расширения пространство имен klisl\mytest и далее в зависимости от папки в которой находится текущий класс. Так автозагрузчик Composera сможет его отыскать согласно стандарта psr-4.
Контроллер создается и используется стандартно. В нем я регистрирую класс TestsAssetsBundle для подключения нашего созданного выше файла стилей. Данный класс создадим чуть ниже.
Далее получаем данные из БД и передаем в вид.
Для демонстрации создания таблицы в базе данных для нужд расширения создаем файл миграции. Его можно создать обычным способом в основном приложении:
yii migrate/create testsи далее перенести в папку src/migrations расширения или создать вручную.
Класс миграции не должен содержать пространство имен.
Название таблиц стоит заключать в фигурные скобки со знаком процента спереди для того, чтобы к названию автоматически подставлялся префикс таблиц используемый пользователем (если установлен префикс в настройках данного пользователя). Префиксы указываются в файле:
- для basic (config\db.php);
- для advanced (common\config\main-local.php) в массиве db.
$this->createTable('{{%counts}}', [ 'id' => $this->primaryKey(), ... ], $tableOptions);
Файл src/migrations/m170306_083010_tests.php
<?php use yii\db\Migration; class m170306_083010_tests extends Migration { public function safeUp() { $tableOptions = null; //Опции для mysql if ($this->db->driverName === 'mysql') { $tableOptions = 'CHARACTER SET utf8 COLLATE utf8_general_ci ENGINE=InnoDB'; } //Создание таблицы IP пользователей $this->createTable('{{%tests}}', [ 'id' => $this->primaryKey(), 'ip' => $this->string(15)->notNull(), 'comment' => $this->string(255), ], $tableOptions); } public function safeDown() { $this->dropTable('{{%tests}}'); } }
Раз есть миграция значит должна быть модель для работы с данной таблицей.
Файл src/models/Tests.php
<?php namespace klisl\mytest\models; use Yii; use yii\db\ActiveRecord; class Tests extends ActiveRecord{ public function rules() { return [ [['ip'], 'ip'], [['comment'], 'required'], ]; } }
Теперь файл-представление (вид).
Файл src/views/test/index.php
<?php if (isset($datas)): ?> <div class="block"> <h3 class="red">Вывод тестовых данных</h3> <?php foreach ($datas as $data ): ?> <p><?=$data->ip?></p> <p><?=$data->comment?></p> <?php endforeach; ?> </div> <?php endif; ?>
Структуру MVC мы создали, осталось еще несколько файлов управляющих модулем.
Создаем файл выполняющийся при загрузке фреймворка (класс начальной загрузки)
Файл src/Bootstrap.php:
<?php namespace klisl\mytest; use Yii; use yii\base\BootstrapInterface; class Bootstrap implements BootstrapInterface{ //Метод, который вызывается автоматически при каждом запросе public function bootstrap($app) { //Правила маршрутизации $app->getUrlManager()->addRules([ 'test' => 'mytest/test/index', ], false); /* * Регистрация модуля в приложении * (вместо указания в файле frontend/config/main.php */ $app->setModule('mytest', 'klisl\mytest\Module'); } }
Напоминаю, что данный класс должен реализовывать интерфейс BootstrapInterface и его метод bootstrap для того, чтобы он выполнился при начальной загрузке приложения. Это нам нужно для регистрации своего правила маршрутизации - сделаем, чтобы ссылка на страницу расширения открывалась по ссылке
http://NAME/test
без указания названия модуля/контроллера/вида.
Так же тут мы регистрируем сам модуль, чтобы не просить пользователя его установившего с помощью Composer проделывать это вручную в файле frontend/config/main.php
Далее создаем класс модуля, т.к. наше расширение будет работать как отдельный модуль в yii-2.
Файл src/Module.php
<?php namespace klisl\mytest; use yii\base\Module as BaseModule; class Module extends BaseModule { public $controllerNamespace = 'klisl\mytest\controllers'; }
Тут мы указываем в свойстве $controllerNamespace путь к контроллеру модуля. Теперь мы добавили контроллер модуля в список контроллеров и маршрут, который создали немного выше сможет его найти.
Ну и завершающим файлом создадим файл с классом подключающим наш CSS файл к файлу-представления. Напомню, что данный класс мы зарегистрировали для представления нашего расширения в его контроллере:
\klisl\mytest\TestsAssetsBundle::register($this->view);
Файл src/TestsAssetsBundle.php
<?php namespace klisl\mytest; use yii\web\AssetBundle; class TestsAssetsBundle extends AssetBundle { public $sourcePath = '@vendor/klisl/yii2-mytest/assets'; public $css = [ 'css/style.css' ]; }
Тут мы указываем путь к папке со стилями и скриптами в свойстве $sourcePath и сами файлы в свойстве
$css и $js
Подключение локального расширения.
Т.к. расширение находится на локальном компьютере, необходимо указать Composerу находящемуся в корне основного проекта в котором будем его тестировать от куда нужно скачивать расширение. В нашем случае просто создастся ссылка на папку с ним.Для этого в файле composer.json yii-проекта добавим секцию:
… , "repositories": [ { "type": "path", "url": "../klisl/yii2-mytest" } ]
По значению поля «url» видно, что необходимо подняться на один уровень выше, то есть выйти в общий каталог проектов и далее подключить файл composer.json уже самого расширения.
Кроме этого нужно подключить его, т.е. обновить зависимости файла composer.json основного проекта, а так же чтобы обновился автозагрузчик классов у Composer. Для этого нужно выполнить команду из корня основного проекта:
composer require klisl/yii2-mytest:dev-master --prefer-source
После этого добавится новая строка с нашим расширением в файл composer.json в секции require:
"klisl/yii2-mytest": "dev-master"а так же ярлык на каталог расширения в папке vendor\klisl.
Расширение автоматически получит алиас, в нашем случае
@klisl/mytest
который будет вести на
…\vendor/klisl/yii2-mytest/src
т.к. в файле composer.json самого расширения есть такой блок:
"autoload": { "psr-4": { "klisl\\mytest\\": "src" } }Вы можете получить данный путь и вывести его на экран таким образом:
echo Yii::getAlias('@klisl/mytest');
Теперь наше расширение можно найти в файле vendor/yiisoft/extensions.php где очень наглядно видно куда ведет созданный алиас, а так же наличие массива bootstrap, в значении у которого находится путь к файлу автозагрузки расширения.
Для создания таблицы нужно перейти в корень основного проекта и выполнить миграцию:
yii migrate --migrationPath=@klisl/mytest/migrations --interactive=0тут мы указываем используя алиас @klisl/mytest путь к каталогу src расширения и далее в папку migrations к файлу миграции. Ключ --interactive=0 значит, что при выполнении данной команды не нужно спрашивать подтверждение о создании таблицы пользователя. Т.к. раз расширению она нужна, то создавать нужно в любом случае.
Все готово для запуска расширения!
Добавите пару строк в базу данных для тестирования.
Для открытия его страницы расширения нужно набрать в адресной строке
- если включено ЧПУ URL:
- если не включено:
Если вы увидели надписи значит все работает.
Перенос на удаленный репозиторий.
Далее можно инициализировать git в корне расширения и отправить его на удаленный репозиторий GitHub, в котором, предварительно, уже должен быть создан репозиторий с названием «yii2-mytest». Примерный набор команд для этого:git init git add . git commit -m "First commit" git remote add origin https://github.com/klisl/yii2-mytest.git git push -u origin master git tag -a 1.0 -m "New version" git push --tagsгде после строки git remote add origin нужно подставить адрес вашего репозитория. Как видите, он повторяет название корневой папки (поставщика) и папки с пакетом. Думаю работать с git вы уже умеете, раз учитесь создавать свои расширения. Так же, тут указываем версию пакета, что понадобится, если вы собираетесь опубликовать его в репозитории публичных расширений на сайте https://packagist.org
Сервис packagist.org используется Composer для поиска пакетов. Если планируете показать свой пакет общественности то после регистрации нужно будет указать URL к вашему пакету на GitHub по нажатию кнопки «Submit». Это если вкратце.
В файле README.md необходимо будет указать как ваш пакет устанавливается. Для этого нужно будет включить кроме описание самого приложения и примеров работы с ним такие строки:
Установка ------------------ * Установка пакета с помощью Composer. ``` composer require klisl/yii2-mytest ``` * Выполнить миграцию для создания нужной таблицы в базе данных (консоль): ``` yii migrate --migrationPath=@klisl/mytest/migrations --interactive=0 ```
Команда
composer require klisl/yii2-mytestобновит зависимости файла composer.json проекта, скачает само расширение и обновит автозагрузчик.
Не забудьте протестировать работу вашего расширения на этот раз уже при установке из удаленного репозитория согласно вашей же инструкции из файла README.md
Если тестировать будете в том же проекте что тестировали локальную версию расширения, не забудьте удалить из файла composer.json проекта секцию repositories и строку с зависимостью "klisl/yii2-mytest": "dev-master" (и запятую перед этой строкой). А так же таблицу из базы данных.
После этого выполните команду:
composer updateчтобы удалить локальное расширение из проекта.
Ссылка на архив с файлами тестового расширения тут.
ответ на комментарий Игорь от 27.10.2017
Покажите код из composer.json расширения.
ответ на комментарий Сергей от 27.10.2017
Мой пакет "sergwizard/yii2-ext": "@dev" находится по пути "url": "/opt/lampp/htdocs/yii2-extentions/yii2-ext" на компьютере.
У него такой composer.json
Когда я делаю в корне приложения composer update ,то вылетает ошибка
Your requirements could not be resolved to an installable set of packages.
Problem 1
- sergwizard/yii2-ext dev-master requires sergwizard/maxmind-geolite2-db ~1.0 -> no matching package found.
- sergwizard/yii2-ext dev-master requires sergwizard/maxmind-geolite2-db ~1.0 -> no matching package found.
- Installation request for sergwizard/yii2-ext dev-master -> satisfiable by sergwizard/yii2-ext[dev-master].
Potential causes:
- A typo in the package name
- The package is not available in a stable-enough version according to your minimum-stability setting
see
Когда убираб из композера "sergwizard/maxmind-geolite2-db": "dev-master"
то без него грузится.
ответ на комментарий Игорь от 27.10.2017
На https://packagist.org есть только версия dev-master данного пакета.
Как поменять dev-master на версию , например 1.0.3. . В гитхаб у меня проставлены соответствующие теги и релизы. Но при этом packagist.org показывает по прежнему (dev-master) ?
ответ на комментарий Игорь от 27.10.2017
ответ на комментарий Сергей от 27.10.2017
Но версия не обновляется, хотя код обновляется автоматически внесении изменений и git push -u origin master отправки на сервер. Автоматически версии не подхватываются.
ответ на комментарий Игорь от 27.10.2017
There is no license information available for the latest version (dev-master) of this package.
Попробуйте создать файл лицензии, вдруг в этом дело.
ответ на комментарий Игорь от 27.10.2017
Заодно получил исчерпывающую информацию по некоторым другим вопросам.