Migracja z poprzednich wersji
API komponentów MVC zmieniało się z biegiem czasu. Jeśli zacząłeś używać
Zend Framework we wczesnej wersji, postępuj według poniższych wskazówek
aby przeprowadzić migrację swoich skryptów aby używały nowej architektury.
Migracja z wersji 1.5.x do 1.6.0 lub nowszejZmiany w interfejsie obiektu uruchamiającego
Użytkownicy zwrócili naszą uwagę na fakt, że klasy
Zend_Controller_Front oraz
Zend_Controller_Router_Route_Module używały metod
obiektu uruchamiającego, które nie były zdefiniowane w
interfejsie tego obiektu.
Dodaliśmy teraz do interfejsu poniższe trzy metody aby upewnić
się, że własne obiekty uruchamiające będą poprawnie działać:
getDefaultModule(): metoda powinna zwracać
nazwę domyślnego modułu.
getDefaultControllerName(): metoda powinna
zwracać nazwę domyślnego kontrolera.
getDefaultAction(): metoda powinna zwracać
nazwę domyślnej akcji.
Migracja z wersji 1.0.x do 1.5.0 lub nowszej
O ile większość z podstawowych funkcjonalności i cała udokumentowana
funkcjonalność pozostały te same, to nastąpiła jedna istotna zmiana
w jednej nieudokumentowanej funkcjonalności.
Udokumentowanym sposobem tworzenia adresów URL w postaci camelCased
jest użycie znaku separatora w nazwie akcji; domyślnie separatorem
mogą być znaki '.' lub '-', jednak może to być skonfigurowane w
obiekcie uruchamiającym. Obiekt uruchamiający zmienia litery w
nazwie akcji na małe i używa separatorów aby otrzymać nazwę metody
akcji w postaci camelCasing. Jednak z tego powodu, że funkcje PHP
nie są wrażliwe na wielkość liter, mogłeś wciąż
tworzyć adresy w postaci camelCasing, a obiekt uruchamiający wciąż
otrzymywał na ich podstawie nazwę tej samej akcji. Na przykład adres
'camel-cased' zostałby zamieniony przez obiekt uruchamiający na
'camelCasedAction', a adres 'camelCased' na 'camelcasedAction';
z tego powodu że PHP nie jest wrażliwe na wielkość liter, w obu
przypadkach zostanie uruchomiona ta sama metoda.
Powoduje to problemy w klasie ViewRenderer gdy szuka ona skryptów
widoku. Podstawowym udokumentowanym sposobem jest zastępowanie
wszystkich separatorów wyrazów znakiem podkreślenia oraz zmiana
liter na małe. Wprowadza to niezgodność semantyczną pomiędzy akcjami
a skryptami widoków, a regulacja tego pozwoli na znajdowanie
skryptów widoków w każdej sytuacji. Teraz jeśli wywołamy metodę
'camelCased', separator wyrazów nie będzie już znajdować się w
nazwie i ViewRenderer spróbuje uruchomić inny plik --
'camelcased.phtml' zamiast 'camel-cased.phtml'.
Niektórzy programiści polegali na tej "funkcjonalności", która nigdy
nie była zamierzona. Wiele zmian w wersji 1.5.0 spowodowało, że
klasa ViewRenderer nie znajduje już plików widoków w taki sposób;
semnatyczna zgodność jest teraz wymuszona. Po pierwsze, obiekt
uruchamiający wymusza teraz wrażliwość na wielkość liter w nazwach
akcji. Oznacza to, że odwoływanie się do akcji używając w adresie
formy camelCasing nie będzie już dłużej prowadzić do tej samej
metody, do której prowadziło odwołanie za pomocą separatorów
wyrazów (np., 'camel-casing'). Teraz klasa ViewRenderer podczas
szukania skryptów widoku akceptuje jedynie formę z separatorami
wyrazów.
Jeśli okazało się, że polegałeś na tej "funkcjonalności", masz kilka
rozwiązań:
Najlepsza opcja: zmień nazwy skwoich skryptów wiodku. Plus:
kompatybilność wsteczna. Minus: jeśli masz dużo skryptów
widoku, które polegają na tym niezamierzonym zachowaniu,
możesz mieć dużo plików do zmiany.
Druga najlepsza opcja: klasa ViewRenderer teraz określa
nazwę skryptu widoku za pomocą klasy Zend_Filter_Inflector;
możesz zmodyfikować reguły określania nazwy, aby nie używać
separatorów wyrazów w nazwach akcji.
getInflector();
$inflector->setFilterRule(':action', array(
new Zend_Filter_PregReplace(
'#[^a-z0-9' . preg_quote(DIRECTORY_SEPARATOR, '#') . ']+#i',
''
),
'StringToLower'
));
]]>
Powyższy kod zmieni sposób określania nazwy skryptu widoku,
aby nie oddzielał słów za pomocą znaku podkreślenia; możesz
także usunać filtr 'StringToLower' jeśli
chcesz używać nazw skryptów widoku
w postaci camelCased.
Jeśli zmiana nazw skryptów widoku zajmie zbyt dużo czasu,
najlepszym sposobem będzie tymczasowe użycie powyższego kodu.
Najgorsza opcja: Możesz spowodować aby obiekt uruchamiający
uruchamiał akcje w postaci camelCased za pomocą nowej flagi
kontrolera frontowego, 'useCaseSensitiveActions':
setParam('useCaseSensitiveActions', true);
]]>
Pozwoli ci to wciąż używać formy camelCasing w adresach URL
i taie wywołanie będzie uruchamiać tę samą akcję jak podczas
użycia separatorów wyrazów. Jednak oznacza to, że oryginalny
błąd będzie wciąż występował; jeśli nie chcesz aby wystąpiły
problemy, użyj przynajmniej drugiej z przedstawionych opcji.
Zauważ też, że użycie tej flagi spowoduje wyświetlenie
informacji o tym, że jej użycie jest przestarzałe.
Migracja z wersji 0.9.3 do 1.0.0RC1 lub nowszej
Głównymi zmianami, jakie pojawiły się w wersji 1.0.0RC1 jest dodanie
i domyśle włączenie wtyczki ErrorHandler
oraz pomocniczej klasy akcji ViewRenderer.
Proszę przeczytaj uważnie dokumentację obu komponentów aby dowiedzieć
się jak one działają i jakie efekty mogą one mieć w twoich aplikacjach.
Wtyczka ErrorHandler jest uruchamiana jako metoda
postDispatch() w celu sprawdzenia czy wyrzucone zostały
wyjątki i ewentualnego przeniesienia żądania do określonego kontrolera
obsługi błędów. Powinieneś mieć taki kontroler w swojej aplikacji.
Możesz jednak wyłączyć taką obsługę błędów ustawiając w kontrolerze
frontowym parametr noErrorHandler:
setParam('noErrorHandler', true);
]]>
Pomocnicza klasa akcji ViewRenderer automatyzuje
przekazywanie widoków do kontrolerów akcji oraz automatycznie
renderuje skrypty widoku oparte na nazwie danej akcji. Głównym
problemem jaki możesz napotkać są akcje, które nie renderują
skryptów widoków, nie przekierowują i nie przenoszą żądania, z tego
względu, że klasa ViewRenderer będzie próbować
renderować skrypt widoku oparty na nazwie akcji.
Jest kilka strategii które możesz podjąc aby zaktualizować swój kod.
Krótkoterminowo możesz globalnie wyłączyć użycie klasy
ViewRenderer w kontrolerze frontowym w pliku uruchamiającym
przed uruchomieniem żądania:
setParam('noViewRenderer', true);
]]>
Jednak długoterminowo nie jest to dobra strategia, ponieważ będziesz
musiał pisać więcej kodu.
Kiedy będziesz gotowy do użycia funkcjonalności klasy ViewRenderer,
będzie kilka rzeczy które będziesz musiał sprawdzić w kodzie swoich kontrolerów.
Wpierw spójrz na metody akcji (metody kończące się na 'Action') i
sprawdź co one robią. Będziesz musiał wprowadzić zmiany, jeśli w
metodzie nie jest przeprowadzana żadna z poniższych czynności:
Wywołanie metody $this->render()Wywołanie metody $this->_forward()Wywołanie metody $this->_redirect()Wywołanie pomocniczej klasy akcji Redirector
Najprostszym sposobem jest wyłączenie automatycznego renderowania dla tej metody:
_helper->viewRenderer->setNoRender();
]]>
Jeśli żadna z twoich akcji nie renderuje, nie przenosi i nie
przekierowuje, możesz powyższą linię umieścić w metodzie
preDispatch() lub init():
_helper->viewRenderer->setNoRender()
// .. robimy coś dalej...
}]]>
Jeśli wywołujesz metodę render(),
i używasz klasycznej modularnej struktury
katalogów,
możesz potrzebować zaktualizować swój kod aby używał automatycznego
renderowania:
Jeśli renderujesz wiele skryptów widoków w jednej akcji,
nie musisz nic zmieniać w tej kwestii.
Jeśli wywołujesz metodę render() bez argumentów,
możesz po prostu usunąć te wywołania.
Jeśli wywołujesz metodę render() używając
argumentów i nie wykonujesz później innego kodu ani nie
renderujesz kolejnych skryptów widoku, możesz zmienić
wywołania aby korzystały z metody o tej samej nazwie, obiektu
$this->_helper->viewRenderer().
Jeśli nie używasz klasycznej modularnej struktury katalogów, jest
wiele sposobów ustawienia bazowej ścieżki widoków i specyfikacji
ścieżek skryptów, do czego możesz użyć klasy ViewRenderer.
Proszę przeczytaj dokumentację
klasy ViewRenderer aby uzyskać więcej informacji na
temat tych metod.
Jeśli używasz obiektu widoku z rejestru, konfigurujesz swój własny
obiekt lub używasz innej implementacji widoku, możesz przekazać ten
obiekt do obiektu ViewRenderer. Możesz to łatwo zrobić
w dowolnym momencie.
Przed uruchomieniem kontrolera frontowego:
W dowolnej chwili podczas procesu ładowania:
setView($view);
]]>
Jest wiele sposobów na zmodyfikowanie obiektu ViewRenderer,
włączając w to ustawienie innego skryptu widoku do renderowania,
zastąpienie wszystkich części ścieżki skrytu widoku (także przyrostka),
wybranie segmentu obiektu odpowiedzi w którym ma być zrenderowany
i kilka innych. Jeśli nie chcesz używać klasycznej modularnej
struktury katalogów, możesz określić inne specyfikacje ścieżek za
pomocą klasy ViewRenderer.
Zalecamy zaadaptowanie w swoim kodzie użycia wtyczki
ErrorHandler oraz pomocniczej klasy akcji
ViewRenderer z tego względu, że te funkcjonalności są
teraz składnikiem jądra.
Migracja z wersji 0.9.2 do 0.9.3 lub nowszej
W wersji 0.9.3 pojawiają się klasy pomocnicze akcji.
W związku z tym, poniższe metody zostały usunięte, z tego względu, że
teraz są one zawarte w przekierowującej
pomocniczej klasie akcji:
setRedirectCode(); użyj
Zend_Controller_Action_Helper_Redirector::setCode().
setRedirectPrependBase(); użyj
Zend_Controller_Action_Helper_Redirector::setPrependBase().
setRedirectExit(); użyj
Zend_Controller_Action_Helper_Redirector::setExit().
Przeczytaj dokumentację
pomocniczych klas akcji aby uzyskać więcej informacji o tym
jak można pobrać obiekty pomocnicze i jak nimi manipulować, oraz dokumentację
przekierowującej
pomocniczej klasy akcji w celu uzyskania informacji o ustawianiu
opcji przekierowania (a także o innych metodach dla przekierowań).
Migracja z wersji 0.6.0 do 0.8.0 lub nowszej
Od czasu poprzednich zmian, najbardziej podstawowe użycie
komponentów MVC pozostaje takie same:
Jakkolwiek, struktura katalogów została przebudowana, kilka
komponentów usunięto, kilku innym zmieniono nazwy, a także kilka
dodano. Zmiany to:
Klasa Zend_Controller_Router została usunięta
na rzecz rewrite routera.
Nazwa klasy Zend_Controller_RewriteRouter
została zmieniona na Zend_Controller_Router_Rewrite
i awansowała ona na standardowy router dostarczany z frameworkiem;
Zend_Controller_Front użyje go domyślnie, jeśli
żaden inny router nie zostanie ustawiony.
Nowa klasa trasy doa użycia z rewrite routerem została
przedstawiona, jest to
Zend_Controller_Router_Route_Module; kryje
ona w sobie domyślną trasę używaną przez MVC i wspiera moduły
kontrolerów.
Nazwa klasy Zend_Controller_Router_StaticRoute
została zmieniona na
Zend_Controller_Router_Route_Static.
Nazwa klasy Zend_Controller_Dispatcher została
zmieniona na Zend_Controller_Dispatcher_Standard.
Zmieniły się argumenty metody
Zend_Controller_Action::_forward(). Sygnatura
wygląda teraz następująco:
Parametr $action jest zawsze wymagany; jeśli
kontroler nie jest określony, to brana pod uwagę jest akcja
z obecnego kontrolera. Parametr $module jest
zawsze ignorowany, o ile parametr $controller
nie jest określony. Ostatecznie każdy z parametrów w
tablicy $params będzie dołączony do obiektu
żądania. Jeśli nie potrzebujesz określić kontrolera lub
modułu, ale potrzebujesz przekazać parametry, po prostu
określ te wartości jako null.
Migracja z wersji 0.2.0 lub z poprzednich do 0.6.0
Podstawowy sposób korzystania z komponentów MVC nie zmienił się;
nadal możesz użyć poniższego kodu:
addRoute('user', 'user/:username', array('controller' => 'user',
'action' => 'info'));
/* -- ustawić go w kontrolerze -- */
$ctrl = Zend_Controller_Front::getInstance();
$ctrl->setRouter($router);
/* -- ustawić katalog kontrolerów i uruchomić -- */
$ctrl->setControllerDirectory('/path/to/controllers');
$ctrl->dispatch();
]]>
Zalecamy użycie obiektu odpowiedzi (Response) do łączenia zawartości
i nagłówków. To pozwala na bardziej elastyczne zmiany formatu danych
wyjściowych (na przykład JSON lub XML zamiast XHTML) w twoich
aplikacjach. Domyślnie metoda dispatch() zrenderuje
całą odpowiedź, wyśle nagłówki i całą zawartość. Możesz także
użyć kontrolera frontowego aby zwrócił zawartość za pomocą metody
returnResponse(), a potem zrenderować odpowiedź używając
twojej własnej logiki. Przyszłe wersje kontrolera frontowego mogą
forsować użycie obiektu odpowiedzi przez wyświetlenie danych
wyjściowych.
Jest wiele dodatkowych funkcjonalności, które rozszerzają istniejące
API i są one opisane w dokumentacji.
Główne zmiany, na które musisz uważać, nastąpiły przy tworzeniu klas
pochodnych komponentów. Te zmiany to:
Zend_Controller_Front::dispatch() domyślnie
łapie wyjątki w obiekcie odpowiedzi i nie renderuje ich
aby zapobiec wyświetlaniu ważnych informacji systemowych.
Możesz zmienić to zachowanie na kilka sposobów:
Ustaw throwExceptions() w kontrolerze
frontowym:
throwExceptions(true);
]]>
Ustaw renderExceptions() w obiekcie
odpowiedzi:
renderExceptions(true);
$front->setResponse($response);
$front->dispatch();
// lub:
$front->returnResponse(true);
$response = $front->dispatch();
$response->renderExceptions(true);
echo $response;
]]>
Zend_Controller_Dispatcher_Interface::dispatch()
zamiast tokena dispatchera przyjmuje i zwraca teraz
obiekt .
Zend_Controller_Router_Interface::route()
przyjmuje i zwraca obiekt
zamiast tokena dispatchera.
Zmiany w Zend_Controller_Action to:
Kontruktor teraz przyjmuje dokładnie trzy argumenty,
Zend_Controller_Request_Abstract $request,
Zend_Controller_Response_Abstract $response,
oraz array $params (opcjonalny).
Zend_Controller_Action::__construct() używa
ich aby ustawić żądanie, odpowiedź, i właściwości
invokeArgs obiektu i jeśli nadpisujesz konstruktor,
powinieneś je także ustawić. Lepiej jednak użyj
metody init() aby skonfigurować instancję,
ponieważ ta metoda jest wywoływana jako ostatnia akcja
konstruktora.
Metoda run() nie jest już zdefiniowana jako finalna,
ale nie jest też już używana przez kontroler frontowy;
Jej jedynym celem jest użycie klasy jako kontrolera strony.
Przyjmuje ona teraz dwa opcjonalne argumenty,
Zend_Controller_Request_Abstract $request
oraz Zend_Controller_Response_Abstract $response.
Akcja indexAction() nie musi być już
zdefiniowana, ale jest zalecana jako domyślna akcja.
To pozwala routerowi RewriteRouter oraz kontrolerom akcji
na określenie innych domyślnych metod akcji.
Metoda __call() powinna być nadpisana aby
obsłużyć automatycznie niezdefiniowane akcje.
Metoda _redirect() przyjmuje teraz opcjonalny
drugi argument, kod HTTP, który ma być zwrócony z
przekierowaniem oraz opcjonalny trzeci argument,
$prependBase, który może zdecydować czy
bazowy adres URL zarejestrowany w obiekcie żądania ma być
dodany do adresu URL.
Właściwość _action nie jest już
zdefiniowana. Ta właściwość była obiektem
Zend_Controller_Dispatcher_Token, który
nie istnieje już w aktualnej wersji. Jedynym
zastosowaniem tokena było przechowanie informacji o
zażądanym kontrolerze, akcji i parametrach URL. Te
informacje są teraz dostępne w obiekcie żądania w
taki sposób:
_action->getControllerName().
// Poniższy przykład używa metody getRequest(), ale możesz także bezpośrednio
// użyć właściwości $_request; użycie getRequest() jest zalecane ponieważ klasa
// rodzica może nadpisać dostęp do obiektu żądania.
$controller = $this->getRequest()->getControllerName();
// Pobierz nazwę akcji z żądania
// Dotychczas dostęp do niej był za pomocą: $this->_action->getActionName().
$action = $this->getRequest()->getActionName();
// Pobierz parametry z żądania
// To się nie zmieniło; metody _getParams() oraz _getParam() teraz w prosty
// sposób wskazują na obiekt żądania.
$params = $this->_getParams();
$foo = $this->_getParam('foo', 'default'); // pobierz parametr 'foo', używając
// wartości 'default' jako domyślnej
]]>
Metoda noRouteAction() została usunięta.
Aby w poprawny sposób obsługiwać nieistniejące
metody akcji powinieneś przekierować je do domyślnej
akcji używając metody __call():
defaultAction();
}
throw new Zend_Controller_Exception('Nieprawdiłowa metoda');
}
]]>
Akcja Zend_Controller_RewriteRouter::setRewriteBase()
została usunięta. W zamian użyj
Zend_Controller_Front::setBaseUrl()
(lub Zend_Controller_Request_Http::setBaseUrl(), jeśli używasz
tej klasy).
Interfejs Zend_Controller_Plugin_Interface został
zamieniony na Zend_Controller_Plugin_Abstract.
Wszystkie metody przyjmują i zwracają obiekt
zamiast tokena dispatchera.