Trendy w programowaniu w PHP
Composer - wprowadzenie
Jedną z zalet otwartych narzędzi programowania takich jak Python czy PHP jest możliwość wykorzystania bibliotek, które są rozwijane przez różnych programistów. Pojawia się w związku z tym problem zależności różnych wersji języka i bibliotek. Zostały stworzone dwa systemy obsługi bibliotek, które rozwiązują ten problem:
PEAR: http://pear.php.net
Composer: https://packagist.org
Różnica między nimi jest taka, że Pear jest używany na poziomie systemu operacyjnego, a więc wszystkie aplikacje na danym serwerze uzyskują dostęp do tych samych bibliotek. Composer natomiast działa w obrębie konkretnej aplikacji.
Composer jest skryptem napisanym w PHP o nazwie composer.phar. Można go pobrać ze strony:https://getcomposer.org/. Wywołuje się go poleceniem:
php composer.phar
Zarówno w systemie Windowa jak i Linux może on zostać zintegrowany z systemem i obudowany skryptem o nazwie composer. Wywołujemy więc po prostu polecenie composer: (lub wybieramy prawym przyciskiem myszy z menu kontektowaego Windows).
Konfigurację Composera zapisuje się w pliku tekstowym, w standardzie json. Można go zainicjować wykonując polecenie:
composer init
W trakcie inicjowania można wyszukać biblioteki jakie są potrzebne. Na przykład po wyborze yii2 dostajemy plik:
Przykładowy wynik:
{
"name": "galicea/test1",
"description": "testowa aplikacja",
"require": {
"yiisoft/yii2": "^2.0"
},
"authors": [
{
"name": "dev",
"email": "[email protected]"
}
]
}
następnie wykonujemy instalację:
composer install
Paczki są instalowane w podkatalogu vendor.
Pełny opis Composera i pliku konfiguracyjnego:http://composer.json.jolicode.com/
Spis najważniejszych kluczy w pliku conposer.json:
name– nazwa pakietu
description– zwięzły opis pakietu
keywords– słowa kluczowe (dla wyszukiwarek)
license– licencja
require– lista wymaganych paczek wraz z ichwersjami.
autoload– definicje dla ładowarki (zob. odrębną część lekcji)
scripts– możliwość rozszerzenia działania composera (zobaczwięcej).
Pełen spis wszystkich możliwy kluczy oraz ich znaczeń znajduje się pod tym linkiem.
Zobacz też:
http://itcraftsman.pl/composer-czyli-jak-zarzadzac-zaleznosciami-w-php/
Yii1 i composer
Jeśli tworzymy aplikację która nie korzysta z Composera, należy przesunąć katalog vendor i plik composera do miejsca z którego będzie można przyłączać biblioteki. Poniżej mamy przykład dla aplikacji w yii1 (choć dla nowych aplikacji chyba lepiej od razu użyć yii2).
Tworzymy aplikację:
vendor/yiisoft/yii/framework/yiic webapp <nazwa aplikacji>
Teraz powinniśmy przesunąć pliki konfiguracyjne Composera (wraz z podkatalogiem vendor) do katalogu protected. Wówczas w pliku index.php możemy zdefiniować:
$yii=dirname(__FILE__).'/protected/vendor/yiisoft/yii/framework/yii.php';
Istnieje zminimalizowana wersja yii1, którą można użyć w miejsce dystrybucji standardowej:
https://github.com/square1-io/yii-framework
Wtedy mamy w pliku composer.json:
"require": {
"square1-io/yii-framework": "1.1.14"
}
Aby wykorzystać inne biblioteki, możemy użyć polecenia composer require. Na przykład:
composer require clevertech/yii-booster
Sekcja „require w naszym pliku composer.json zmieni się na:
"require": {
"square1-io/yii-framework": "1.1.14",
"clevertech/yii-booster": "^4.0"
},
Oczywiście musimy odpowiednio skonfigurować aliasy. W pliku konfiguracyjnym config/main.php dodajemy na początku:
Yii::setPathOfAlias('booster', dirname(__FILE__).'/../vendor/clevertech/yii-booster/src/');
Dodatkowo:
'preload'=>array('log','bootstrap'),
…
'components'=>array(
'bootstrap' => array(
'class' => 'booster.components.Booster'
),
Możemy już przetestować kontrolki (widgets) Bootstrapa. Na przykład dodając do views/site/index.php:
$this->widget('booster.widgets.TbButton', array(
'buttonType'=>'submit',
'context'=>'primary',
'label'=>'OK',
));
Joomla i Composer
Komponenty dla CMS Joomla można tworzyć także z użyciem Composera. Pomocny może być w tym projekt https://github.com/galicea/jcc (plik Composera znajdziesz w katalogu: https://github.com/galicea/jcc/tree/master/src/library).
Przestrzenie nazw i ładowarki
Przestrzenie nazw
Może się zdarzyć tak, że użyjemy takiego samego identyfikatora w dwóch różnych modułach php. Wówczas może dojść do nieoczekiwanych efektów i trudnych w diagnostyce błędów. Dlatego wprowadzono mechanizm przestrzeni nazw (namespaces). Wybierając przestrzeń nazw w jakiej ma operować nasz moduł, świadomie decydujemy jakie identyfikatory są dla niego widoczne.
Polecenie namespace jest umieszczane zawsze na początku modułu.
Przetestujmy, tworząc dwa moduły:
1) test1.php:
<?php
namespace ns1;
class test1 { public function id() { echo 'test1'; } }
2) test2.php:
<?php
namespace ns2;
class test1 { public function id() { echo 'test2'; }}
Stwórzy teraz moduł testowy
namespace ns1;
require("test1.php"); require("test2.php");
test1::id();
Jego uruchomienie powoduje wypisanie napisu 'test1'.
Jeśli w miejsce ns1 wpiszemy ns2, to wynikiem będzie napis 'test2'.
Autoloader
W wersji 5.0 php wprowadzono mechanizm automatycznego ładowania klas (zob.https://pl.wikibooks.org/wiki/PHP/Automatyczne_%C5%82adowanie). Umożliwia on ładowanie modułów zawierających definicję klas bez stosowania require lub include. Ładowanie w chwili użycia obiektu wykonuje funkcja __autoload.
Stwórzmy na przykład moduł definiujący klasę test. Jego nazwa powinna być zgodna z nazwą klasy, czyli test.php:
<?php
class test { public function id() { echo 'test'; }}
Moduł testowy:
<?php
function __autoload($class_name) {
include $class_name . '.php';
}
$obj = new test();
$obj->id();
W wersji php 5.1 wprowadzono możliwość używania wielu „ładowarek”. Informujemy o nich system funkcją spl_autoload_register(). Wywołując ją bez parametrów, nakazujemy użycie standardowej ładowarki:
spl_autoload_register();
test::id();
Jeśli używamy przestrzeni nazw, to standardowa ładowarka zakłada, że umieszczamy moduły w odpowiednich podkatalogach – o nazwie równej nazwie przestrzeni nazw. Możemy też używać innego rozszerzenia, niż php – na przykład class.php:
namespace ns1;
set_include_path('.');
spl_autoload_extensions('.class.php');
spl_autoload_register();
test1::id();
Autoloader i Composer
Autoloader jest jedną z funkcji „autoload” pliku composer.json definiujemy co ma być ładowane. Używany jest do tego standard PSR-0 lub PSR-4 (zobacz różnicę:). W obydwu wypadkach definiowany jest alias, którego możemy używać w miejsce ścieżki do katalogu. Na przykład:
use Jaspersoft\Client\Client;
wskazuje, że chcemy użyć modułu Client.php z przestrzeni nazw Jaspersoft/Client.
Przykład definicji w pliku composer.json:
"autoload": {
"psr-0": { "Album": "module/Album/src/" }
},
Composer na podstawie podanych defincji tworzy autoloadera w pliku vendor/autoload.php.
Autoloader w Yii
Framework Yii daje możliwość używania wielu ładowarek (autoloader) dopiero w wersji 2.0. W wersji 1.0 mamy tylko jedną ładowarkę (używaną przezYii::import()) i jedną przestrzeń nazw (http://www.yiiframework.com/doc/guide/1.0/pl/basics.namespace).
Chcąc używać bibliotek z własnymi przestrzeniami nazw trzeba nieco zmienić moduł yii.php - wykorzystując moduł Gautoloader: https://gist.github.com/mindplay-dk/4234540.
Po tej modyfikacji możemy zaimplementować rozszerzenie do Yii do obsługi raportów Jasperreport:
<?php
use Jaspersoft\Client\Client;
class jrs extends CComponent {
public function report($server="http://jasper.pwste.edu.pl:8080/jasperserver",
$username="jasperadmin",
$password="<haslo>",
$reportUri='/reports/report001') {
$cl = new Client($server, $username,$password,"");
$cl->setRequestTimeout(60);
$report = $cl->reportService()->runReport($reportUri, 'pdf');
....
}
}
W pliku konfiguracyjnym main.php możemy zarejestrować biblitekę Jaspersoft:
Yii::getAutoloader()->addNamespace('Jaspersoft', 'protected/extensions/jrs/Jaspersoft');
return array(
…
'import'=>array(
'ext.jrs.*',
...
),
'components'=>array(
'jrs'=>array('class'=>'ext.jrs.jrs'),
...