Autor wpisu: Śpiechu, dodany: 12.01.2014 20:46, tagi: php
I’ve always looked for a rational explanation of using traits in PHP and I think I’ve found one. Let’s say we have a bunch of status codes which are set using constants. To remind: constants can also be set in interfaces (notice that constant interface pattern is considered as a bad practice).
We are writing an utils library and simply don’t trust users :-) It means we need to check if status codes set on object are valid. One way is to keep status codes as a range from number to number. Validating is easy in that case. We’re simply check if status is in range. This is obviously not common. In that case we can use reflection to list all class constants. And what if we have unrelated hierarchies of objects? We must duplicate some code. It’s against DRY principle. Trait to the rescue!
Take look at my rich documented gist and see how it works at the bottom of listing. Code is licensed under MIT License, so grab it and use it.
Autor wpisu: matiit, dodany: 01.01.2014 18:21, tagi: php
Świat wolny od miliona require i include
PHP od wersji 5.3.0, a więc już od jakiegoś czasu wspiera przestrzenie nazw, czyli w oryginale namespace. Mówi się, że lepiej późno niż wcale, z tego powodu nie będę się rozwodził nad tym, że od wielu lat PHP było w tyle, zachęcało do budowania aplikacji w brzydkim stylu – trudno, od jakiegoś czasu wszystko idzie w lepszą stronę.
Nie trudno pewnie sobie wam przypomnieć sytuację, w której include był używany w co drugim pliku, nikt nie wiedział co się skąd bierze i tak dalej. Dzisiaj pokażę jak stworzyć małą aplikację w PHP korzystając z dobrodziejstw PSR, namespace, composer. Jak prosto jest używać zewnętrznych bibliotek i jak nie pogubić się we wczytywaniu masy plików w miejscach do tego nieprzeznaczonych.
Wyobraźmy sobie, że piszemy jakiś parser zbierający informacje. Mamy do wyciągnięcia dane z jakiejś strony – parsowanie HTML i zapisanie tego do bazy danych.
Zewnętrzne biblioteki
W celu ułatwienia sobie pracy, postanawiamy skorzystać z zewnętrznej biblioteki tworzenia zapytań HTTP. Wybieramy na przykład Guzzle.
Zacznijmy od zainstalowania composera. Proces instalacji jest banalnie prosty, więc nie ma sensu go opisywać. Daję tylko odnośnik: http://getcomposer.org/doc/00-intro.md#installation-nix
composer.json
Przejdźmy do stworzenia pliku, który będzie opisywał dla composera nasz projekt:
{ "name": "matiit/justForExample", "description": "Example for blogpost", "license": "MIT", "require": { "guzzle/guzzle": "3.8.*@dev" } }
Oraz wykonajmy polecenie composer install w katalogu z naszym projektem (lub php composer.phar install - w zależności od tego jak zaintstalowaliśmy composera).
Dostaniemy fajną strukturę:
. ├── composer.json ├── composer.lock └── vendor ├── autoload.php ├── composer │ ├── autoload_classmap.php │ ├── autoload_namespaces.php │ ├── autoload_real.php │ ├── ClassLoader.php │ └── installed.json ├── guzzle │ └── guzzle │ ├── build.xml I tak dalej wgłąb guzzle/
Mamy więc już zainstalowaną i prawie gotową do użycia bibliotekę guzzle. Proste, tak? Tak.
Teraz potrzebujemy „naszego kodu”. Warto utworzyć folder o nazwie src oraz pozmieniać trochę w composer.json, tak, aby korzystać z dobrodziejstw PSR-0.
Autor wpisu: stormfly, dodany: 31.12.2013 10:40, tagi: php
Autor wpisu: bastard13, dodany: 30.12.2013 15:22, tagi: oop
Autor wpisu: zleek, dodany: 18.12.2013 13:27, tagi: php, zend_framework
Autor wpisu: Jacek Skirzyński, dodany: 09.12.2013 23:54, tagi: php
Przyszedł czas na drugie spojrzenie na Phing – czym on jest napisałem w skrócie w poprzednim wpisie.
Parametry uruchomienia
To narzędzie konsolowe, więc jest uruchamiane za pomocą wywołania phing [opcje] [cel]
w konsoli (najlepiej w katalogu zawierającym plik build.xml
). W wywołaniu można umieścić parametry/opcje:
[nazwa celu]
– nazwa celu, który ma zostać wywołany; jeżeli się nie pojawi zostanie uruchomiony cel domyślny projektu (<project ... default="domyslny_cel"/>
);-h
/-help
– wyświetlenie ogólnej pomocy aplikacji;-l
/-list
– wyświetlenie listy celów zdefiniowanych wbuild.xml
;-f [plik]
/-buildfile [plik]
– nazwa pliku skryptu, jeżeli inna niżbuild.xml
;-D[właściwość]=[wartość]
– przekazanie do skryptu właściwości o podanej wartości;-propertyfile [plik]
– wczytanie podanego pliku z deklaracjami właściwości;
Cele
W poprzedniej sekcji wspomniałem o parametrze pozwalającym wyświetlić listę dostępnych celów. Jednak nie każdy cel powinien być uruchamiany „samodzielnie” – czasem jest potrzebny tylko do spełnienia jakichś podstawowych wymagań dla innego celu, który wykonuje faktyczne operacje. Przykładem może być cel, który wczytuje/ustala odpowiednie właściwości konfiguracyjne (np. ścieżki do katalogów, dane FTP etc.), wywołanie takiego celu samodzielnie do niczego nie doprowadzi. Dlatego takie „prywatne” cele można ukryć na liście za pomocą atrybutu <target ... hidden="true"/>
.
Kolejną i chyba nabardziej przydatną możliwością celów jest ustalanie dla nich zależności – na przykład, żeby wykonać cel „deploy” (który wgrywa pliki na serwer), należy najpierw te pliki/katalogi przygotować (np. usunąć pliki tymczasowe). W skrypcie Phing nie trzeba deklarować dodatkowo wywołań celów, od których zależy wykonanie bieżącego lub samemu wywoływać ręcznie cele w odpowiedniej kolejności. W tym celu wykorzystuje się atrybut <target ... depends="cel1,cel2,cel3"/>
Są jeszcze dwa pomocne atrybuty celów – if
, unless
. Pierwszy uruchamia cel tylko w momencie, kiedy zmienna o podanej nazwie jest zadeklarowana. Drugi ma działanie odwrotnie. Poniżej przykład:
<?xml version="1.0" encoding="UTF-8"?> <project name="HelloWorld" default="hello"> <property name="uruchomione" value="" /> <target name="hello" depends="cel1,cel2"> <echo>Hello</echo> </target> <target name="cel1" if="uruchomione"> <echo>cel 1</echo> </target> <target name="cel2" unless="uruchomione"> <echo>cel 2</echo> </target> </project>
Poniżej wynik uruchomienia (pojawiają się nagłówki wszystkich wywołanych celów, ale kod cel2
nie został wykonany ze względu na warunek zawarty w atrybucie unless
.
cim@cim-k52:~/public_html/Phing$ phing Buildfile: /home/cim/public_html/Phing/build.xml HelloWorld > cel1: [echo] cel 1 HelloWorld > cel2: HelloWorld > hello: [echo] Hello BUILD FINISHED Total time: 0.0581 seconds
Właściwości
Właściwości są swego rodzaju zmiennymi dla skryptu Phing i zostały już użyte w poprzednich przykładach. Warto pamiętać, że odwołania do właściwości mają budowę ${nazwaWlasciwosci}
, np. <echo>Wartość zmiennej: ${nazwa}</echo>
. Przydatne jest używanie kropek dla budowania hierarchii – ${aplikacja.baza.host}%
– można w ten sposób grupować właściwości co mocno zwiększa czytelność.
Do tej pory w przykładach pojawiały się właściwości z wartościami zadeklarowanymi w pliku build.xml
, jednak to nie jedyne możliwe źródła danych:
<property name="nazwa" value="wartosc" />
– pokazywany wcześniej sposób deklarowania zmiennej, w deklaracjach można odwoływać się do innych zmiennych (np. do jakiejś ścieżki dodać nazwe kolejnego katalogu);<property file="plik.properties" />
– wczytuje do skryptu właściwości zdefiniowane w podanym pliku; można użyć również dodatkowego atrybutu<property file="plik.properties" prefix="zPliku" />
co spowoduje dodanie prefiksu do wszystkich nazw właściwości znajdujących się w pliku;<echo>${env.PATH}</echo>
– odwołania z prefiksemenv.
pozwalają na dostęp do zmiennych środowiskowych (zależne od systemu);
W przypadku zdublowania nazw właściwości Phing będzie zwracał pierwszą wartość właściwości, żeby zmienić to zachowanie trzeba dodać do drugiej deklaracji atrybut <property ... override="yes" />
.
Podczas tworzenia ścieżek lub operacji plikowych pomocny może okazać się dostęp do ścieżki do katalogu projektu (zadeklarowanej w tagu <project ... basedir="/var/www/Projekt">
lub domyśnie ustawianej przez Phing). Ścieżka jest dostępna pod nazwą ${project.basedir}
.