Hirdetés

PHP függőségek: web szerver

PHP-nak vannak függőségei, bár nem egészen olyanok, mint egy embernek. Közvetlenül a webszerver felé vannak elvárásai, kicsivel közvetettebben pedig az operációs rendszer felé (gondoljunk csak a fájlrendszerek különbségeire például).

Ezeknek a függőségeknek a kiiktatása lehetetlen (persze, ha a PHP-t nem weben keresztül használjuk, nyilván nincs webszerveres függősége), viszont megpróbálhatjuk kisimítani, vagy legalább elrejteni a rendszerek közötti különbségeket. A kettő közül igazán okos megoldások az elsőre vannak, utóbbi esetében pedig fokozottan oda kell figyelni, hogyan is használjuk az erőforrásokat, most az elsőre adok egy ötletet.

Mikor PHP-s alkalmazásokat fejlesztünk, elsőnek mindig szükségünk van egy vázra, amibe a konkrét alkalmazást pakoljuk, ez lehet általunk készített vagy már kész keretrendszer is. Több példát is lehet látni arra, hogy bizonyos metódusok belsejében hatalmas if-else block-ok vannak arra vonatkozóan, hogy az adott környezet épp mit támogat az adott funkcionalitás elérése érdekében. Szerencsések vagyunk, mert a PHP objektum orientáltsága mindent megad nekünk, hogy ekkora hülyeségeket ne kövessünk el. Ami miatt még örülhetünk, hogy az idő előrehaladtával a különbségeket maga a PHP fogja lekezelni, ha nem is teljesen.

Saját rendszeremben úgy kezelem le a különböző webszervereket, hogy létrehoztam egy osztályt, ami a kapcsolatot biztosítja a webszerver felé a keretrendszer számára, ezen osztály kivételével semminek sincs kapcsolata vele, semmi sem fog közvetlenül a webszervertől (pl. $_SERVER, de még az említett osztálynak sincs köze a $_GET, $_POST super global tömbökhöz).

Az osztálynak a neve HttpWorker a System\Web\Hosting névtérben, ez látszólag sok mindenért felelős (szerver, kérés, válasz változók, fejlécek olvasása írása, HTTP kérés kiszolgálásának eleje, vége, de pl. nálam az aktuális handler-t is ez jelenti le a rendszer többi részének).

A HttpWorker-ben olyan módon vannak megoldva a különböző funkciók kiszolgálása, hogy a lehető legtöbb webszerver esetében működőképes legyen mindenféle extra varázslás nélkül. Ez szerintem jól hangzik, csak épp még nem leszünk vele kisegítve, mert sajnos mindent nem tud, ezért szükségünk lesz specializált worker-ekre, így született meg pl. az IISWorker osztályom.

<?php

namespace System\Web\Hosting;

class IISWorker extends HttpWorker {

public function __construct(array $server, array $get, array $post, array $cookies, array $files) {
parent::__construct($server, $get, $post, $cookies, $files);
}

public function ReadRequestHeaders() {
return version_compare(PHP_VERSION, '5.4.0') >= 0 ? getallheaders() : parent::ReadRequestHeaders();
}

public function ApplicationPhysicalPath() {
return $this->_server["APPL_PHYSICAL_PATH"];
}

}

Látszik, hogy a HttpWorker-ből származik, és csupán két metódust írok felül benne úgy, hogy a legjobban passzoljon az IIS-hez. Igen, a ReadRequestHeaders() kicsit csúnya azzal a verzióellenőzéses izével, de azt gondolom, hogy azoknál az elemeknél, amelyek elég alacsony szinten vannak, beleférnek ezek a hack-elések, hiszen pont ezért hoztuk létre ezeket az osztályokat.

Ezek még így rendben is vannak, de futáskor mi fogja eldönteni, melyiket kell használnia a rendszernek? Azzal nem lennénk kisegítve, ha pl. a bootstrap-ben kellene mindig kézzel meghatározni, mi is történjen, az valahogy nem profi, helyette használhatunk egy factory-t erre.

HttpWorkerFactory osztályt készíthetünk pl. erre a célra, nálam még ez elég primitív, egyszerű static cucc, ami a szerverváltozók alapján el tudja dönteni, IISWorker, ApacheWorker vagy az általános HttpWorker-t kell neki példányosítani a GetWorker() metódusában. (Azt gondolom mindenki látja, hogy ez egyelőre egy öntött vas rugalmasságú megoldás, de kezdetnek jó.)

Hirdetés