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 nowszej Zmiany 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.