Hirdetés

PHP telepítése Windows 7, 8-ra (Vista-ra is szerintem)

Nem, Apache-ot nem telepítünk. Pfuj.

Windows-on a web server szerepét az Internet Information Services (IIS) fogja betölteni, ami amellett, hogy rendelkezik egy normális grafikus kezelőkonzollal, remekül tudja futtatni a PHP-t Windows-on egy pár kattintásos telepítés után, sőt, akár több verziót is fenn tudunk tartani vele könnyen.

PHP telepítését semmi esetre sem kézzel fogjuk végezni, a Microsoft ehhez is ad nekünk nem kis segítség a Microsoft Web Platform Installer személyében, amivel PHP mellet IIS modulokat telepíthetünk (fogunk is), de van itt ASP.NET-hez cucc, alkalmazások is megtalálható, szóval minden, ami webfejlesztéshez kellhet.

Első lépésként telepítsük fel a WPI-t a fenti linkről, a picike exe-t simán futtassuk böngészőből, kis szöszmötölés után meg fog jelenni egy katalógus keresővel a jobb felső sarkában, beállításokkal a jobb alsó részén.

Motorola

A Motorola-tól ocsmányabb céget még nem láttam, moslék népség.

Cégnél vannak (eredetileg Symbol) Motorla barcode reader-ek, amelyek össze vannak építve egy PDA-val, amin többnyire Windows CE fut. Erre kellett fejleszteni alkalmazást, és emiatt kerültem közelebbi kapcsolatba velük.

Az oldalukon semmit nem lehet megtalálni, ha egyáltalán működik, volt, hogy egy napon keresztül minden 404-et dobott, illetve még a keresőjük is visszahozta a saját 404-es hibaoldalukat.
A PDA-khoz való SDK megtalálása sem egyszerű, futott összesen három név alatt, és kb. csak a 2. napon sikerült megtalálnom a legfrissebb EMDK-t. Miután sikerült letöltenem, a következő probléma a feltelepítéssel volt, ugyanis képtelen volt felmászni Windows 7 + Visual Studio 2008 kombóra, szerezni kellett egy XP-s gépet hozzá, erről átmásolva a DLL-eket már ment a dolog.

Problémánk van a PDA-k WiFi-jével is, igyekeztem ezt is frissíteni (Fusion, ha mond valakinek valamit), csakhogy már nekünk nincs támogatásunk a PDA-k, mert X éevesek, ezért le sem tölthetem az újabb szoftvert, pedig a Motorola is nagyon jól tudja, hogy egy rakás sz.r azegész, olyan hosszú a change log. Kerülővel végül sikerült beszereznem a CAB fájlt, az oldal leírása szerint csak fel kell másolni az eszközre majd telepíteni. Aha, majdnem. Maga a telepítő nem csinál meg mindent, kézzel kell megoldani 3 DLL-nek a \Windows könyvtárba történő másolását cold boot esetén (alapból a Platform könyvtárba kerülnek egy-egy *.gz állományba).

WCF dependency injection

A dependency injection-t remélhetőleg már nem kell bemutatni, mi is lenne, ám azt úgy gondolom, kevesebben tudják, amibe sikeürlt belefutnom.

Történt ugyanis, hogy hősünk egy faék WCF service-t szeretett volna készíteni, amit sikerült is megépíteni, hasznos unit test-ekkel körülbástyázni, remekül működött.
A probléma akkor kezdődött, mikor tényleges service-ként kellett volna működésbe hozni, tesztelés alatt ugyanis nem történik nagy varázslat, simán példányosítással történik a működés ellenőrzés.

IIS-en host-olt WCF service-ek aktivációját mindig egy factory végzi, amit mi magunk is beállíthatunk, ha megnézzük a *.svc fájlunk markup-ját, abba az egyetlen direktívába kell felvennünk a Factory-nkat:

<%@ ServiceHost Language="C#" Debug="true" Service="SmartcardService.Authentication"
CodeBehind="Authentication.svc.cs" Factory="SmartcardService.Factory.ServiceFactory" %>

MVC

"A modell-nézet-vezérlő (MNV; angolul model-view-controller) a szoftvertervezésben használatos szerkezeti minta. Összetett, sok adatot a felhasználó elé táró számítógépes alkalmazásokban gyakori fejlesztői kívánalom az adathoz (modell) és a felhasználói felülethez (nézet) tartozó dolgok szétválasztása, hogy a felhasználói felület ne befolyásolja az adatkezelést, és az adatok átszervezhetők legyenek a felhasználói felület változtatása nélkül. A modell-nézet-vezérlő ezt úgy éri el, hogy elkülöníti az adatok elérését és az üzleti logikát az adatok megjelenítésétől és a felhasználói interakciótól egy közbülső összetevő, a vezérlő bevezetésével." - Wikipédia

