W Zend_Session stworzenie własnego adaptera polega formalnie na stworzeniu nowej klasy implementującej odpowiedni interfejs, lecz zdefiniowane tam metody sesja podpina funkcją session_set_save_handler(). Już to samo z siebie narzuca sporo ograniczeń. Po pierwsze, standardowy mechanizm sesji oczekuje, że funkcja read() odczytująca zawartość sesji o podanym ID, zwróci zserializowaną tablicę. Analogicznie, zserializowana tablica przekazywana jest do wykonującej zapis funkcji write(). Programiści z pietruszki założyli, że wszyscy pragną przechowywać wszystkie dane w postaci jednego wielkiego ciągu tekstowego, co mija się z rzeczywistością. Po pierwsze, ktoś może chcieć w MySQL-u wykorzystać do składowania sesji tabelę typu MEMORY o rekordowo szybkim czasie dostępu, lecz niezezwalającą na tworzenie pól typu TEXT/BLOB. Krytyczne dane najlepiej jest więc przechowywać w oddzielnych, specjalnie wydzielonych polach, a co do pozostałych, należy sprawdzić, czy nie został przekroczony rozmiar pola VARCHAR (255 znaków), o ile w ogóle ktoś chce takie pole mieć - to też nie jest przesądzone. W końcu wiele aplikacji korzysta ze sztywnego schematu tabeli sesji o ustalonej liczbie pól.
Nawet, jeśli nie korzystamy z typu MEMORY, przeniesienie np. ID użytkownika w wydzielone pole umożliwi później tworzenie zapytań odpytujących, ilu mamy aktualnie zalogowanych użytkowników lub co robią. W oddzielnym polu można przechowywać informację, na jakiej podstronie internauta się znajduje, która będzie powiązana z rejestrem zasobów serwisu i pozwoli na precyzyjne wyświetlenie takich danych administratorowi jednym prostym zapytaniem. Zastosowań jest sporo.
Dla programisty najlepiej byłoby, gdyby dostawał tablicę danych i sam decydował o tym, które dane zapisać w postaci zserializowanej, które w dedykowanych miejscach, lub które da się odtworzyć automatycznie przy starcie sesji. Można zapytać: jejku, masz problem. Odserializuj sobie albo pobierz odpowiedni obiekt Zend_Session_Namespace i działaj, lecz czy to nie mija się z logiką? Jaki jest sens pakowania danych tylko, by je zaraz rozpakować i spakować ponownie, tylko już poprawnie? Nie ma żadnego, a na dodatek marnujemy czas na takie działania (ziarnko do ziarnka, a zbierze się miarka). Drugie rozwiązanie również budzi wątpliwości co do klarowności kodu. Skoro jest to wewnętrzny mechanizm sesji, nie powinniśmy z niego wyskakiwać i odwoływać się naokoło, zwłaszcza, że sesja na dokładkę dalej niepotrzebnie nam wszystko serializuje.
Gdyby klasa Zend_Session całkowicie zerwała z dokonaniami ekipy PHP sprzed ładnych paru lat, mogłaby z łatwością zorganizować pracę adapterów w znacznie lepszy sposób. Jedyna wada całkowicie nowego kodu, jaką dostrzegam, to konieczność ręcznego wywołania hipotetycznej metody save() pod koniec skryptu w celu zapisania zmian w sesji. Umieszczenie tego w destruktorze odpada - obiekt bazy danych może przecież zostać zniszczony przed sesją, a dodatkowo sam destruktor zachowuje się też dziwnie w stosunku do obsługi plików. Twórcy PHP odżegnują się od tego, zwalając całą winę na serwer Apache.















Napisał Turgon w wtorek, 27 marca 2007 o 14:51
Zyx: Zepsuli, ale też apache nie jest bez winy. np. wykonanie CWD przed destruktorem i jaja są ;) . Z resztą sprawa życia obiektów, to po prostu masakra.