Jogg.About::$Me->RaVbaker

 

08

marca

2009

« Wishlista - czyli co zamierzam przeczytać oraz co ostatnio czytam/czytałem Praca z Gitem lokalnie, a z SVNem globalnie »

Mój(*) pomysł na ładowanie klas w PHP

W nawiazaniu do wpisu Prosty loader plików w PHP postanowiłem podzielić się moimi przemyśleniami w temacie pisania loaderów klas w PHP.

Ja polecam zasadę "convention over configuration". Nawet takie configuration jak podawanie: Load::load('folder1/folder2/*'); wydaje mi się zbędne. Tym bardziej polecane w komentarzach pomysły statycznych listy klucz-wartość z klasami i ścieżkami do plików z klasą wydaje mi się być nie na miejscu.

Więc skoro dysponowałbym czystym projektem i nic by mnie nie ograniczało, to użyłbym czegoś w tym stylu:

  1. Klasy pogrupowałbym w stosowne pakiety: do obsługi maili w folderze /Mailer, dla parserów w /Parser, te odpowiadające, za różnego rodzaju klasy użytkowe w /Utilities, a np. pliki z możliwymi do zgłoszenia przez parsery wyjątkami w folderze /Parser/Exception
  2. Kolejną czynnością byłaby konwencja nazywania klas. W związku z tym, że np. do obsługi maili byłaby klasa odpowiedzialna za wysyłkę i odbiór, to obie znalazłyby się w folderze /Mailer w plikach Sender.php i Reciver.php, a klasy nazywałyby się Mailer_Sender i Mailer_Reciver, no i podobnie z pozostałymi klasami. Np. parser XMLi w klasie Parser_XML i pod ścieżką /Parser/XML.php
  3. Myślę, że większość już łapie o co chodzi...

Teraz wystarczy tylko w standardowej metodzie __autoload() dopisać do tego odpowiednią obsługę, czyli zamianę znaków / na _ i można już używać wszystkich klas dostępnych w aplikacji w ogóle nie myśląc o ich ładowaniu. A także bez nadmiarowego doładowywania klas, których się nie potrzebuje. Dlatego w przykładowym pliku index.php w katalogu nadrzędnym dla wszystkich z klasami powinien być kod:


<?php
	define("APP_PATH", dirname(__FILE__));
	
	function __autoload($class) {
		$filepath = str_replace('_', '/', $class).".php";
		require_once APP_PATH.'/'.$filepath;
	}
?>

* Oczywiście, nie twierdzę, że jest to moje autorskie rozwiąznie. Jednak wydaje mi się jak najbardziej odpowiednie do projektów w których jest skomplikowania hierarchia klas. Ciekaw jestem co o nim sądzicie.

 

Komentarze

 
 
 

№ 1

08 marca 2009, 22:25:33

Trobin

Mnie osobiście takie rozwiązanie podoba się z dwóch powodów:
1. Istotnie nie ładuje się niepotrzebnych klas
2. Wymusza stosowanie określonej struktury katalogów, co pomaga utrzymać porządek w projekcie.
Jednak de facto mój kod bynajmniej nie miał mi służyć tylko do ładowania plików z klasami PHP, tylko ogólnie do ładowania wielu plików naraz :-).
Tak czy inaczej powyższy sposób przypadł mi go gustu.

 
 
 

№ 2

08 marca 2009, 22:34:37

BTM

Osobiście używam podobnego rozwiązania, ale z założenia konceptowego mam po prostu $base->className i ładowaniem zajmuje się __get()

No i przydał by się jakiś Throw w przypadku Twojego rozwiązania. U mnie sobie rzucam errora i w wypadku jakiegoś trywialnego obiektu robię stdClass coby skrypt mógł przejść gdzieś dalej (TYLKO jeżeli jest to na prawdę trywialny obiekt).

 
 
 

№ 3

08 marca 2009, 22:41:50

Rafał Piekarski

Ukrywanie błędów – nawet w sposób typu „ zwracam stdClass” wydaje się nieelegancki. Gdyż w ten sposób sam przed sobą chowasz błędy – które są IMHO jak najbardziej na miejscu. Przecież nie możesz oczekiwać, że stdClass ma takie same właściwości co Twoja klasa. ;-) Więc, zwrócenie wyjątku, gdy pliku nie ma to ok, ale ukrywanie błędów i przenoszenie ich na dalszy plan, gdzie jakiś inny obiekt korzysta z właściwości obiektu który jest niewłaściwy to jest trochę nieeleganckie. Mój kawałek kodu – nie miał być rozwiązaniem finalnym problemu ładowania klas, a bardziej chciałem przedstawić koncepcję, więc pominąłem zbędny kod odpowiedzialny za obsługę błędów zaciemniający całe rozwiązanie – ufając PHPowi, że sam powie „Class not found”, a programista dopisze to czego brakuje. ;-)

 
 
 

№ 4

08 marca 2009, 23:15:06

BTM

Rafał – nie ukrywam, rzucam wyjątek, więc sterowanie wraca w miejsce, które przygotowane jest na przechwycenie wyjątku i zastąpienie obiektu dummy-klasą. Może to być np. obiekt cache – skrypt dalej stwierdza, że cache jest przedawnione i wykonuje się inna gałąź kodu.

 
 
 

№ 5

09 marca 2009, 00:03:43

Zbigniew 'zibi' Jarosik

To rozwiązanie funkcjonuje np w Zend Framework. I paru innych.
Co do __autoload i wyjątków widzę taki problem, że … z __autoload nie możesz rzucić wyjątku.

 
 
 

№ 6

09 marca 2009, 08:11:27

dikamilo

Używam tego dokładnie tak samo :) (pomysł z Zenda), bardzo wygodne i nie trzeba się martwić o ładowanie czegokolwiek.

 
 
 

Dodaj komentarz

 

Podpis

 

URL

 

Treść
(z textile)

 
 
 
 

Flakoblog