Ezek után találkoztam egy ilyen osztállyal a codereview-on:

class mvc {

/* view-ok keresése, controller-ek (több vagy egy?) keresés, némi routing, minden végrehajtása, kacifántos kód */

}

Nem jött át. :DDD Van még egy router fájlja is, csak egy script, de hogy a $_SESSION miért van benne használva, rejtély.

ASP.NET MVC ClientDataTypeModelValidatorProvider

Az ASP.NET MVC-t nehéz nem szeretni, kimondottan jól össze van rakva, jó használni, és ugye alatta van a teljes .NET Framework minden jósággal (pl. Entity Framework). A .NET jellemzően jól felépített cucc, bárhonnan is nézzük, nehéz rajta fogást találni.

A héten sikerült egy olyan dologgal találkoznom, amit nehezen hittem el, gyakorlatilag rosszul (vagy legalábbis hülye módon) implementáltak az ASP.NET MVC-ben egy igen fontos dolgot: attribútum nélküli kliensoldali típusvalidációt.

Ha valaki már használta az MVC keretet, akkor tudhatja, hogy minden különösebb erőfeszítés nélkül reklamál kliensoldalon azért, ha egy numeric típus helyett szöveget írunk egy input-ba, majd el szeretnénk küldeni az adatokat. Ezt a varázslatot végzi nekünk a ClientDataTypeModelValidatorProvider, ami alapból regisztrálva van a ModelValidatorProviders-ben. Ez nagyon klassz, teljesen jól működik, a gond akkor adódott, mikor lokalizálni szerettem volna a validációs üzenetet.

PHP PDOStatement::getColumnMeta

A PHP-ról senki sem mondaná, hogy egy jól kivitelezett nyelv, inkább arra hajaz, hogy mindent a lehető leggyorsabban egy húzással megcsináljunk, az nem számít, hogyan.
Ékes példája ennek a PDOStatement::getColumnMeta, ahol mindennel megpróbálnak bennünket eltántorítani attól, hogy használjuk ahelyett, hogy értelmesen megépítették volna ezt a részét a PDO-nak. Mire is gondolok?

Az rendben van, hogy nem minden driver támogatja (igazából ezért van kint a figyelmeztetés is), akkor adjon vissza NULL (de ne FALSE-t :U ), és kész.
Azokban az esetekben, mikor a driver támogatja ezt a dolgot, nem sima array()-t kellene megadniuk, hogy "hát, valami ilyesmi jön vissza", hanem készíteni kellett volna egy egyszerű interface-t, ami összefog mindent. A PDO eleve arra lenne, hogy egy könnyen átjárható interfészt adjon a különböző adatbázisok felé, ehelyett meg itt hülyéskednek. :N

PHP dependency injection container

A dependency injection (függőségbefecskedzés, DI) lehetőséget ad arra, hogy megválasszuk és egyértelműsítsük, hogyan és miből akarjuk létrehozni alkalmazásaink egyes részeit. Kicsit hülyén hangzik, de erről van szó.

Fabian Potencier példájánál maradva (nagyvonalakban), ha van egy User osztályunk, aminek szüksége van valamilyen tárolóra, amiben ténylegesen lesznek a User property-ei, akkor azt ne a User ctor-ában példányosítsuk, hanem adjunk lehetőséget arra, hogy mindenki megválassza a saját módszerét.

Első:
class User {

protected $_storage;

public function __construct() {
$this->_storage= new SessionStorage();
}
}

Második:
class User {

protected $_storage;

public function __construct(IStorage $storage) {
$this->_storage= $storage;
}
}

Ugye az elsőt sokkal könnyebb használni (biztosan így van ez? :N ), ellenben lehetetlen testreszabni, hogy nekem konkrétan milyen tárolóm is van, itt csak egyfélére vagyok korlátozva. A második esetében a kód mindenképp hosszabb lesz, hiszen meg kell írnunk egy interface-t, majd ezt implementálva tudunk csak különféle storage megoldásokat szállítani a User-nek példányosításkor. Mindenki láthatja, hogy így gyakorlatilag akármilyen tárolási mechanizmussal előállhatunk, könnyen tudjuk implementálni a változást, de könnyebben is tudjuk használni az egészet, ha ez nem is egyértelmű annyira. Az első esetben fogalmunk sem lesz arról, hogy mi fog történni akkor, mikor egy User létrejön a rendszerünkben, ha ez egy kész library lenne, akkor hányan néznének bele a kódba, hogy ugyan, mi is van benne? (Főleg a kevésbé gyakorlottak, akiknek csak működő megoldás kell?)

