ujovlado.dev

Yii framework a Composer

06.01.2014

Do Yii pridali vo verzii 1.1.14 (konečne!) podporu Composera. Nemyslím si však, že to urobili úplne najlepšie.

Composer

Composer je nástroj nástroj na správu závislostí v PHP. Umožní vám definovať závislosti vašich projektov tak, aby každý, kto bude váš projekt používať alebo ho vyvíjať, získal takú verziu závislostí, akú ste zadefinovali.

Keď začínate nový projekt v PHP, nemali by ste už sťahovať žiadny .zip, či .tar.gz archív ale rovno začať s Composerom. To znamená vytvoriť súbor composer.json s potrebnými závislosťami a jednoducho spustiť composer install.

Súbor composer.json s požiadavkou na Yii 1.1.14:

{
	"require": {
		"yiisoft/yii": "1.1.14"
	}
}

Z adresára, kde je tento súbor vytvorený následne spustíte:

user@pc:~project$ composer install

Výsledkom je nainštalovaný Yii framework v adresári vendor/yiisoft/yii (t.j. akoby ste stiahli archív a rozbalili ho tam) a vytvorený súbor composer.lock, ktorý presne popisuje a fixuje závislosti vašeho projektu.

Yii webapp

Yii poskytuje možnosť vygenerovať úvodnú webapp. Je akousi základnou kostrou projektu. Túto kostru vygenerujeme pomocou príkazu yiic. A keďže Yii má v composer.json časť bin, Composer nám pri inštalácii vytvoril symlink z vendor/yiisoft/yii/framework/yiic do vendor/bin/yiic.

user@pc:~project$ ./vendor/bin/yiic webapp web

Príkaz vytvorí v adresári web základnú kostru projektu. Tento adresár je potom nastavený ako DocumentRoot a obsahuje súbor index.php, ktorého kód je:

<?php

// change the following paths if necessary
$yii=dirname(__FILE__).'/../vendor/yiisoft/yii/framework/yii.php';
$config=dirname(__FILE__).'/protected/config/main.php';

// remove the following lines when in production mode
defined('YII_DEBUG') or define('YII_DEBUG',true);
// specify how many levels of call stack should be shown in each log message
defined('YII_TRACE_LEVEL') or define('YII_TRACE_LEVEL',3);

require_once($yii);
Yii::createWebApplication($config)->run();

Keďže používame Composer, chceme aby sa o závislosti staral on a nie my, preto by sme mali použiť jeho autoloader.

Yii a Composer autoloader

Zameníme teda require_once($yii); za require_once(dirname(__FILE__).'/../vendor/autoload.php'); a zmažeme definíciu premennej $yii.

Súbor index.php bude vyzerať takto:

<?php

// change the following paths if necessary
$config=dirname(__FILE__).'/protected/config/main.php';

// remove the following lines when in production mode
defined('YII_DEBUG') or define('YII_DEBUG',true);
// specify how many levels of call stack should be shown in each log message
defined('YII_TRACE_LEVEL') or define('YII_TRACE_LEVEL',3);

require_once(dirname(__FILE__).'/../vendor/autoload.php');

Yii::createWebApplication($config)->run();

A tu nastáva problém. Composer nevie, že má načítať Yii, t.j. súbor vendor/yiisoft/yii/framework/yii.php. Dá sa to vyriešiť jednoducho, no autorom Yii sa do toho moc nechce, a tak si musíme poradiť sami.

Riešením je úprava composer.json tak, aby Yii obsahoval autoload časť. Nie je ho však možné pridať do existujúcej require časti ale treba zadefinovať Yii ako “nový” balíček:

{
	"require": {
		"yiisoft/yii": "1.1.14"
	},
	"repositories": [
		{
			"type": "package",
			"package": {
				"name": "yiisoft/yii",
				"version": "1.1.14",
				"dist": {
					"url": "https://github.com/yiisoft/yii/releases/download/1.1.14/yii-1.1.14.f0fee9.tar.gz",
					"type": "tar",
					"shasum": "b405beeb3487c9c41f4e3b8b6b5c8d63068a294d"
				},
				"bin": [
					"framework/yiic"
				],
				"autoload": {
					"files": ["framework/yii.php"]
				}
			}
		}
	]
}

K archívu som pridal i jeho shasum (SHA1 checksum). V prípade, že sa checksum archívu nebude zhodovať so zadaným, Composer “vyhodí” chybu.

Následne treba zmazať priečinok vendor/yiisoft/yii a spustiť composer update:

user@pc:~project$ rm -rf vendor/yiisoft/yii && composer update

Spustiť len composer update nestačí, pretože Composer nezistí, že sa niečo zmenilo, pokiaľ sa nezmení číslo verzie.

Composer nainštaluje Yii aj s časťou autolad. Dôkazom by mala byť existencia súboru vendor/composer/autoload_files.php s vygenerovaným obsahom:

<?php

// autoload_files.php @generated by Composer

$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);

return array(
    $vendorDir . '/yiisoft/yii/framework/yii.php',
);

Teraz môžete do svojho Yii projektu pridať ďalšie závislosti a o ich načítanie sa postará Composer a jeho autoloader.

Záver

Takýmto spôsobom nemusíte riešiť len Yii, no môžete spravovať aj závislosti projektov, ku ktorým sú dostupné len archívy, prípadne ak máte len VCS prístup. Viac sa dočítate na stránke Composera, v časti Repositories/Types/Package.