PHP ViewEngine

Van egy php template inheritance nevű projekt, ami kiválóan használható arra, hogy egy ASPX/Razor-szerű renderelési technikát alkalmazzunk alkalmazásainkban: készíthetünk olyan oldalakat, amelyek gyakorlatilag csak a szerkezetét adják mindennek, majd az egyes valódi tartalmat megjelenítő oldalakon (view) rakhatjuk be különböző szekciókba az egyes elemeket akár egymásba ágyazva is.

Ami mindenképp rossz ebben a projectben az a nem OO megközelítés, illetve a debug_backtrace() használata. Az első gondon viszonylag gyorsan lehetett segíteni, a másikon már nem annyira (a legtöbb, amit hirtelen lehetett csinálni: debug_backtrace(defined('DEBUG_BACKTRACE_IGNORE_ARGS') ? DEBUG_BACKTRACE_IGNORE_ARGS : false);), így aztán hegesztettem egy teljesen sajátot, és összevetettem őket.

Sebességben a debug_backtrace() kikönnyítése nem sokat dobott (memóriahasználat biztosan csökkent), legrosszabb esetben (a PHPTI leggyorsabb futási ideje szemben az enyém leglassabb futási idejével) is a sajátom 25-30%-kal gyorsabb, míg egyéb helyzetekben néha 5-6-7-szer gyorsabb. :) Amin meglepődtam az az volt, hogy a PHPTI nem működött megfelelően, hibázott az egyes elemek összepakolásánál, ugyanis nem megfelelő sorrendben jelentek meg az elemek.

PHP iteráció

PHP-val képesek vagyunk megoldani azt, hogy egy-egy objektumunk iterálható legyen foreach-csel, avagy kompletten tömbként működjön. Most vegyük az egyszerűbbet, és nézzük meg, hogyan kell iterálható osztályt írnunk:

http://php.net/manual/en/class.iterator.php

Készen is vagyunk, örülünk.

De.

A PHP SPL könyvtárában akad egy olyan varázslat, amit IteratorAggregate-nek hívunk. Ez szintén segít megoldani a problémánkat, csak sokkal egyszerűbben. Itt csak egy metódust kell implementálnunk, ami visszaad egy ArrayIterator-t. Ugye, hogy sokkal szebb?!

De.

Van egy másik hatalmas előnye a második verziónak: gyorsabb.
Készítettem egy házitesztet, aminek az eredménye ez lett:
IteratorAggregate: 12,5+ másodperc
Iterator: Fatal error: Maximum execution time of 200 seconds exceeded in D:\xampp\htdocs\ref\index.php on line 26

PHP 5.4 - trait

A PHP 5.4-es verziója még nincs készen, de már most érdeme foglalkozni az újításokkal, hiszen a szokásos hibajavítások, teljesítményfokozások mellett nyelvi újdonságokat is fog hozni magával.

A címből villámgyorsan kiderül, mivel is szeretnék most foglalkozni: trait. PHP-ban ez egy új kód-újrahasználati lehetőséget biztosít számunkra, osztályainkat tudjuk bővíteni trait-ek használatával, de nem olyan módon, ahogyan azt öröklésnél megszokhattuk. Ha egy új osztályt származtatunk egy meglévőből, akkor tulajdonképpen a szülőt vertikálisan bővítjük, ezzel szemben a trait-ek ezt horizontálisan tudják megtenni.

Miért is jó ez nekünk? Szerintem mindenkivel előfordult már, hogy 2 osztályban hasonló dolgot szeretett volna megvalósítani, de örökléssel nem igazán azt érte volna el, amit szeretne, mert a két osztálynak egyébként semmi köze egymáshoz. Kézenfekvő példa a Singleton minta. Ezt magam is sokszor eljátszottam, eljátszom, hogy az osztályaim megírását azzal kezdem, hogy belezongorázom mindbe a Singleton-hoz szükséges elemeket, amelyek gyakorlatilag minden egyes osztálynál megegyeznek, ami hatalmas pazarlást jelenthet.