Heavymind
Gdyby ludzie rozmawiali tylko o tym, co rozumieją, zapadłaby nad światem wielka cisza.

19/07/2007

Zend Framework Tutorial - Pierwsze kroki z Zend Framework

Opublikowane jako: Off topic — Kubek Bartosz @ 10:25

Zend Framework Tutorial

cześć I

Pierwsze kroki z Zend Framework

Kubek Bartosz, www.heavymind.net

Artykuł powstał na bazie:
Getting Started with the Zend Framework
Rob Allen, www.akrabat.com

Wersja dokumentu 1.5
Copyright © 2007 - 2008

Założeniem tego samouczka jest pokazanie najbardziej podstawowego wykorzystania Zend Framework do napisania prostej aplikacji opartej o bazę danych.

UWAGA: Ten samouczek został przetestowany w oparciu o Zend Framework w wersji 1.5.1. Najprawdopodobniej będzie działał także z późniejszymi wersjami, jednak jest mało prawdopodobne by prawidłowo mógł być uruchamiany z wersjami wcześniejszymi niż wersja 1.0.0.

Spis treści:

Architektura Model-View-Controller

Jeśli chcielibyśmy przygotować najprostszy przykład kodu aplikacji w języku PHP, najprawdopodobniej napisali byśmy coś w na wzór:

<?php
include "common-libs.php";
include "config.php";
mysql_connect($hostname, $username, $password);
mysql_select_db($database);
?>

<?php include "header.php"; ?>
<h1>Home Page</h1>
<?php
$sql = "SELECT * FROM news";
$result = mysql_query($sql);
?>

<table>
<?php
while ($row = mysql_fetch_assoc($result)) {
?>
   <tr>
      <td><?php echo $row['date_created']; ?></td>
      <td><?php echo $row['title']; ?></td>
   </tr>
<?php
}
?>
</table>

<?php include "footer.php"; ?>

Z biegiem czasu, okazuje się jednak, że aplikacja takiego typu staje się niezarządzalana np. ze względu na to, że nasz klient nie przestaje żądać od nas kolejnych zmian w wyglądzie lub sposobie działania aplikacji, które to zmiany należy wykonać na wspólnym (HTML wraz z PHP) kodzie bazowym w wielu miejscach naszej dużej już wtedy aplikacji. Jeśli dodać do tego jeszcze jakiś przedział czasowy, po którym wracamy do naszej aplikacji, okazuje się że trudno nam się “rozczytać” z własnego kodu.

Jedną z metod zwiększenie zarządzalności kodu aplikacji jest rozdzielenie kodu na trzy różne części (które są również reprezentowane przez oddzielne pliki):

Model
Część “Modelu” aplikacji jest tą częścią, która skupia się na wyróżnieniu danych które mają być wyświetlone. W powyższym przykładowym kodzie jest nim zestawianie danych “news” pobrane z bazy danych. Tak więc “Model” generalnie skupia się na “logice biznesowej” aplikacji, pobieraniem i zapisywaniem danych z/do bazy danych.
View (Widok)
“Widok” to ta część aplikacji, która skupia się na wyświetleniu treści użytkownikowu. Zazwyczaj jest to kod HTML.
Controller (Kontroler)
“Kontroler” jest łącznikiem pomiędzy Modelem a Widokiem. Jego zadaniem jest zapewnienie, że właściwe dane (Model) są wyświetlane na właściwej stronie (Widok).

Zend Framework wykorzystuje architekturę Model-View-Controller (MVC), by oddzielić róże części Twojej aplikacji na poszczególne segmenty, dzięki czemu pisanie i późniejsze zarządzanie (rozbudowywanie) aplikacji staje się wiele prostsze.

Wymagania

Wymagania Zend Framework są następujące:

  • PHP 5.1.4 (lub nowszy)
  • Serwer www wspierający funkcionalnośc “mod_rewrite”.

Ten samouczek zakłada, że korzystasz z serwera Apache.

Pobieranie Zend Framework

Zend Framework może być pobrany z strony domowej projektu: http://framework.zend.com/download w formacie .zip lub .tar.gz

Struktura Katalogów

Mimo tego, że Zend Framework nie narzuca struktury katalogów dla aplikacji, dokumentacja Framework’a sugeruje nam korzystanie z uwspólnionego modelu struktury katalogów. Typ ten zakłada, że posiadamy pełną kontrolę nad serwerem Apache, jednakże na potrzeby tego samouczka, użyjemy pewnej modyfikacji, by ułatwić sobie pracę.

Rozpocznij poprzez stworzenie katalogu w głównym katalogu serwera (root directory) i nazwij go
zf-tutorial. Dzięki temu adres URL do naszej aplikacji będzie następujący:
http://localhost/zf-tutorial.

Stwórz następującą strukturę katalogów, która będzie przetrzymywała pliki naszej aplikacji:

zf-tutorial/
   /application
      /controllers
      /models
      /views
         /filters
         /helpers
         /scripts
   /library
   /public
      /images
      /scripts
      /styles

Jak zauważyłeś już na pewno, rozdzieliliśmy dla naszej aplikacji katalogi dla Modelu, Widoku i Kontrolera. Pliki dodatkowe tj. Obrazki, skrypty JavaScript oraz arkusze stylów CSS są przechowywane w całkiem oddzielnej od aplikacji gałęzi katalogów: public. Ściągnięte pliki bibliotek Zend Framework będą umieszczone w katalogu bibliotek library. Jeśli będziemy potrzebowali użyć jakichkolwiek dodatkowych bibliotek, powinny one również znaleźć się w tym katalogu.

Rozpakuj ściągnięte archiwum, ZendFramework-1.0.3.zip w moim przypadku, do tymczasowego katalogu. Powinieneś otrzymać podkatalog ZendFramework-1.0.3, który w sobie zawiera kolejną strukturę podkatalogów i plików. Następnie skopiuj zawartość podkatalogu library/Zend/ do katalogu zf-tutorial/library/. Po tej operacji Twój katalog zf-tutorial/library/ powinien zawierać pod-katalog nazwany Zend.

Bootstrapper

Główny kontroler Zend Framework’a, Zend_Controller jest zaprojektowany by obsługiwać strony internetowe w oparciu o “czyste URL’e”. Aby to osiągnąć, wszystkie żądania HTTP (wywołania stron) muszą przechodzić przez jeden plik : index.php, zwany w tym kontekście jako “bootstrapper”. Takie działanie zapewnia nam centralny punkt startu dal wszystkich naszych generowanych stron i upewnia nas, że środowisko aplikacji jest zawsze skonfigurowane w ten sam sposób. Osiągamy ten efekt poprzez stworzenie pliku .htaccess w głównym katalogu naszej aplikacji (application root directory), czyli zf-tutorial/.

plik zf-tutorial/.htaccess

RewriteEngine on
RewriteRule .* index.php

php_flag magic_quotes_gpc off
php_flag register_globals off

Ta reguła RewriteRule jest bardzo prosta i może być interpretowana jako: “dla każdego wywołania URL użyj pliku index.php w zamian”.

Poprzez zdrowy rozsądek i dla bezpieczeństwa naszej aplikacji, ustawiliśmy także kilka ustawień PHP ini. Prawdopodobnie już są one prawidłowo ustawione w głównym pliku ustawień PHP (php.ini), jednak chcemy mieć pewność, że tak jest.

Jednakże musimy nanieść poprawkę na nasze reguły przekierowań, ponieważ żądania obrazków, skryptów Java Script lub plików CSS nie powinny być nakierowywane na naszego “bootstrapper’a”. Dzięki temu, że trzymamy wszystkie tego typu pliki w publicznym katalogu, możemy “powiedzieć” serwerowi Apache, by traktował te pliki w specialny sposób, poprzez stworzenie kolejnego pliku .htaccess tworząc go w katatalogu zf-tutorial/public/:

plik zf-tutorial/public/.htaccess

RewriteEngine off

Mimo że nie jest to całkowicie potrzebne dla tego przykładu, możemy dodać jeszcze kolejne pliki .htaccess aby uchronić pliki naszej aplikacji oraz biblioteki przed niepowołanym dostępem z zewnątrz. Stwórzmy więc następujące dwa pliki:

plik zf-tutorial/application/.htaccess

deny from all

plik zf-tutorial/library/.htaccess

deny from all

Pamiętaj, że aby poprawnie używać w/w plików .htaccess, konfiguracja serwera Apache (plik httpd.conf) musi mieć ustawioną poprawnie dyrektywę “AllowOverride” na wartość “All“.

Plik index.php

Skoro zf-tutorial/index.php jest naszym centralnym plikiem “bootstrapper’a”, rozpoczniemy od następującego kodu:

zf-tutorial/index.php

<?php
error_reporting(E_ALL|E_STRICT);
date_default_timezone_set('Europe/London');
set_include_path('.' . PATH_SEPARATOR . './library'
   . PATH_SEPARATOR . './application/models/'
   . PATH_SEPARATOR . get_include_path());

include "Zend/Loader.php";
Zend_Loader::loadClass('Zend_Controller_Front');

// setup controller
$frontController = Zend_Controller_Front::getInstance();
$frontController->throwExceptions(true);
$frontController->setControllerDirectory('./application/controllers');

// run!
$frontController->dispatch();

Zauważ, że nie zamykamy sekcji kodu PHP poprzez znacznik ?> na końcu pliku. Jest to działanie celowe, ponieważ nie jest on wymagany, a nie umieszczenie go może być dla nas pożyteczne w przypadku trudnych do znalezienia błędów przekierowań. Błędy te powstają podczas przekierowywania stron (redirecting) funkcją header(), gdy gdzieś w kodzie pojawia się dodatkowa spacja (white space) za znacznikiem ?>

Prześledźmy teraz powyższy plik.

error_reporting(E_ALL|E_STRICT);
date_default_timezone_set('Europe/London');

Te linie kodu upewniają nas, że wszystkie powstałe podczas uruchamiania programu błędy będą wyświetlane na ekran (przy czym zakładam, że w konfiguracji PHP’a dyrektywa “display_errors” jest ustawiona na “On“). Ustawiamy także strefę czasową, co jest wymogiem specyfikacji PHP v.5.1+ względem każdej aplikacji.

set_include_path('.' . PATH_SEPARATOR . './library'
   . PATH_SEPARATOR . './application/models/'
   . PATH_SEPARATOR . get_include_path());

include "Zend/Loader.php";

Zend Framework jest zaprojektowany tak, że ścieżka do jego bibliotek musi się znajdować w “include path”, aby biblioteki te były poprawnie odnajdywane przez PHP. W ten sam sposób podajemy także ścieżkę do naszych plików Modelu, byśmy mogli później je łatwo wywoływać. Aby wystartować, musimy także zainkludować plik “ładowarki bibliotek” Zend_Loader, która pozwoli nam ładować później wszystkie inne klasy Zend Framework wedle naszych potrzeb.

   Zend_Loader::loadClass('Zend_Controller_Front'); 

Zend_Loader::loadClass ładuje klasę z odpowiedniego pliku, według podanej jako parametr nazwy klasy. Dzieje się to poprzez konwersję znaków podkreślenia (underscore) na separatory ścieżki (np: “/“) i dodanie przyrostka “.php” na końcu. W takim razie Zend_Controller_Front będzie odczytany z lokalizacji: Zend/Controller/Front.php. Jeśli wykorzystaż tę samą metodę do nazewnictwa własnych bibliotek/klas, bedziesz mógł także wykorzystać Zend_Loader::loadClass() by je ładować. Powyższa klasa to pierwsza jaką potrzebujemy – kontroler frontowy.

Kontroler frontowy wykorzystuje klasę Routera by żądaniom URL przypisywać odpowiednie funkcje PHP, które z kolei będą wykorzystane do generowania właściwej strony. Aby Router mógł wykonywać swoją pracę, musi on dostać informację, która część żądania URL jest wskazaniem na nasz plik index.php, tak by resztę adresu mógł odpowiednio wykorzystać. Tym zadaniem zajmuje się obiekt żądania (Request object). Wykonuje on świetną pracę w automatycznym określaniu bazowego adresu ULR (base URL), lecz jeśli nie uda mu się to, np. ze względu na nietypową konfigurację Twego środowiska, możesz mu w tym pomóc poprzez manualne nadpisanie wartości adresu bazowego funkcją: $frontController->setBaseUrl().

Musimy także skonfigurować kontroler frontowy, tak by wiedział gdzie szukać naszych kontrolerów:

$frontController = Zend_Controller_Front::getInstance();
$frontController->setControllerDirectory('./application/controllers');
$frontController->throwExceptions(true);

Jako że jest to aplikacja samouczka, która będzie działała na środowisku testowym, zdecydowałem poinstruować kontroler frontowy by “wyrzucał” wszyskie “wyjątki” (throw exceptions) jakie ewentualnie wystąpią. Domyślnie jest tak, że kontroler frontowy “wyłapuje” wszystkie obiekty wyjątków i przetrzymuje je w własności “_exceptions” obiektu “Response“. Obiekt odpowiedzi (Response object) przechowuje wszystkie informacje na temat odpowiedzi na zadane żądanie URL. Zawierają się w nim nagłówki strony (Headers), treść strony (Body content) i wspomniane obiekty wyjątków. Kontroler frontowy zajmuje się także automatycznym wysłaniem nagłówków i wyświetleniem treści strony tuż przed zakończeniem jego pracy.

Wszystko to może wydawać się zawiłe dla osoby po raz pierwszy korzystającej z Zend Framework. Z tego też względu “wyrzucamy” na ekran wszystkie wyjątki, by można było obserwować ewentualne błędy. Oczywiście na serwerze produkcyjnym ,takie rozwiązania nie powinny mieć miejsca.

Ostatecznie dochodzimy do sedna sprawy i uruchamiamy naszą aplikację:

// run!
$frontController->dispatch();

Jeśli w tym momencie w przeglądarce uruchomisz nastęoujący adres:
http://localhost/zf-tutorial/ dla testu, powinieneś zobaczyć następujący błąd:

Fatal error: Uncaught exception 'Zend_Controller_Dispatcher_Exception'
   with message 'Invalid controller specified (index)' in...

Oznacza to dla nas, że nie stworzyliśmy jeszcze naszej aplikacji. Zanim jednak się tym zajiemy, omówmy sobie co tak na prawdę chcemy zbudować.

Strona internetowa

Naszym celem będzie zbudowanie prostego programu do inwentarzu płyt CD. Strona główna będzie wyświetlać listę naszej kolekcji i pozwalać nam korzystać z funkcji dodawania, edycji i usuwania płyt. Jako miejsce przechowywania danych o naszej kolekcji wybierzemy bazę danych MySql o następującej strukturze:

Fieldname Type Null? Notes
id Integer No Primary key, Autoincrement
artist Varchar(100) No  
title Varchar(100) No  

Wymagane strony

Następujące strony muszą być więc przygotowane:

  • Stronę główną (home page) – będzie wyświetlać listę albumów i linki do edycji i ich usuwania. Również dostępny powinien być link do dodawania nowego albumu.
  • Stronę dodawania albumu – będzie wyświetlać formularz dodawania nowego albumu.
  • Strona edycji albumu - będzie wyświetlać formularz edycji istniejącego albumu.
  • Strona usuwania albumu – będzie wyświetlać stronę potwierdzania usunięcia albumu.

Organizacja stron

Zanim zaczniemy tworzyć nasze pliki, ważne jest by zrozumieć jakiej organizacji plików oczekuje od nas Zend Framework. Każda strona naszej aplikacji będzie rozumiana jako “akcja” (action), a akcje są grupowane w “kontrolery” (controllers). Dla przykładu dla ULR’a formatu
http://localhost/zftutorial/news/view, kontrolerem jest “news”, a akcją jest “view”. Rozwiązanie to istnieje po to by grupować pokrewne akcje. Więc dla przykładu kontrolera “news”, akcjami pokrewnymi mogły by również być “current” (bieżące wiadomości), “archived” (archiwum wiadomości) i “search” (wyniki wyszukiwania). Struktura MVC zaimplementowana w Zend Framework przygotowana jest również do obsługi modułów, które służą do grupowania kontrolerów. Jednak nasza aplikacja nie jest wystarczająco wielka by z nich korzystać.

Kontrolery Zend Framework’a mają zarezerwowaną specjalną nazwę dla jednej z akcji. Akcja ta nazywa się “index” i jest przeznaczona dla adresu URL takiego jak np:
http://localhost/zf-tutorial/news/. Jako że w podanym przykładzie nie ma podanej części URL odpowiadającej akcji (jest tylko “news” odpowiadająca nazwie kontrolera), domyślna nazwa akcji “index” będzie użyta. W przypadku gdyby w URL’u nie było podanej nazwy kontrolera, Zend Framework rezerwuje także nazwę domyślnego kontrolera dla takiego przypadku. Nie powinno być to już zaskoczeniem, że nazwą tą jest “index”. Reasumując, dla adresu URL: http://localhost/zf-tutorial/ wywołana zostania akcja “index” w kontrolerze “index”.

Jako że nasza plikacja ma być prosta, nie będziemy również zajmować się komplikowaniem “rzeczy” poprzez np. mechanizm do logowania użytkownika. Ten temat doczeka się może kolejnego samouczka….

Jako że mamy zaplanowane wykonanie czterech stron, które wszystkie dotyczą “albumów”, zgrupujemy je w jeden kontroler. Tak więc naszymi akcjami w kontrolerze będą:

Strona Kontroler Akcja
Główna strona Index Index
Dodawanie albumu Index Add
Edycja albumu Index Edit
Usuwanie album Index Delete

Proste i jasne – prawda?

Przygotowanie kontrolera

Jesteśmy już gotowi by przygotować nasz kontroler. W Zend Framework kontroler jest klasą, której nazwa składa się z {Nazwa kontrolera}Controller. Pamiętaj, by {Nazwa kontrolera} była napisana małymi literami, a rozpoczynała się z dużej litery. Klasa ta powinna się znajdować w pliku o nazwie {Nazwa kontrolera}Controller.php, a plik ten będzie stworzony w katalogu kontrolerów (controllers). Ponownie, dla pliku, {Nazwa kontrolera} powinna być napisana małymi literami i zaczynać się z dużej litery. Wewnątrz klasy kontrolera, każda funkcja akcji musi być publiczna. Nazwa akcji składa się z: {nazwa akcji}Acrion i tylko w tym przypadku nazwa ta powinna zaczynać się z małej litery.

Tak więc, jak już wcześniej ustaliliśmy, nasza jedyna klasa kontrolera nazywać się będzie IndexController i zdefiniowana będzie w pliku:

zf-tutorial/application/controllers/IndexController.php :

<?php
class IndexController extends Zend_Controller_Action {
   function indexAction() {
      echo "<p>in IndexController::indexAction()</p>";
   }

   function addAction() {
      echo "<p>in IndexController::addAction()</p>";
   }

   function editAction() {
      echo "<p>in IndexController::editAction()</p>";
   }

   function deleteAction() {
      echo "<p>in IndexController::deleteAction()</p>";
   }
}

Na dobry początek, ustawiliśmy każdą akcję tak, by tylko wyświetlała swoją nazwę. Dla testu możesz teraz przejść do poniższych adresów URL i zobaczyć rezultat.

URL Wyświetlony tekst
http://localhost/zf-tutorial in IndexController::indexAction()
http://localhost/zf-tutorial/index/add in IndexController::addAction()
http://localhost/zf-tutorial/index/edit in IndexController::editAction()
http://localhost/zf-tutorial/index/delete in IndexController::deleteAction()

W tym momencie mamy już poprawnie działający router, oraz dające się wywołać akcje dla każdej strony naszej aplikacji. Jeśli z jakiegoś powodu coś nie zadziałało, poszukaj pomocy w sekcji “Rozwiązywanie problemów” na końcu tego samouczka.

Nadszedł czas na zbudowanie widoku (View)

Przygotowanie widoku

W Zend Framework komponent odpowiedzialny nazywa się bardzo odkrywczo: Zend_View. Komponent ten pozwala nam oddzielić kod odpowiedzialny za wyświetlanie strony, od kodu funkcji kontrolerów.

Podstawowym użyciem Zend_View jest :

$view = new Zend_View();
$view->setScriptPath('/sciezka/do/pliku_widoku');
echo $view->render('plik_widoku.php');

Łatwo zauważyć, że jeśli umieścilibyśmy ten szablon kodu bezpośrednio w każdej akcji, powtórzylibyśmy się - co nie jest wskazane. Zresztą kod ten nie tyczy się tego, czym akcje powinny się zajmować. Wolelibyśmy raczej by obiekt widoku został zainicjowany w innym miejscu, byśmy mogli odwoływać się z naszych akcji bezpośrednio do już zainicjalizowanego obiektu widoku.

Projektanci Zend Framework’a przewidzieli tego typu problem, a rozwiązanie umieścili w “klasie akcji pomocniczych ” (action helper). Zend_Controller_Action_Helper_ViewRenderer zajmuje się zainicjowaniem obiektu widoku i umieszczeniem go w własności “widok” w kontrolerze ($this->view). Dzięki temu możemy go wygodnie używać jak i renderować skrypt widoku. Dla renderingu, obiekt Zend_View wyszuka w views/scripts/{nazwa kontrolera}/ plików, których nazwa jest zgodna z nazwą kontrolera, a rozszerzeniem nazwy pliku (przynajmniej domyślnie) jest .phtml. Tak więc plikiem skryptu do renderowania będzie: views/scripts/{nazwa kontrolera}/{nazwa akcji}.phtml. Zrenderowany plik zostaje dołączony do obiektu odpowiedzi (Response object). Obiekt odpowiedzi, dzięki strukturze MVC prócz wygenerowania ciała strony, zgromadzi również nagłówki HTTP oraz ewentualne błędy. Dalej, kontroler frontowy wyśle automatycznie ciało strony (body) poprzedzone nagłówkami w końcowej fazie przetwarzania. Zgrabnie i sprawnie.

Aby zintegrować widok z naszą aplikacją, musimy stworzyć kilka skryptów widoku z testowym kodem.

Żadnych poważnych zmian w kontrolerze nie musimy wykonywać. Dodamy jedynie nowe linie (pogrubiony tekst):

zf-tutorial/application/controllers/IndexController.php

<?php
class IndexController extends Zend_Controller_Action {
   function indexAction() {
      $this->view->title = "My Albums"; 
   }

   function addAction() {
      $this->view->title = "Add New Album"; 
   }

   function editAction() {
      $this->view->title = "Edit Album"; 
   }

   function deleteAction() {
      $this->view->title = "Delete Album";
   }
}

W każdej funkcji ustawiamy w obiekcie widoku pojedynczą własność. Na razie tylko tyle. Zauważ, że żadne wyświetlanie treści nie odbywa się w tym momencie! Stanie się to automatycznie pod koniec procesu przetwarzania kontrolera frontowego.

Teraz musimy dodać cztery skrypty widoku do naszej aplikacji. Pliki te są znane jako “szablony” (templates), a metoda renderująca render() oczekuje, że nazwa pliku szablonu będzie zbudowana z nazwy akcji i rozszerzenia .phtml. Rozszerzenie to ma symbolizować plik szablonu. Pliki szablonu muszą się znajdować w katalogu, którego nazwa jest nazwą kontrolera, z którego te akcje są wywoływane.
Tak więc dla nas są nimi:

zf-tutorial/application/views/scripts/index/index.phtml

<html>
   <head>
      <title><?php echo $this->escape($this->title); ?></title>
   </head>

   <body>
      <h1><?php echo $this->escape($this->title); ?></h1>
   </body>
</html>

zf-tutorial/application/views/scripts/index/add.phtml

<html>
   <head>
      <title><?php echo $this->escape($this->title); ?></title>
   </head>

   <body>
      <h1><?php echo $this->escape($this->title); ?></h1>
   </body>
</html>

zf-tutorial/application/views/scripts/index/edit.phtml

<html>
   <head>
      <title><?php echo $this->escape($this->title); ?></title>
   </head>

   <body>
      <h1><?php echo $this->escape($this->title); ?></h1>
   </body>
</html>

zf-tutorial/application/views/scripts/index/delete.phtml

<html>
   <head>
      <title><?php echo $this->escape($this->title); ?></title>
   </head> 

   <body>
      <h1><?php echo $this->escape($this->title); ?></h1>
   </body>
</html>

Przetestowanie aplikacji w tym momencie, powinno dać rezultat w postaci wyświetlania tytułów i pogrubionego tekstu.

Wspólny kod HTML

Bardzo szybko staje się oczywistym, że mamy sporo wspólnego kodu HTML w naszych widokach. Zorganizujemy teraz nasz kod w taki sposób by mieć dodatkowe dwa pliki : header.phtml oraz footer.phtml w katalogu z skryptami szablonów. Pliki te wykorzystamy do przechowywania wspólnego dla wszystkich naszych szablonów kodu HTML. Jedyne co więcej musimy zrobić to z naszych czterech szablonów odnieść się do dwóch nowych: nagłówka i stopki.

Nowymi plikami są:

zf-tutorial/application/views/scripts/header.phtml

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
   <head>
      <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
      <title><?php echo $this->escape($this->title); ?></title>
   </head>

   <body>
      <div id="content">

(Zauważ że rozszerzyliśmy zawartość uwspólnionego nagłówka, dzięki czemu spełniamy standardy! )

zf-tutorial/application/views/scripts/footer.phtml

      </div>
   </body>
</html>

Raz jeszcze nasze cztery skrypty widoku wymagają zmian:

zf-tutorial/application/views/scripts/index/index.phtml

<?php echo $this->render('header.phtml'); ?>
<h1><?php echo $this->escape($this->title); ?></h1>
<?php echo $this->render('footer.phtml'); ?>

zf-tutorial/application/views/scripts/index/add.phtml

<?php echo $this->render('header.phtml'); ?>
<h1><?php echo $this->escape($this->title); ?></h1>
<?php echo $this->render('footer.phtml'); ?>

zf-tutorial/application/views/scripts/index/edit.phtml

<?php echo $this->render('header.phtml'); ?>
<h1><?php echo $this->escape($this->title); ?></h1>
<?php echo $this->render('footer.phtml'); ?>

zf-tutorial/application/views/scripts/index/delete.phtml

<?php echo $this->render('header.phtml'); ?>
<h1><?php echo $this->escape($this->title); ?></h1>
<?php echo $this->render('footer.phtml'); ?>

Stylizacja

Mimo tego, iż jest to tylko samouczek, będziemy potrzebowali arkusza stylów CSS, by naszej aplikacji dodać choć trochę prezencji i czytelności. Nie jest to jednak takie proste, ponieważ jako że nie wiemy na jak rzeczywisty główny katalog aplikacji wskazuje adres URL, nie możemy z dowolnego miejsca w szablonie odnieść się do bezpośredniej ścieżki pliku CSS. Aby poradzić sobie z tym, użyjemy funkcji getBaseUrl(), która zawiera się w obiekcie żądania (Request) i jest przekazywana do widoku. Udostępni nam to tę część ścieżki URL, której nie możemy sami określić.

Aby tego dokonać, operację tę wykonamy w funkcji inicjalizacyjnej init(), która jest wywoływana przez konstruktor ( __construct() ) każdego kontrolera (specyfika Zend Framework). Dzięki temu ustawiona przez nas własność, będzie dostępna z poziomu każdej akcji.

zf-tutorial/application/controllers/IndexController.php

...
class IndexController extends Zend_Controller_Action {

   function init() {
      $this->view->baseUrl = $this->_request->getBaseUrl();
   } 

   function indexAction() {
…

Musimy dodać jeszcze odnośnik do pliku CSS w sekcji <HEAD> pliku header.phtml:

zf-tutorial/application/views/scripts/header.phtml

...
<head>
   <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
   <title><?php echo $this->escape($this->title); ?></title>
   <link rel="stylesheet" type="text/css" media="screen"
      href="<?php echo $this->baseUrl;?>/public/styles/site.css" /> 
</head>
…

Ostatecznie, powinniśmy stworzyć ów plik CSS:

zf-tutorial/public/styles/site.css

body,html {
   font-size:100%;
   margin: 0;
   font-family: Verdana,Arial,Helvetica,sans-serif;
   color: #000;
   background-color: #fff;
}

h1 {
   font-size:1.4em;
   color: #800000;
   background-color: transparent;
}

#content {
   width: 770px;
   margin: 0 auto;
}

label {
   width: 100px;
   display: block;
   float: left;
}

#formbutton {
   margin-left: 100px;
}

a{
   color: #800000;
}

Ta zmiana powinna zauważalnie poprawić wygląd naszej aplikacji.

Baza danych

Teraz, gdy mamy już rozdzieloną kontrolę aplikacji od jej widoku, nadszedł czas by przyjrzeć się części Modelu aplikacji. Przypomnijmy sobie, iż model jest tą częścią aplikacji, która zajmuje się jej “rdzeniem”, obsługą danych wejścia/wyjścia (często nazywany także jako “model biznesowy”). W naszym przypadku jest to obsługa bazy danych. Oczywiście Zend Framework ma przygotowane narzędzia, by wspierać pracę z bazą danych. Wykorzystamy klasę Zend_Db_Table, która zajmie się zapisywaniem, edycją i usuwaniem rekordów w bazie danych.

Konfiguracja

Aby móc użyć Zend_Db_Table, musimy podać informacje takie jak typ bazy danych, jej nazwa, użytkownik i jego hasło. Jako że nie preferujemy “zakodowania” na stałe danych konfiguracyjnych w aplikacji (”hard coding”), użyjemy do tego celu osobnego pliku konfiguracji.

Po raz kolejny, Zend Framework udostępnia nam gotowe rozwiązanie. Zend_Config jest elastycznym obiektem, który pozwala odczytywać dane konfiguracyjne z plików INI lub XML. My wykorzystamy typ INI.

zf-tutorial/application/config.ini

[general] 
   db.adapter = PDO_MYSQL
   db.config.host = localhost
   db.config.username = bart
   db.config.password = 123456
   db.config.dbname = zftest

Oczywiście powinieneś użyć własnych wartości dla nazwy użytkownika (username), hasła (password) i nazwy bazy danych (dbname), nie moich - przykładowych.

Używanie Zend_Config jest bardzo poste!:

$config = new Zend_Config_Ini('config.ini', 'general');

Zauważ, że w tym przypadku Zend_Config_Ini ładuje tylko jedną sekcję konfiguracyjną (”general”) z pliku config.ini, a nie każdą (owszem, mogło by tak być gdyby nie podać nazwy sekcji). Dodatkowo Zend_Config_Ini, traktuje parametr “kropki” do ustawiania hierarchii ustawień i dodatkowego grupowania ich. W naszym pliku konfiguracji, host, nazwa użytkownika, hasło i nazwa bazy są zgrupowane w : $config->db->config, dzięki zapisowi db.config.{własność}.

Nasz plik konfiguracji załadujemy w “bootstrapperze” :

zf-tutorial/index.php

...
Zend_Loader::loadClass('Zend_Controller_Front');
Zend_Loader::loadClass(’Zend_Config_Ini’);
Zend_Loader::loadClass(’Zend_Registry’); 

// load configuration
$config = new Zend_Config_Ini(’./application/config.ini’, ‘general’);
$registry = Zend_Registry::getInstance();
$registry->set(’config’, $config); 

// setup controller
…

Nowe linie to te pogrubionym tekstem. Najpierw inkludujemy dwie potrzebne nam klasy Zend_Config_Ini oraz Zend_Registry. W kolejnym kroku tworzymy obiekt konfiguracji, który z pliku application/config.ini ładuje sekcję konfiguracyjną pod nazwą “general”. Ostatecznie referencję do obiektu Zend_Config_Ini zapisujemy w “rejestrze” (korzystając z tego, dostarczonego przez Zend Framework: Zend_Registry ), by można było w dowolnym miejscu w aplikacji uzyskać dostęp do tej referencji i skorzystać z zapamiętanego obiektu konfiguracji.

Uwaga: Na potrzeby tego samouczka nie musieliśmy korzystać z zapisywania referencji $config (obiektu Zend_Config_Ini ) w rejestrze, jednak jest dobrą praktyką robić tak w “prawdziwej” aplikacji, w której prawdopodobnie posiadałbyś wiele więcej referencji do zapamiętania, niż tylko obiekt konfiguracji. Pamiętać jednak należy, iż rejestr jest czymś na wzór zmiennych globalnych i może być nie zawsze wskazane dana referencja była zapisana w rejestrze.

Przygotowanie Zend_Db_Table

Aby korzystać z Zend_Db_Table, musimy przesłać do niego ustawienia konfiguracyjne bazy danych, które właśnie załadowaliśmy z pliku konfiguracyjnego. Aby to uczynić, stworzymy instancję obiektu Zend_Db i zarejestrujemy w tym obiekcie adapter obsługi tabel funkcją statyczną: Zend_Db_Table:: setDefaultAdapter(). Po raz kolejny nowe linie dodamy do “bootstrappera”:

zf-tutorial/index.php

... 
Zend_Loader::loadClass(’Zend_Controller_Front’);
Zend_Loader::loadClass(’Zend_Config_Ini’);
Zend_Loader::loadClass(’Zend_Registry’);
Zend_Loader::loadClass(’Zend_Db’);
Zend_Loader::loadClass(’Zend_Db_Table’); 

// load configuration
$config = new Zend_Config_Ini(’./application/config.ini’, ‘general’);
$registry = Zend_Registry::getInstance();
$registry->set(’config’, $config);

// setup database 
$db = Zend_Db::factory(	$config->db->adapter,
$config->db->config->toArray() );
Zend_Db_Table::setDefaultAdapter($db); 

// setup controller
…

Tworzenie tabeli

Jako że używam bazy danych MySQL, polecenie SQL tworzące tabelę jest następujące:

CREATE TABLE album (
   id int(11) NOT NULL auto_increment,
   artist varchar(100) NOT NULL,
   title varchar(100) NOT NULL,
   PRIMARY KEY (id)  );

Uruchom powyższe polecenie w kliencie bazy MySQL, takim jak phpMyAdmin lub standardowa linia poleceń w konsoli klienta.

Dodawanie testowych albumów

Dodamy także kilka nowych rekordów do naszej tabeli, dzięki czemu będziemy mogli zaobserwować czy nasza “home page” zachowuje się prawidłowo. Dodajmy więc pierwsze dwa albumy z listy “Hot 100″ serwisu Amazon.co.uk.

INSERT INTO album
   (artist, title)
VALUES
   ('James Morrison', 'Undiscovered'),
   ('Snow Patrol', 'Eyes Open');

Przygotowanie modelu

Zend_Db_Table jest klasą abstrakcyjną, więc musimy ją uzupełnić przez dziedziczenie nadając jej specyfikę naszej tabeli albumów. Nie ma znaczenia jak nazwiemy naszą klasę, jednak ma sens ze względu na przejrzystość, by nazywać ją nazwą tabeli bazy danych, na której będzie operowała (choć nie jest to żadnym wyznacznikiem). Tak więc skoro nasza tabela nazywa się “album”, nasza klasa będzie nazywać się będzie Album. Aby Zend_Db_Table wiedział jak się nazywa tabela, którą ma obsługiwać, musimy tę nazwę podać ustawiając chronioną własność tego obiektu $_name nazwą tabeli w bazie danych. Co ważne, Zend_Db_Table zakłada, że obsługiwana przez niego tabela to auto-inkrementacyjny klucz główny nazwie “id“. Nazwa tego pola także może być zmieniona, jeśli to wymagane.

Naszą klasę Album, zapiszemy w katalogu modelów:

zf-tutorial/application/models/Album.php

<?php
class Album extends Zend_Db_Table {
   protected $_name = 'album';
}

Niezbyt skomplikowane – prawda? Na szczęście dla nas, nasze potrzeby są na tyle podstawowe, że wszelką funkcjonalność przez nas wymaganą dostarczy nam obiekt Zend_Db_Table sam w sobie. Jeśli jednak pisalibyśmy aplikację, gdzie potrzebowalibyśmy więcej funkcjonalności niż ta podstawowa, ten obiekt byłby właściwym miejscem na ich implementację. Dla przykładu mogły by to być funkcje “wyszukiwania”, które uwzględniając szczególne warunki i filtry, zwracały by kolekcję specjalnie przygotowanych danych.
Sam obiekt Zend_Db_Table daje także większe możliwości jego wykorzystania, poprzez podawanie mu informacji nt. relacyjnych tabel. Tym się nie zajmujemy w tym samouczku.

Budowa kolejnych stron

Wyświetlanie listy albumów

Teraz, gdy mamy już ustawioną konfigurację i informacje nt. bazy danych, możemy przejść do rzeczy: wyświetlenia listy albumów. Stanie się to przez klasę IndexController.

Dla jasności, każda akcja w IndexController będzie manipulowała danymi w tabeli bazy danych “album” używając do tego celu klasy Album. Dlatego też ma uzasadnienie, by załadować klasę albumu wraz z inicjalizacją IndexController (czyli w metodzie init() )

zf-tutorial/application/controllers/IndexController.php

...
function init() {
   $this->view->baseUrl = $this->_request->getBaseUrl();
   Zend_Loader::loadClass(’Album’); 
}
…

Uwaga: Powyżej widzimy przykład użycia Zend_Loader::loadClass() do ładowania plików klas naszego własnego autorstwa. Oczywiście powyższy przykład zadziuała poprawnie, ponieważ umieściliśmy ścieżkę plików modelów w ścieżce plików inkludowanych PHP (php include path) w naszym bootstrapperze.

Teraz wylistujemy wszystke albumy w akcji indexAction(), tak jak mamy to zaplanowane.

zf-tutorial/application/controllers/IndexController.php

...
function indexAction() {
   $this->view->title = "My Albums";

   $album = new Album();
   $this->view->albums = $album->fetchAll(); 
}
…

Metoda Zend_Db_Table::fetchAll() zwraca tablicę obiektów Zend_Db_Table_Rowset, która pozwoli nam poprzez iterację uzyskać dostęp do kolejnych rekordów pobranych z bazy danych. Uczynimy to w pliku szablonu:

zf-tutorial/application/views/scripts/index/index.phtml

<?php echo $this->render('header.phtml'); ?>
<h1><?php echo $this->escape($this->title); ?></h1>

<p><a href="<?php echo $this->baseUrl; ?>/index/add">Add new album</a></p>
<table>
   <tr>
      <th>Title</th>
      <th>Artist</th>
      <th>&nbsp;</th>
   </tr>

   <?php foreach($this->albums as $album) : ?>
   <tr>
      <td><?php echo $this->escape($album->title);?></td>
      <td><?php echo $this->escape($album->artist);?></td>
      <td>
         <a href="<?php echo $this->baseUrl; ?>/index/edit/id/<?php
            echo $album->id;?>">Edit</a>
         <a href="<?php echo $this->baseUrl; ?>/index/delete/id/<?php
            echo $album->id;?>">Delete</a>
      </td>
   </tr>
   <?php endforeach; ?> 

</table> 
<?php echo $this->render(’footer.phtml’); ?>

Uruchomienie adresu http://localhost/zf-tutorial/ w przeglądarce powinno wyświetlić śliczną listę (dwóch) albumów.

Dodawanie nowego albumu

Możemy teraz zaprogramować funkcjonalność dodawania albumów. Składają się na to dwa kroki:

  • wyświetlenie użytkownikowi formularza do wprowadzenia szczegółów,
  • przetworzenie wprowadzonych danych i zapisanie ich w bazie danych

Dokonamy tego w addAction():

zf-tutorial/application/controllers/IndexController.php

...
function addAction() {
   $this->view->title = "Add New Album";

   if ($this->_request->isPost()) {
      Zend_Loader::loadClass(’Zend_Filter_StripTags’);
      $filter = new Zend_Filter_StripTags();

      $artist = $filter->filter($this->_request->getPost(’artist’));
      $artist = trim($artist);
      $title = trim($filter->filter(
      $this->_request->getPost(’title’))); 

      if ($artist != ” && $title != ”) {
         $data = array(
           ‘artist’ => $artist,
           ‘title’ => $title,
         );
         $album = new Album();
         $album->insert($data);
         $this->_redirect(’/');
         return;
      }
   }
   // set up an "empty" album
   $this->view->album = new stdClass();
   $this->view->album->id = null;
   $this->view->album->artist = ”;
   $this->view->album->title = ”; 

   // additional view fields required by form
   $this->view->action = ‘add’;
   $this->view->buttonText = ‘Add’; 
}
…

Zwróć uwagę na to jak sprawdzamy wartość zmiennej $_SERVER[’REQUEST_METHOD’], by dowiedzieć się czy formularz został wysłany. Jeśli tak, odczytujemy nazwę artysty oraz albumu z tablicy POST i poprzez klasę Zend_Filter_StripTags upewniamy się, że nazwy te nie zawierają w sobie niedopuszczalnych tagów HTML. Wtedy, zakładając że nazwy te były podane poprawnie, wykorzystujemy naszą klasę modelu Album, by zapisać informację o nowym albumie do bazy danych.

Po dodaniu nowego albumu, przekierowujemy aplikację do głównej strony metodą kontrolera: _redirect().

Ostatecznie, przygotowujemy w tej akcji kontrolera także pustą klasę standardową, odpowiadającą swoimi własnościami temu, czego oczekuje od nas plik widoku dla tej akcji. Wypełniamy także własności, które nadają nazwę wyświetlaną i nazwę pola “Add” (”dodaj”).

Wychodząc krok naprzód, jako że formularz dla akcji dodawania albumu będzie identyczny z formularzem jego edycji, przygotujemy sobie wspólny plik skryptu szablonu _form.phtml, który zaimplementujemy do obu akcji dodawania (add.phtml) oraz edycji (edit.phtml).

Pliki szablonu potrzebne dla akcji dodawania to:

zf-tutorial/application/views/scripts/index/add.phtml

<?php echo $this->render('header.phtml'); ?>
<h1><?php echo $this->escape($this->title); ?></h1>
<?php echo $this->render(’index/_form.phtml’); ?>
<?php echo $this->render(’footer.phtml’); ?>

zf-tutorial/application/views/scripts/index/_form.phtml

<form action="<?php echo $this->baseUrl ?>/index/<?php
      echo $this->action; ?>" method="post">
   <div>
      <label for="artist">Artist</label> 
      <input type="text" name="artist" value="<?php
         echo $this->escape(trim($this->album->artist));?>"/>
   </div>
   <div>
      <label for="title">Title</label>
      <input type="text" name="title" value="<?php
         echo $this->escape($this->album->title);?>"/>
   </div>
   <div id="formbutton">
      <input type="hidden" name="id" value="<?php
         echo $this->album->id; ?>" /> 
      <input type="submit" name="add" value="<?php
         echo $this->escape($this->buttonText); ?>" />
   </div>
</form>

Jest to dość prosty kod. Jako, że chcemy wykorzystać skrypt _form.phtml także w akcji edycji, użyliśmy zmiennej $this->action w zamiast wpisywania “na sztywno” (”hard coding”) tej wartości w pliku. W taki sposób również postępujemy z wyświetlaniem nazwy guzika zatwierdzania.

Edycja Albumu

Edycja albumu jest niemal identyczna z dodawaniem go, więc i kod jest bardzo podobny:

zf-tutorial/application/controllers/IndexController.php

...
function editAction() {
   $this->view->title = "Edit Album";
   $album = new Album(); 

   if ($this->_request->isPost()) {
      Zend_Loader::loadClass(’Zend_Filter_StripTags’);
      $filter = new Zend_Filter_StripTags(); 

      $id = (int)$this->_request->getPost(’id’);
      $artist = $filter->filter($this->_request->getPost(’artist’));
      $artist = trim($artist);
      $title = trim($filter->filter(
      $this->_request->getPost(’title’))); 

      if ($id !== false) {
         if ($artist != ” && $title != ”) {
            $data = array(
               ‘artist’	=> $artist,
               ‘title’	=> $title,
            );
            $where = ‘id = ‘ . $id;
            $album->update($data, $where); 

            $this->_redirect(’/');
            return;
         } else {
            $this->view->album = $album->fetchRow(’id=’.$id);
         }
      }
   } else {
      // album id should be $params[’id’]
      $id = (int)$this->_request->getParam(’id’, 0);
      if ($id > 0) {
         $this->view->album = $album->fetchRow(’id=’.$id);
      }
   }
   // additional view fields required by form
   $this->view->action = ‘edit’;
   $this->view->buttonText = ‘Update’; 
}
…

Zwróć uwagę, że tym razem sprawdzamy, że jeśli nie było przesyłania danych w trybie POST, staramy się odczytać parametr “id” z tablicy REQUEST (przyp: która to z kolei jest sumą tablic GET i POST. Więc skoro nie było trybu POST podczas pierwszego sprawdzenia, oznacza to, że tak naprawdę w tablicy REQUEST poszykujemy zmiennej typu GET). Do tego celu korzystamy z metody getParam().

Plikiem szablonu dla edycji jest teraz:

zf-tutorial/application/views/scripts/index/edit.phtml

<?php echo $this->render('header.phtml'); ?>
<h1><?php echo $this->escape($this->title); ?></h1>
<?php echo $this->render(’index/_form.phtml’); ?> 
<?php echo $this->render(’footer.phtml’); ?>

Poprawki!
Nie powinno umknąć twej uwadze, iż addAction() oraz editAction() są bardzo do siebie podobne, a ich pliki szablonów niemal identyczne. Dlatego też warto by je poprawić gwoli reguły DRY (”Don’t Repeat Yourself” czyli “nie powtarzaj sam siebie”. Należy pamiętaż o optymalizacji kodu w każdym momencie!).

Pozostawiam jednak to jako ćwiczenie Tobie, drogi mój czytleniku.

Usuwanie Albumu

Aby dopełnić wszystkich założonych kroków, musimy stworzyć jeszcze akcję usuwania. Mamy już link usuwania wyświetlany przy każdym albumie z osobna, więc z rozpędu, moglibyśmy usuwać album w momencie kliknięcia na link. Jednak to nie jest dobry sposób. Przywołując ku pamięci specyfikację HTTP, nie powinno się wykonywać nieodwracalnych operacji z użyciem parametrów typu GET, lecz POST! Program “Google Web Accelerator” uświadomił tę potrzebę wielu ludziom!

Więc powinniśmy wyświetlić ekran potwierdzający tę operację z przyciskami “tak” lub “nie”.
Kod będzie wyglądał w pewien sposób podobnie do akcji dodawania i edycji:

zf-tutorial/application/controllers/IndexController.php

...
function deleteAction() {
   $this->view->title = "Delete Album";
   $album = new Album();

   if ($this->_request->isPost()) {
      Zend_Loader::loadClass(’Zend_Filter_Alpha’);
      $filter = new Zend_Filter_Alpha(); 

      $id = (int)$this->_request->getPost(’id’);
      $del = $filter->filter($this->_request->getPost(’del’));
      if ($del == ‘Yes’ && $id > 0) {
         $where = ‘id = ‘ . $id;
         $rows_affected = $album->delete($where);
      }
   } else {
      $id = (int)$this->_request->getParam(’id’);
      if ($id > 0) {
         // only render if we have an id and can find the album.
         $this->view->album = $album->fetchRow(’id=’.$id);
         if ($this->view->album->id > 0) {
            // render template automatically
            return;
         }
      }
   }
   // redirect back to the album list unless we have rendered the view
   $this->_redirect(’/'); 
}
…

Po raz kolejny, wykorzystujemy trik z sprawdzaniem typu zapytania (GET, POST) by dowiedzieć się, czy mamy wykonać operację wyświetlenia ekranu potwierdzającego usuwanie, czy po prostu usunąć album z bazy danych za pomocą klasy Album. Tak samo jak dodawanie rekordu (insert) i jego edycja (update) w tabeli bazy danych, wykonuje się usuwanie – przez wywołanie Zend_Db_Table::delete().

Zwróć uwagę, że wychodzimy z funkcji (return;) zaraz po ustawieniu treści odpowiedzi. Jest to zamierzone działanie by wyświetlić informację o usuwanym albumie, bez odwoływania się do kolejnych funkcji w tej akcji (w szczególności by uniknąć _redirect() ).Także, jeśli choć jeden z zapisanych warunków zawiedzie, zostajemy przeniesieni na stronę domową, a konstrukcja tych warunków pozwala posiadać tylko jedną metodę przekierowania ( _redirect() ) na końcu całej akcji.

Szablon jest prostym formularzem:

zf-tutorial/application/views/scripts/index/delete.phtml

<?php echo $this->render('header.phtml'); ?>
<h1><?php echo $this->escape($this->title); ?></h1>

<?php if ($this->album) :?>
   <form action="<?php echo $this->baseUrl ?>/index/delete" method="post">
      <p>Are you sure that you want to delete ‘
         <?php echo $this->escape($this->album->title); ?>’ by ‘
         <?php echo $this->escape($this->album->artist); ?>’? </p>
      <div>
         <input type="hidden" name="id" value="<?php
            echo $this->album->id; ?>" />
         <input type="submit" name="del" value="Yes" />
         <input type="submit" name="del" value="No" />
      </div>
   </form>

<?php else: ?>
   <p>Cannot find album.</p>
<?php endif;?> 

<?php echo $this->render(’footer.phtml’); ?>

Rozwiązywanie problemów

Jeśli napotkałeś problemy z działaniem którejkolwiek akcji innej niż index/index, to najprawdopodobniej router nie był w sanie określić bazowego adresu katalogu dla Twojej aplikacji. Poprzez moje własne doświadczenia, dochodzę do wniosku, że najczęstszą przyczyną takiego zachowania jest przypadek, gdy URL twojej aplikacji nie odpowiada ścieżce do głównego katalogu (root folder) twojej aplikacji.

Jeśli więc prezentowany kod nie zadziałał na Twoim środowisku, powinieneś spróbować ustawić $baseURL na poprawną wartość manualnie:

zf-tutorial/index.php

...
// setup controller
$frontController = Zend_Controller_Front::getInstance();
$frontController->throwExceptions(true);
$frontController->setBaseUrl(’/mysubdir/zf-tutorial’); 
$frontController->setControllerDirectory(’./application/controllers’);
…

Powinieneś zamienić wyrażenie ‘/mysubdir/zf-tutorial/‘ poprawną ścieżką wskazującą na katalog w którym znajduje się index.php. Dla przykładu, jesli twój URL wskazujący na plik index.php to jest http://localhost/~misiu/zf-tutorial/index.php, wtem poprawny adres bazowy to: ‘/~misiu/zf-tutorial/‘.

Podsumowanie

W tym momencie możemy już podziwiać naszą prostą, acz w pełni funkcjonalną, opartą o strukturę MVC aplikację zbudowaną na środowisku Zend Framework. Mam nadzieję, że znalazłeś tutaj pożyteczne dla siebie informacje i jesteś zadowolony z efektór swojej pracy. Jeśli znalazłaś jakiekolwiek uchybienia, błędy bądź niejasności, proszę poinformuj mnie o tym : kubek.bartosz@gmail.com.

Ten samouczek daje jedynie ogólny pogląd na podstawowe możliwości Zend Framework. Przedstawione wyżej biblioteki to jedynie mała część całości, którą można wykorzystać do wielu celów. Najlepszym kolejnym krokiem po zapoznaniu się z przedstawionymi tutaj podstawami, jest rozpoczęcie czytania “instrukcji użytkownika” (manual) na oficialnej stronie frameworka (http://framework.zend.com/manual), a także z wiki (http://framework.zend.com/wiki). Jeśli będziesz już gotów do pisania własnych aplikacji w tym framework’u, zapoznanie się z materiałem na stronie dla developerów (http://framework.zend.com/developer) będzie także dobrym pomysłem.

Repozytorium SVN

Opisywana wyżej aplikacja testowa jest dostępna do pobrania za pośrednictwem systemu kontroli wersji Subversion (SVN), na serwerach udostępnionych przez usługę Google Code. Kod źródłowy kolejnych wersji tego samouczka, które to powstawały ze względu na kolejne wersje Zend Framework, został odpowiednio rozdzielony, na tzw. tagi. Tak więc są nimi:

Aby skorzystać z w/w repozytoriów, należy użyć jednego z istniejących klientów SVN, tj. np.: KSVN (dla KDE linux), TortoiseSVN (dla windows), lub po prostu CLI klienta SVN w *nix systemach.

Kod aplikacji zawarty w repozytorium można także przeglądać poprzez przeglądarkę internetową, umieszczając adres repozytorium w pasku adresu.

Pozdrawiam
Kubek Bartosz



Komentarze: 161 »

  1. z reguły nie komentuje niczego ;-) ale tym razem nie mogę się powstrzymacć - bardzo fajna tutka ;-)

    Komentarz od Kosmowariat — 22/07/2007 @ 17:02

  2. no i od razu komentarz nr 2 ;]
    jeśli kopiujecie kod to pamiętajcie o zmianie odwrotnych apostrofów(`) na właściwe (’) :-)
    ja jednej pary nie zmieniłem i pół godziny w plecy ;(

    Komentarz od Kosmowariat — 23/07/2007 @ 00:02

  3. @Kosmowariat:
    Rzeczywiście, trudno mi zmusić ten system blogowy do poprawnego wyświetlania kodu. Może uda mi się to poprawić z czasem.
    Pozdrawiam!

    Komentarz od Kubek Bartosz — 23/07/2007 @ 12:04

  4. Przydałaby się jeszcze wersja PDF ;)

    Komentarz od programowanie — 23/07/2007 @ 18:54

  5. Poprawiłem sekcje kodu PHP by zwiększyć czytelność.
    Cały samouczek mieści się na jednej stronie, mam nadzieję że zastąpi wam to wystarczająco wersję PDF.
    Pozdrawiam.

    Komentarz od Kubek Bartosz — 23/07/2007 @ 19:27

  6. Artykuł piszemy przez “u” zwykłe ;), pozdrawiam.

    Komentarz od Iceman — 25/07/2007 @ 07:13

  7. […] Pierwsze kroki z Zend Framework - Bartosz Kubek […]

    Pingback od MalDevBlog » Zend Framework 1.0.1 Released — 01/08/2007 @ 22:08

  8. Mam problem php wyrzuca mi błąd :

    Strict Standards: Creating default object from empty value in … on line 5

    Gdy przygotuje widok i akcje w IndexController w których przypisuje tytuł… (dokładnie dział: Przygotowanie widoku)

    PHP : 5.2.3 ZF : 1.0.1

    męczę się z tym już trochę i nie mam zielonego pojęcia co jest nie tak…

    Komentarz od harek — 10/08/2007 @ 16:03

  9. Hej,

    Nareszcie jakis bardzie3j rozbudowany i praktyczny tutorial odnosnie ZF i to juz po wydaniu stabilnej wersji ;)
    Dzieki wielkie, mam nadzieje ze moze z czasem dopiszesz jeszcze cos o autoryzacji.

    Znalazlem jeden maly blad w Twoim opisie, odnosnie dolaczania arkusza CSS. W Twoim przykladzie kod wyglada tak:

    baseUrl;?>/public/styles/site.css” />

    u mnie dopero zadzialalo kiedy usunalem slasha przed katalogiem public.
    Pozdrawiam!

    Komentarz od tommy_from_cracow — 11/08/2007 @ 18:36

  10. @harek : Ostrzeżenia PHP typu “Strict Standards” nie powinny być traktowane jako błąd. Są to informacje czasu kompilacji, które tylko przypominają, że wykonywana jest jakaś domyślna operacja itp. Jeśli nie chciał byś otrzymywać tego typu informacji (większość programistów wyłącza je), powinieneś w konfiguracji php.ini ustawić: error_reporting = E_ALL & ~E_STRICT

    @tommy_from_cracow: tak więc rzeczywiście, poprawne zapisanie ścieżki dla inkludowanych plików jest wielką sztujką, zależną od indywidualnego środowiska, o czym więcej będzie można przeczytać w drugiej części tutorial’a za niedługo

    Komentarz od Kubek Bartosz — 13/08/2007 @ 08:44

  11. Zend Framework…

    Pierwsze kroki z Zend Framework. Założeniem tego samouczka jest pokazanie najbardziej podstawowego wykorzystania Zend Framework do napisania prostej aplikacji opartej o bazę danych….

    Trackback od pligg.com — 21/08/2007 @ 11:31

  12. Może ktoś spotkał się z błedem :
    Fatal error: Uncaught exception ‘Zend_View_Exception’ with message ’script ‘index/index.phtml’ not found in path (.\application\views\scripts\)’ in C:\Program Files\Apache Group\Apache2\htdocs\panel\library\Zend\View\Abstract.php:856 Stack trace: #0 C:\Program Files\Apache Group\Apache2\htdocs\panel\library\Zend\View\Abstract.php(764): Zend_View_Abstract->_script(’index/index.pht…’) #1 C:\Program Files\Apache Group\Apache2\htdocs\panel\library\Zend\Controller\Action\Helper\ViewRenderer.php(742): Zend_View_Abstract->render(’index/index.pht…’) #2 C:\Program Files\Apache Group\Apache2\htdocs\panel\library\Zend\Controller\Action\Helper\ViewRenderer.php(763): Zend_Controller_Action_Helper_ViewRenderer->renderScript(’index/index.pht…’, NULL) #3 C:\Program Files\Apache Group\Apache2\htdocs\panel\library\Zend\Controller\Action\Helper\ViewRenderer.php(810): Zend_Controller_Action_Helper_ViewRenderer->render() #4 C:\Program Files\Apache Group\Apache2\htdocs\panel\library\Zend\Controller\Action\HelperBroker.php(160): Zend_Cont in C:\Program Files\Apache Group\Apache2\htdocs\panel\library\Zend\View\Abstract.php on line 856

    Idąc krokami tutki utkąłęm z czymś takim przed “Stylizacją”.

    Komentarz od krasnal — 23/08/2007 @ 23:58

  13. @krasnal: niestety taki błąd oznacza najprawdopodobniej, że popełniłeś gdzieś błąd! Proszę sprawdź czy posiadasz na pewno plik szablonu w lokacji: application\views\scripts\index\index.phtml (może to literówka w nazwie któregoś katalogu, bądź pliku lub jego rozszerzenia).

    Komentarz od Kubek Bartosz — 24/08/2007 @ 17:49

  14. Mam mały problem. Robię wszystko krok po kroku i gdy dochodzę do wykorzystania bazy danych konkretnie wyświetlenia danych otrzymuje komunikat:

    Fatal error: Uncaught exception ‘Zend_Db_Adapter_Exception’ with message ‘The mysql driver is not currently installed’ in C:\wamp\www\Zend\library\Zend\Db\Adapter\Pdo\Abstract.php:104 Stack trace: #0

    dodam tylko, że oczywiście mam MySQL (zintegrowanego z pakietem WAMP) i inne aplikacje PHP bez problemu działają razem z bazą danych. Czy jakieś dodatkowe dane na temat serwera MySQL trzeba gdzieś definiować? Dodam, że w tym domowym localhoście nie korzystam, z żadnego hasła do bazy danych i zostawiam pole hasła puste, może to jest problemem?

    Komentarz od Yuras — 25/08/2007 @ 17:29

  15. @Yuras: Prawdopodobnie dotychczas do połączeń z bazą danych nie korzystałeś z driver’a PDO (Php Database Objects). Oczywiście Zend Framework, a dokładniej Zend_DB jest zbudowana w oparciu o te rozszerzenie PHP. Tak więc potrzebujesz głównego drivera PDO oraz wyspecjalizowanego pod dany silnik bazy danych, w Twoim przypadku PDO_Mysql. Aby je załadować, wejdź w edycję swego pliku php.ini i znajdź linie (dla wersji Apache zainstalowanego na systemie windows):
    ;extension=php_pdo.dll
    ;extension=php_pdo_mysql.dll
    Dla systemów linux, te linie są bardzo podobne, prawdopodobnie tylko rozszerzenie jest inne (.so).
    Tak więc wystarczy od komentować te linie (poprzez usunięcie średnika z początku) i uruchomić serwer Apache ponownie. To powinno rozwiązać problem

    Komentarz od Kubek Bartosz — 25/08/2007 @ 19:14

  16. Dzięki;) Faktycznie jedna była zakomentowana (ta od Mysql) i teraz wszystko ładnie śmiga;) Btw. gratuluję naprawdę dobrego tutoriala;)

    Komentarz od Yuras — 25/08/2007 @ 19:34

  17. krasnal: ja otrzymałem taki błąd jak usunąłem .htaccess

    nie wiem czemu .htaccess mi nie dziala :( pisze błąd servera …
    używam xampp z apatche 2 i php 5.2.3

    .htaccess: Invalid command RewriteEngine, perhaps misspelled or defined by a module not included in the server configuration

    Komentarz od stik — 28/08/2007 @ 12:21

  18. @stik: Domyślnie serwery Apache mają wyłączony moduł ModRewrite. Moduł ten pozwala z poziomu już serwera apache zarządzać wywoływanymi adresami URI. Polecam więc włączenie rozszerzenia ModRewrite w konfiguracji Apache, a dokładniej w pliku httpd.conf, od komentować linię:
    #LoadModule rewrite_module modules/mod_rewrite.so
    poprzez usunięcie znaku ‘#’ z początku linii. Proszę pamiętać o zapisaniu zmiany w pliku i ponownym uruchomieniu serwera Apache.

    A na marginesie, to po wielu już pytaniach, również na e-maila i GG, noszę się z zamiarem spisania krótkiego artykułu nt. stawiania serwera Apache+PHP+mySQL (prawdopodobnie z użyciem WAMP) w taki sposób by aplikacja testowa mogła działać i to na virtualHost’cie.

    Komentarz od Kubek Bartosz — 28/08/2007 @ 17:42

  19. Witaj, może orientujesz się czy jest możliwość skrócenie adresu np. “z
    przyklad.pl/kontroler/akcja/par1/val1/par2/val2/par3/val3″
    do “przyklad.pl/kontroler/val1/val2/val3″ za pomocą mod_rewrite lub
    samego ZF ?

    Komentarz od emm — 01/09/2007 @ 19:16

  20. @ emm : ogólnie rzecz biorąc, nie ma rzeczy niemożliwych w Zend Framework. Jest to główna jego zaleta, ponieważ jeśli tylko gotowe rozwiązanie jakie dostarcza nam Zend Framework jest dla nas nieodpowiednie, to mamy zazwyczaj możliwość wyboru kilku dróg by zastąpić je własnym poprzez: wykorzystanie interfejsu do napisania własnej klasy, napisanie pluginu, bądź po prostu dziedziczenie (”sub-classing”). Jest to GŁÓWNA zaleta tego framework’a, której nie znajdziemy w innych!

    Co do manipulowania URI. Domyślnie Zend_Controller do obsługi URI ładuje instancję routera: Zend_Controller_Router_Rewrite. Już za pomocą tego routera jest możliwość w pewnym stopniu manipulacji adresem URI. Bardzo specyficzne możliwości dają alternatywne routery: Zend_Controller_Router_Route_Static oraz Zend_Controller_Router_Route_Regex. To co ty jednak chciałbyś osiągnąć, wymagało by stworzenie własnego routera, napisanego w oparciu o interfejs Zend_Controller_Router_Interface. Jest to jednak rozległy temat, tak więc nie jestem w stanie więcej napisać w formie krótkiej podpowiedzi. Polecam za to lekturę tego rozdziały dokumentacji Zend Framework: http://framework.zend.com/manual/en/zend.controller.router.html

    Dodam jeszcze, że na potwierdzenie tego że wszystko się da zrobić, przedstawię wzór adresu URI, jaki był obsługiwany przez własny router który napisaliśmy z innymi developerami na potrzeby pewnego projektu:
    http://nazwastrony.exp/(język)/(lokalizacja)/(dowolny_SEO_tekst_pod_kątem_wyszukiwarek)/…
    …/(dowolny_tekst)-(ID_strony)/(nazwa-modułu)/(kontroler)/(akcja)/(val1)/(par1) itd

    Komentarz od Kubek Bartosz — 01/09/2007 @ 20:12

  21. jak zmienić domyślne rozszerzenie plików, które Zend wywołuje? chodzi o controllers, views, itp.

    np: z IndexController.php na IndexController.abc

    dodam, że od strony serwera to rozszerzenie mam już odpowiednio skonfigurowane.

    Komentarz od motrax — 05/09/2007 @ 17:11

  22. po wykonaniu instrukcji “Dodawanie nowego albumu” i przetestowaniu jej w przeglądarce wyskoczył mi błąd
    “Fatal error: Uncaught exception ‘Zend_Controller_Response_Exception’ with message ‘Cannot send headers; headers already sent in C:\Program Files\WebServ\httpd\zend\index.php, line 1′ in”

    Proszę o pomoc.

    Komentarz od Fatal — 25/09/2007 @ 03:27

  23. Czesc,
    ja mam problem tego typu. Musze wybrac z tabeli jedno pole, ale nie moge tego zrobic:/ Jezeli mozna prosic to moze poda ktos kod jak to ma wygladac?

    Komentarz od Abel — 25/09/2007 @ 19:33

  24. @motrax : Tego typu zmiany są niespotykaną praktyką i nie są przewidziane w ZendFramework. Jeśli jednak jesteś pewien co czynisz ;) możesz spróbować zmienić na sztywno wpisane rozszerzenie w bibliotece Zend_Controller_Dispatcher_Standard w metodzie classToFilename

    @Fatal : Bardzo często spotykany problem ;) Dzieje się tak ponieważ w momencie gdy Zend Framework jest gotów do przesłania całej treści wygenerowanej strony, wraz z nagłówkami, okazuje się że nagłówki zostgały już wysłane wcześniej! A w praktyce sprowadza się to zazwyczaj do tego, że należy przeszukać swoje pliki z kodem i znaleźć te w których przed symbolem rozpoczęcia kodu PHP: “< ?php”, wkradła się spacja lib inny znak. W Twoim przypadku wygląda na to, że właśnie w index.php masz wpisaną spację przed znacznik “

    @Abel: Drogi czytelniku - wyciąganie rekordu o konkretnym ID, to jest dokładnie to co zostało opisane w tym tutorial’u. Polecam dokładniejsze wczytanie się w lekturę ;)

    Komentarz od Kubek Bartosz — 27/09/2007 @ 20:30

  25. Dzięki!

    Komentarz od Arek — 28/09/2007 @ 07:08

  26. Napotkałem na mały problem podczas przechodzenia krok po kroku przez ten tutorial.
    Mianowicie, w sekcji #500 (przygotowanie kontrolera) jest tabelka w której podajesz, że masz taką a nie inną akcję to wyświetli Ci się taki a nie inny tekst. No i tu był problem - bo ZF się burzył, że nie ma plików widoku.
    W momencie wgrania skryptów widoku wszystko zaczęło działać.

    Ale poza tym, to tutorial zrobiony całkiem miło dla początkujących :)

    Komentarz od Krzysztof — 12/10/2007 @ 11:08

  27. Tutorial rewelacja
    Masz zadatki na napisanie książki (albo chociaż polskie wydanie)
    Tak trzymać
    Tłumaczysz już autoryzację??
    Tak na marginesie to zabrałem się za zend framework bo potrzebuję czegoś sensownego do adwords api
    mam nadzieje że nie długo będę mógł się za nie wziąć
    pozdrawiam

    Komentarz od owczar — 21/10/2007 @ 21:19

  28. No, w końcu będę mógł się nauczyć tego Zenda. Dzięki Ci wielkie!

    Komentarz od Escimo — 23/10/2007 @ 11:27

  29. Po prostu dziękuję. Kawał dobrej roboty. Pozdrawiam.

    Komentarz od Marek Ciszewki — 28/10/2007 @ 08:00

  30. Dzięki! Bardzo dobry tutorial (mimo kilku literówek i ortów) ;)

    Komentarz od xis — 11/11/2007 @ 11:10

  31. hi

    i’m lookinf for good tutorials but i failed until now. it’s s shame taht i’m not able to read polish. do you plan to release an english or german version soon?

    regards

    Komentarz od Bleu — 11/11/2007 @ 17:16

  32. @Bleu: You definatelly should check out this page: http://zftutorials.com/ . Greets

    Komentarz od Kubek Bartosz — 11/11/2007 @ 19:38

  33. Dopisuje sie do listy podziekowan, zasluzyles na sporego Pint-a /paint/ ode mnie i od tych ktorzy przeczytali Twoje wprowadzenie do ZF a teraz poszerzaja grono ZF community.
    Zrobiles tez dobra rzecz przez wylistowanie wszystkich praktycznych linkow dla ZF developerow!

    Gratulacje!

    Komentarz od pablo77 — 14/11/2007 @ 11:02

  34. Dla informacji: Sciezki jakie ustawilem na Debianie 4.0 to:

    set_include_path(’.’ . PATH_SEPARATOR . ‘/var/www/zfpl/library’
    . PATH_SEPARATOR . ‘./application/models/’
    . PATH_SEPARATOR . get_include_path());

    Po kilku probach okazalo sie ze u mnie nie zadzialaja konfiguracje:
    set_include_path(’.’ . PATH_SEPARATOR . ‘./library’
    . PATH_SEPARATOR . ‘./application/models/’ …

    ani

    set_include_path(’.’ . PATH_SEPARATOR . ‘/var/www/zfpl/library’
    . PATH_SEPARATOR . ‘/var/www/zfpl/application/models/’ …

    Jezeli ktos ma problemy z uruchomieniem swojej kopii, moge wyslac swoja - dzialajaca.

    Komentarz od pablo77 - Profimedia — 14/11/2007 @ 11:24

  35. Wielkie dzięki, ten artykuł był dla mnie bardzo pomocny:*

    Komentarz od Klaudia — 20/11/2007 @ 14:55

  36. “Pozostawiam jednak to jako ćwiczenie Tobie, drogi mój czytleniku.” Jakos nie mam pomysłu jak można zoptymalizowac te metody i szablony:/ moze jakas podpowiedz?;)

    Komentarz od michu — 23/11/2007 @ 23:43

  37. Witam, a ja napotkałem na następujący problem przy próbie pobrania danych z bazy danych i nie wiem jak to obejść. Dostaję takie informacje dla odpowiednich linijek kodu:

    51: //setup database
    52: $db = Zend_Db::factory( $config->db->adapter,
    53: $config->db->config->toArray() );
    54: Zend_Db_Table::setDefaultAdapter($db);

    Notice: Trying to get property of non-object in D:\www\zf-tutorial\index.php on line 52

    Notice: Trying to get property of non-object in D:\www\zf-tutorial\index.php on line 53

    Fatal error: Call to a member function toArray() on a non-object in D:\www\zf-tutorial\index.php on line 53

    Komentarz od Roger — 30/11/2007 @ 02:04

  38. @Roger: Upewnij się proszę, że w tym pliku index.php nie ominąłes powołania do życia obiektu configuracji parę linii wcześniej:
    $config = new Zend_Config_Ini(’/application/config.ini’, ‘general’);

    Komentarz od Kubek Bartosz — 30/11/2007 @ 10:21

  39. Dzięki za odpowiedź. Już się z tym uporałem. Problem spowodował prosty błąd literowy.

    Komentarz od Roger — 30/11/2007 @ 16:58

  40. very interesting, but I don’t agree with you
    Idetrorce

    Komentarz od Idetrorce — 16/12/2007 @ 02:35

  41. Jeśli w podpunkcie “Przygotowanie kontrolera” otrzymujecie błąd w stylu “Fatal error: Uncaught exception ‘Zend_Controller_Dispatcher_Exception’ with message ‘Invalid controller specified (add)’ in … ”

    musicie na czas testowania tego podpunktu zmodyfikować akcje w kontrolerze w taki sposób:
    function indexAction() {
    global $frontController;
    $frontController->setParam(’noViewRenderer’, true);
    echo “in IndexController::indexAction()”;
    }
    podobnie wszystkie pozostałe akcje.

    Komentarz od kiler2k3 — 16/12/2007 @ 17:53

  42. a ja mam taki bład
    Fatal error: Uncaught exception ‘Zend_Db_Exception’ with message ‘Adapter name must be specified in a string’ in H:\wamp\www\zend\library\Zend\Db.php:228 Stack trace: #0 H:\wamp\www\zend\index.php(25): Zend_Db::factory(NULL, Array) #1 {main} thrown in H:\wamp\www\zend\library\Zend\Db.php on line 228

    coś tutaj jest nie tak :
    // setup database
    $db = Zend_Db::factory($config->db->adapter,$config->db->config->toArray());
    Zend_Db_Table::setDefaultAdapter($db);

    w indexie

    Komentarz od adf — 28/12/2007 @ 23:22

  43. witam
    mam problem na samym poczatku
    jestem przy tworzeniu IndexControllera, przekopiowalem kod zeby sie nigdzie nie pomylic ale nie chce do konca dzialac

    gdy wpisuje adres http://www.adres.pl/zend/ to wyswietla mi “in IndexController::indexAction()” czyli tak jak powinno byc, natomiat jak wpisze /zend/index /zend/index/add lub edit,delete to mam komunikat
    “Not Found The requested URL /zend/index was not found on this server.” :/

    jesli utworze pliki .htaccess to wogole nic nie rusza bo mam “500 Internal Error …”
    korzystam z wykupionego serwera wiec zmiana w plikach konfiguracyjnych apacha odpada

    Komentarz od snaip — 10/01/2008 @ 22:20

  44. @snaip: plik htaccess musi absolutnie istnieć (w przypadku Apache) by kierować wszelkie żądania aplikacji wyłącznie na plik index.php (jest to zawarte w regule przedstawionej w pliku .htaccess. Warto więc zwrócić się do administratora serwera by zezwolił na posiadanie htaccess’a - większość providerów zezwala na to. Inna rzecz może być taka że twój serwer w cale nie jest postawiony na Apache, tylko np na lighttpd itp. Tak czy inaczej - warto porozmawiać z adminem.

    Komentarz od Kubek Bartosz — 11/01/2008 @ 09:35

  45. Witam, od paru dni próbuje dojść do końca tutoriala, i wszystko oczywiście jest prawidłowo wyświetlane, niestety nie radzę sobie z funkcjonalnością. Działa mi jedynie usuwanie rekordów, z aktualizacją oraz dodawaniem nie mogę dojść do ładu. Aktualizacja pobiera wszystkie dane jednak po zatwierdzeniu zmian, nie ma przekierowania na główną strone i poprawki nie są nanoszone. Dodawanie równierz nie działa(_redirect przenosi podobnie jak to ma miejsce w funkcji update z powrotem na strone dodawania). Strona główna też działa bez zarzutu i wyświetla właściwe rekordy. Nie wiem za bardzo jak z tego wybrnąć…wszystko sprawdzałem po kilka razy, wszystkie potrzebne aplikacje są zainstalowane.

    Komentarz od toss — 17/01/2008 @ 16:25

  46. problem z przekierowaniem wewnętrznym - mialem z tym klopot na serwerze home.pl, zeby zadzialalo i redirect po kasowaniu i dodaniu i edycji przerzucal na glowną strone dodac trzeba w metodzie init() kontrolera takie cos:

    $this->_helper->redirector->setUseAbsoluteUri(true);

    i dziala

    pozdr

    Komentarz od alex — 21/01/2008 @ 20:27

  47. Witam, wszystko działa super (tutorial jest the Best) ale mam pytanie jak ustawić domyslny kontroler/akcję bo jesli w url-u wpisze np: zamiast index, hhh a edit aaa ? Po wpisaniu tych danych wywala mi

    Fatal error: Uncaught exception ‘Zend_Controller_Dispatcher_Exception’ with message ‘Invalid controller specified (hhh)’ in…..

    czy tu trzeba kombinowac cos z try catch ?

    Komentarz od comp — 05/03/2008 @ 01:36

  48. witam

    co bym nie robbił otrzymuję taki błąd:

    Fatal error: Uncaught exception ‘Zend_Controller_Dispatcher_Exception’ with message ‘Cannot load controller class “IndexController” from file “IndexController.php” in directory “\”‘ in G:\Strony\zend\library\Zend\Controller\Dispatcher\Standard.php:295 Stack trace: #0 G:\Strony\zend\library\Zend\Controller\Dispatcher\Standard.php(212): Zend_Controller_Dispatcher_Standard->loadClass(’IndexController’) #1 G:\Strony\zend\library\Zend\Controller\Front.php(931): Zend_Controller_Dispatcher_Standard->dispatch(Object(Zend_Controller_Request_Http), Object(Zend_Controller_Response_Http)) #2 G:\Strony\zend\index.php(17): Zend_Controller_Front->dispatch() #3 {main} thrown in G:\Strony\zend\library\Zend\Controller\Dispatcher\Standard.php on line 295

    kod w bootstraperze jest taki jak w tym tutku, wszystkie pliki na swoich miejscach…

    Komentarz od kociou — 06/03/2008 @ 15:04

  49. Mam jedną uwagę do sekcji “Przygotowanie kontrolera”. Po stworzeniu pliku “zf-tutorial/application/controllers/IndexController.php” wyskakuje nadal błąd. A mianowicie może ja źle odczytałem tą sekcję ale chyba nie było tam napisane że żeby to działało trzeba także stworzyć przynajmniej pusty plik w lokalizacji “zf-tutorial/application/views/scripts/index/index.php”.
    Ogólnie jak na razie tutorial mi się podoba, jest napisany w prostym języku i łatwo go zrozumieć.

    Komentarz od przemeo — 17/03/2008 @ 23:54

  50. Poprawka! Napisałem tam złe rozszerzenie pliku. Oczywiście powinno być “zf-tutorial/application/views/scripts/index/index.phtml”

    Komentarz od przemeo — 17/03/2008 @ 23:56

  51. W akcji deleteAction() należy także umieścić linijkę “$album = new Album();” bo nie jest podświetlona na czarno i ktoś kto nie potrafi odczytać dobrze komunikatu błędu może stracić dużo czasu nad rozwiązaniem problemu. Tutorial świetny. Lecę czytać drugą część. Pozdrawiam

    Komentarz od przemeo — 18/03/2008 @ 12:15

  52. Jak w arkuszach stylów zastosować $this->baseUrl aby określić ścieżkę do katalogu z grafiką w stylach? Arkusz styli podpinam tak: <link rel=”stylesheet” type=”text/css” media=”screen” href=”baseUrl;?>/public/styles/site.php” /> ale gdy stosuję np. wpis “background:url(baseUrl;?>/public/images/frame-bg.gif)” to otrzymuję komunikat “Using $this when not in object context in …..” Co z tym zrobić ??

    Komentarz od marcif — 19/03/2008 @ 03:44

  53. Najlepiej, jakby autor zip-owal ten przykład i umieścił w sekcji download ;) Tak jak niektórzy, mam pewne problemy, a widząc cały projekt, po wykluczyłbym swoje błędy..(jak je mam);]

    Komentarz od Zip — 21/03/2008 @ 01:30

  54. Taki mi błąd wyrzuca gdy chce pobrać dane z bazy :

    Fatal error: Uncaught exception ‘Zend_Db_Adapter_Exception’ with message ‘The PDO extension is required for this adapter but the extension is not loaded’ in /var/www/library/Zend/Db/Adapter/Pdo/Abstract.php:95 Stack trace: #0 /var/www/library/Zend/Db/Adapter/Abstract.php(395): Zend_Db_Adapter_Pdo_Abstract->_connect() #1 /var/www/library/Zend/Db/Adapter/Pdo/Abstract.php(206): Zend_Db_Adapter_Abstract->query(’DESCRIBE `album…’, Array) #2 /var/www/library/Zend/Db/Adapter/Pdo/Mysql.php(138): Zend_Db_Adapter_Pdo_Abstract->query(’DESCRIBE `album…’) #3 /var/www/library/Zend/Db/Table/Abstract.php(595): Zend_Db_Adapter_Pdo_Mysql->describeTable(’album’, NULL) #4 /var/www/library/Zend/Db/Table/Abstract.php(528): Zend_Db_Table_Abstract->_setupMetadata() #5 /var/www/library/Zend/Db/Table/Abstract.php(264): Zend_Db_Table_Abstract->_setup() #6 /var/www/zend_app/application/controllers/IndexController.php(15): Zend_Db_Table_Abstract->__construct() #7 /var/www/library/Zend/Controller/Action.php(498): IndexController->indexAction() #8 in /var/www/library/Zend/Db/Adapter/Pdo/Abstract.php on line 95

    Czy to znaczy że muszę zainstalować PD0_MYSQL z pear ? Czy może jakiś błąd popełniłem?

    Komentarz od janek — 25/03/2008 @ 13:00

  55. Ok , to była wina niezainstalowania pdo_mysql.. Teraz działa. Pozdrawiam:)

    Komentarz od janek — 25/03/2008 @ 15:25

  56. eee zrobilem wszystko tak jak w opisie i :
    Fatal error: Uncaught exception ‘Zend_Controller_Dispatcher_Exception’ with message ‘Invalid controller specified (l)’ in C:\xampp\xampplite\htdocs\zf-tutorial\library\Zend\Controller\Dispatcher\Standard.php:249 Stack trace: #0 C:\xampp\xampplite\htdocs\zf-tutorial\library\Zend\Controller\Front.php(914): Zend_Controller_Dispatcher_Standard->dispatch(Object(Zend_Controller_Request_Http), Object(Zend_Controller_Response_Http)) #1 C:\xampp\xampplite\htdocs\zf-tutorial\index.php(18): Zend_Controller_Front->dispatch() #2 {main} thrown in C:\xampp\xampplite\htdocs\zf-tutorial\library\Zend\Controller\Dispatcher\Standard.php on line 249

    prosze o pomoc

    Komentarz od krzysztof — 06/04/2008 @ 15:20

  57. @krzysztof: podaj proszę adres URI jaki podajesz w przeglądarce?

    Komentarz od Kubek Bartosz — 06/04/2008 @ 21:00

  58. Witam,
    na wstępie chciałbym podziękować za tutoriala:), powolutku chciałem sobie przez niego przebrnąć ale w momencie gdy dochodzę do momentu “Przygotowanie kontrolera” i wstukuję http://localhost/zf-tutorial pojawia mi się błąd:

    Fatal error: Uncaught exception ‘Zend_Controller_Dispatcher_Exception’ with message ‘Invalid controller specified (error)’ in C:\serwer\strony\zf-tutorial\library\Zend\Controller\Dispatcher\Standard.php:249 Stack trace: #0 C:\serwer\strony\zf-tutorial\library\Zend\Controller\Front.php(914): Zend_Controller_Dispatcher_Standard->dispatch(Object(Zend_Controller_Request_Http), Object(Zend_Controller_Response_Http)) #1 C:\serwer\strony\zf-tutorial\index.php(16): Zend_Controller_Front->dispatch() #2 {main} thrown in C:\serwer\strony\zf-tutorial\library\Zend\Controller\Dispatcher\Standard.php on line 249

    bardzo podobny do tego, który powinien się wyskoczyć, z tego fragmentu widzę tylko, że zamiast słowa index mam w nawiasie error, natomiast, gdy podaje kolejne urle http://localhost/zf-tutorial/index/add to jest:

    The requested URL /zf-tutorial/add was not found on this server.

    wynika to pewnie z błędu w pliku kontrolera, zresztą nie wiem:) Proszę o radę…

    Komentarz od Tomek — 07/04/2008 @ 22:20

  59. @Tomek: widzę żę problem z “Zend_Controller_Dispatcher_Exception” się przewija ponownie. Jutro zabiorę się za upgrade tutoriala do współpracy z ZF 1.5. Powinno to wyjaśnić wiele.

    Komentarz od Kubek Bartosz — 07/04/2008 @ 22:38

  60. @Tomek: sprawdziłem tę część tutoriala z Zend Framework 1.5.1, zarówno poprzez adres: http://localhost/zft1/svn/ jak równierz poprzez vHosta: http://www.zft1.local. Wszystko działa. Tak więc polecam dokładniejsze sprawdzenie krok po kroku czy wszystko masz dobrze.

    Komentarz od Kubek Bartosz — 08/04/2008 @ 16:39

  61. Witam, wydaje mi się, że postępowałem zgodnie z tutorilem, jednak nie działają mi linki na głównej stronie. Zostaje podana informacja, że nie ma takiej strony. Katalog Zf-tutorial jest w głównym katalogu localhosta. Bardzo proszę o pomoc. Pozdrawiam, Michał

    Komentarz od Mick71 — 09/04/2008 @ 23:18

  62. @Mick71: podaj proszę dokładnie, w którym miejscu samouczka jesteś, gdy pojawia się Tobie ten błąd. Pierwsza rada: sprawdź nazwy plików, klas i funkcji (akcji). Najczęściej tutaj są uchybienia ;)
    Także dla pewności sprawdź czy mod Re-write masz aktywny w apache.

    Komentarz od Kubek Bartosz — 10/04/2008 @ 19:13

  63. @Mick71, Michał Sz.: po przeanalizowaniu problemu Michała, moja podpowiedź dla was jest następująca:

    * brak plików .htaccess jest przyczyną niemożności otwarcia innych stron niż główna. Bez tych plików, mod_rewrite nie pomoże Zend Framework’owi w odczytywaniu wywoływanych adresów URI. A to musi się stać! Opis jak je założyć znajduje sie w tym samouczku.

    * zauważyłem, że gdy kopiujecie kod z samouczka do własnego edytora w takiej postaci:
             <a href=”<?php echo $this- rel=”nofollow”>baseUrl; ?>/index/edit/id/
                <?php echo $album->id;?>”>Edit
             <a href=”<?php echo $this- rel=”nofollow”>baseUrl; ?>/index/delete/id/
                <?php echo $album->id;?>”>Delete
    to efektem jego jest taki adres URI:
             http://localhost/zft/index/edit/id/%20%20%20%20%20%20%20%20%20%20%20%204

    Dlatego proszę pozamieniajcie tego typu linie na ciągłe :
             <a href=”<?php echo $this- rel=”nofollow”>baseUrl; ?>/index/edit/id/<?php
                echo $album->id;?>”>Edit
             <a href=”<?php echo $this- rel=”nofollow”>baseUrl; ?>/index/delete/id/<?php
                echo $album->id;?>”>Delete
    Czego efektem będzie prawidłowe:
             http://localhost/zft/index/edit/id/4

    Taki mały trick - mam nadzieję że zrozumiały. Dla wygody przyszłych osób poprawiłem kod samouczka pod tym kątem.

    Komentarz od Kubek Bartosz — 10/04/2008 @ 20:32

  64. […] Repozytorium SVN w “Zend Framework Tutorial - Pierwsze kroki z Zend […]

    Pingback od Kody źródłowe samouczków Zend Framework | Heavymind — 12/04/2008 @ 15:08

  65. Dodadałem w indexController.php “end_Controller_Front::throwExceptions(true);” i juz nie pokazuje mi się błąd: “Fatal error: Uncaught exception”. Niestety teraz pokazuje mi się: “Using $this when not in object context in”, ale o ile dobrze pamiętam coś o tym było w tutorialu.

    Komentarz od krzysztof — 12/04/2008 @ 17:59

  66. Zrobilem i wszystko fajnie tylko przy kasowaniu mam taki blad i w zasadzie nie wiem dlaczego. Można prosoc o pomoc?

    Notice: Undefined variable: album in C:\xampp\htdocs\test\application\controllers\IndexController.php on line 106

    Fatal error: Call to a member function fetchRow() on a non-object in C:\xampp\htdocs\test\application\controllers\IndexController.php on line 106

    a to ta linia:
    if ($id > 0)
    {
    // only render if we have an id and can find the album.
    106 $this->view->album = $album->fetchRow(’id=’.$id);
    if ($this ->view->album->id > 0) {
    // render template automatically

    Komentarz od Bocian837 — 14/04/2008 @ 15:07

  67. @Bocian837: sprawdź w kodzie czy masz zdefiniowane zmienne $album i $id, bo wygląda na, to, że opuściłeś jakąś linijkę ( gdzie były definiowane ) i stąd “Undefined variable”
    Pozdrawiam

    Komentarz od Tomek — 23/04/2008 @ 21:58

  68. Bardzo fajny tutek;) tylko teraz mam mały problem…wiem że troszke z innej beczki,ale męcze się z tym juz ponad miesiąc i mam nadzieję,że mi pozmożecie!Otóż przy wysyłaniu maila nie wyświetlają mi się polskie znaki…tutaj podaje skrypt:
    require_once ‘Zend/Mail.php’;
    $mail = new Zend_Mail();
    $mail->setBodyText(’Aktywacja’);
    $mail->setBodyHtml($content);
    $mail->setFrom(’www.asd.com’, ‘asd.com’);
    $mail->addTo($email, ‘Odbiorca’);
    $mail->setSubject(’Aktywacja’);
    $mail->send();
    Już kombinowałem na różne sposoby i nie moge znaleźć rozwiązania. plisssssss help meee!!!!!!!

    Komentarz od krasnal — 09/05/2008 @ 11:56

  69. Tuturial super. Ja miałem problem, który był opisany wyżej, tj. następujący:

    Fatal error Uncaught exception ‘Zend_Controller_Response_Exception’ with message ‘Cannot send headers; headers already sent in F:\xampp\htdocs\zend.framework.t.2\public\index.php, line 1′ in F:\xampp\htdocs\zend.framework.t.2\library\Zend\Controller\Response\Abstract.php:281
    Stack trace:
    #0 F:\xampp\htdocs\zend.framework.t.2\library\Zend\Controller\Response\Abstract.php(147): Zend_Controller_Response_Abstract->canSendHeaders(true)
    #1 F:\xampp\htdocs\zend.framework.t.2\library\Zend\Controller\Action\Helper\Redirector.php(200): Zend_Controller_Response_Abstract->setRedirect(’/zend.framework…’, 302)
    #2 F:\xampp\htdocs\zend.framework.t.2\library\Zend\Controller\Action\Helper\Redirector.php(371): Zend_Controller_Action_Helper_Redirector->_redirect(’/zend.framework…’)
    #3 F:\xampp\htdocs\zend.framework.t.2\library\Zend\Controller\Action\Helper\Redirector.php(453): Zend_Controller_Action_Helper_Redirector->setGotoUrl(’/index’, Array)
    #4 F:\xampp\htdocs\zend.framework.t.2\library\Zend\Controller\Action.php(675): Zend_Controll in F:\xampp\htdocs\zend.framework.t.2\library\Zend\Controller\Response\Abstract.php on line 281

    Problem wyskakuje przy użyciu _redirect(). Żadnych wolnych znaków przed znacznikiem <?php nie mam. W końcu zrezygnowany wgrałem przykład na wykupiony serwer i o dziwo tam tego problemu nie było. No więc zainstalowałem w końcu WAMP’a. No i też problemu nie było. Wcześniej miałem zainstalowany XAMPP. Może ktoś wie jak poprawić ten problem w XAMPP’ie? (chociaż teraz to używam WAMP’a, ale ktoś inny możliwe, że skorzysta z rozwiązania). Pozdrawiam,

    Komentarz od Michał — 22/05/2008 @ 20:08

  70. Swietny poradnik :)
    Ale mam podobny problem co krasnal. Aplikacja nie wyswietla mi polskich znakow. Ustawilem porownywanie napisow w mysql na utf8, w phpmyadmin dziala dobrze. Co jest nie tak?

    Komentarz od phobos — 22/05/2008 @ 21:36

  71. Na serwerze IIS 6 nie wczytuje mi pliku css, podglad kodu pokazuje mi cos takiego, przy adresie do pliku css : href=”/index.php/public/styles/site.css” co z tym zrobic?

    Komentarz od gyzo — 23/05/2008 @ 22:30

  72. Bardzo jasno rozpisany i czytelnie, jako że często się człowiek uczy z podobnych turek, to jako całokształt 9/10 punktów , według mnie mógłbyś napisać książkę zbierając kilka turek w całość, mam nadzieję że natknę się na więcej dzieł twojego autorstwa :)

    Komentarz od rtsd2 — 30/05/2008 @ 10:14

  73. […] Pierwsze kroki z Zend Framework [tutorial napisany początkowo dla Zenda 1.0, działa również z następnymi wersjami] […]

    Pingback od Web By Kosmowariat » Blog Archive » Zend Framework - wartościowe źródła informacji [PL] — 15/06/2008 @ 17:13

  74. A mi wywala taki błąd :<

    Warning: include(Zend/Loader.php) [function.include]: failed to open stream: Nie ma takiego pliku ani katalogu in /opt/lampp/htdocs/Xenon/Alpha_1/index.php on line 8

    Warning: include() [function.include]: Failed opening ‘Zend/Loader.php’ for inclusion (include_path=’.:./library:./application/models/:.:/opt/lampp/lib/php’) in /opt/lampp/htdocs/Xenon/Alpha_1/index.php on line 8

    Fatal error: Class ‘Zend_Loader’ not found in /opt/lampp/htdocs/Xenon/Alpha_1/index.php on line 9

    Sam nie wiem w czym tu jest błąd tak tu namieszane jest z include’ami…

    Komentarz od Wytry — 20/06/2008 @ 14:43

  75. Super przewodnik!
    Ale ze nie moge sie nie przyczepic - sprawdzajcie count tablic dla petli foreach, plz ;)

    Komentarz od v. — 24/06/2008 @ 06:35

  76. W przypadku błędu:
    Strict Standards: Creating default object from empty value in … on line 5

    może pomóc ustawienie w pliku index.php następującego parametru:
    $frontController->setParam(’useDefaultControllerAlways’, true);

    Komentarz od casi — 01/07/2008 @ 10:02

  77. A jak wygląda sprawa z dodaniem nowego kontrolera? Dodaję nowy kontroler (do autoryzacji userów) wg. tego pdf’a: http://akrabat.com/wp-content/uploads/getting-started-with-zend-auth_108.pdf i przy wybraniu adresu w przeglądarce /zf-tut/auth wywala mi 404, mimo, że plik z kontrolerem nazywa się AuthController.php i nazwa klasy kontrolera to Auth.

    Komentarz od r3m0 — 04/07/2008 @ 16:35

  78. @Wytry : Jako że używasz środowiska Unix, proponuję dla testu podać pełną ścieżkę (absolutną, od root katalogu) wskazującą na katalog /library, przez funkcję set_include_path()

    @r3m0: klasy kontrolerów powinny naśladować wzorzec:
    [nazwaKlasy]Controller extends Zend_Controller_Action
    Przynajmniej w tym podstawowym użycu tak jest. Czy to rozwiązuje Twój problem?

    Komentarz od Kubek Bartosz — 05/07/2008 @ 16:59

  79. Niestety nie. Nie działa z podreśleniem i bez podreślenia pomiędzy nazwą kontrolera a “Controller”. Ja też używam środowiska Unix, więc to może ma jakieś znaczenie?

    Komentarz od r3m0 — 05/07/2008 @ 17:22

  80. Mam problem z przekierowaniem na strone główną z nieistniejącego linku. np . z http://www.mojastrona.pl/jakis_dziwny_link chce zeby przekierowalo na strone główną. wywala mi błąd,że nie może znaleźć danego kontrolera.
    W index.php mam cos takiego:
    $route = new Zend_Controller_Router_Route(
    ‘:controller/:action/:id’,
    array( ‘controller’ => ‘index’,
    ‘action’ => ‘index’,
    ‘id’ => 0 ),
    array( ‘id’ => ‘\d+’ )
    );
    $router->addRoute(’default’, $route);
    Pliss help me!

    Komentarz od krasnal — 09/07/2008 @ 14:37

  81. @krasnal: ścieżka routing’owa, jaką przekazałeś do front controller’a nie powinna mieć wpływu na twój problem. Po pierwsze sprawdź czy efekt jest ten sam gdy nie definiujesz w/w ścieżki dla routera. Po drugie - czy nie rozwiązuje twego problemu ustawienie takiego parametru dla kontrolera frontowego:
    $frontController->setParam( ‘useDefaultControllerAlways’, true );

    Komentarz od Kubek Bartosz — 11/07/2008 @ 13:05

  82. Właśnie czegoś takiego szukałem - no i działa:) Troche sie wkurzyłem i ustawiłem poprostu dla jakich sciezek jaki ma czytać kontroler.Na sztywno i troche nieprofesjonalnie,ale działało ;-p Dzięki za pomoc.

    Komentarz od krasnal — 12/07/2008 @ 11:46

  83. Mam problem w akcji usuwania. To jest wyświetlany błąd:
    Notice: Undefined variable: album in /var/www/zf-tutorial/application/controllers/IndexController.php on line 110

    Fatal error: Call to a member function fetchRow() on a non-object in /var/www/zf-tutorial/application/controllers/IndexController.php on line 110

    W pliku zmieniłem wszystkie ” ‘ ” na ” ‘ ” i wszystko inne działa tylko ten ostatni listing po skopiowaniu nie działa.

    Z góry dzięki za jakąś pomoc.

    Komentarz od Rafał — 25/07/2008 @ 15:08

  84. U mnie pojawiał się ten kłopot dopóki nie zmieniłem w indexControllerze “” na ” (czyli dwa ogonki zamiast cudzysłowu)

    jak np. tu:

    if ($artist != ” && $title != ”)

    I teraz bangla jak należy :-)

    Dzięki za ten tutorial dla autora!

    Komentarz od Łukasz — 28/07/2008 @ 13:57

  85. Nie mogę dołączyć skryptu JavaScript.
    W header.phtml dałem w sekcji head
    <script type=”text/javascript” src=”baseUrl;?>/public/scripts/menu.js”>
    a w katalogu /public/sripts mam skrypt menu.js
    Jak używam skryptu poza ZF to mi działa a tutaj nie umiem zaimplementować:(

    Komentarz od witek010 — 29/07/2008 @ 00:17

  86. oczywiscie sciezka w sekcji head to <script type=”text/javascript” src=”baseUrl;?>/public/scripts/menu.js”>

    Komentarz od witek010 — 29/07/2008 @ 00:22

  87. Na początku jeszcze przed “Przygotowanie widoku” jak zacząłem sprawdzać czy wszystkie podstrony działają - pokazywały mi się błędy i myślałem, że ten samouczek może ma błędy. Na szczęście później już wszytko było OK. Ostatecznie wszystko rewelacyjnie działa. Wielkie podziękowania dla autora.

    Komentarz od wojtek77 — 03/08/2008 @ 08:15

  88. A ja mam problem (i może to już było i pozostaje mi kontakt z adminem), bo stworzywszy całą strukturę wyskakuje mi błąd 500. Ale co ciekawe tylko, gdy w kontrolerach umieszczone są definicje klas. Jeśli zamiast “class IndexController…” umieszczę zwykłe “echo ‘aaa’; ” wszystko działa prawidłowo odnajdując kontrolery. O co więc chodzi - czy ktoś wie może?

    Komentarz od martin shadows — 14/08/2008 @ 13:16

  89. @shadows: czy twój serwer www obsługuje PHP5?

    Komentarz od Kubek Bartosz — 14/08/2008 @ 14:32

  90. Zdecydowałem się na ten hosting właśnie dlatego, że wymieniona jest obsługa php5 - livenet.pl

    Komentarz od martin shadows — 14/08/2008 @ 14:38

  91. @shadows: tak więc na stronie livenet chwali się ze ma PHP,jak i PHP5. tak więc w panelu klienta powinieneś mieć instrukcje jakie stosować rozszerzenie plików PHP dla aplikacji PHP5 LUB powinieneś mieć możliwość ustawienia wersji silnika PHP4/PHP5 dla założonego konta/domeny. Obstawiam że tutaj jest przyczyna.

    Komentarz od Kubek Bartosz — 14/08/2008 @ 14:43

  92. Dzięki za pomoc. Faktycznie jak poszukałem w ustawieniach to znalazłem (dokładniej w tutorialu dostarczanym przez livenet) - ustawianie w index.php
    $frontController->setBaseUrl(’/home/nick/public_html/’);
    pomogło. Co prawda dziwne, że bez “class” pracowało wcześniej a z tym nie, ale obecnie chodzi dobrze, więc jest ok. Może innym ten komentarz też się przyda.
    Pozdrawiam

    Komentarz od martin shadows — 15/08/2008 @ 13:43

  93. @witek10

    musisz miec <script type=”text/javascript” src=”baseUrl;?>/public/scripts/menu.js”>
    w pliku widoku żeby ci działało. Oczywiście zakładam, że zgodnie z tutorialem zdefiniowałeś $this->view->baseUrl w odpowiednim kontrolerze.

    Komentarz od tawnos — 21/08/2008 @ 23:24

  94. @witek10, fak, parser strony, sprobuje jeszcze raz
    musisz miec <script type=”text/javascript” src=” baseUrl ; ? > /public/scripts/menu.js”>

    spacje oczywiscie pominac

    Komentarz od tawnos — 21/08/2008 @ 23:27

  95. W końcu jakiś konkretny artykuł jasno pokazujący od A do Z zasadę działania Frameworka. Jedyne co bym zmienił to fragment kodu z formularzem i jego obsługą. Rozumiem, że autor chciał oszczędzić sobie pisania robiąc jeden formularz, ale szybko to nadrobił od linikji “// set up an “empty” album” ;), brzydkie to trochę, bylejakie i nie oszczędza czasu a do tego ma służyć framework, zwłaszcza że jest klasa Zend_Form. Uzupełnienie tutoriala o wykorzystanie tej klasy byłoby dla początkujących na pewno cenną wskazówką.

    Pozdrawiam!

    Komentarz od RW — 02/10/2008 @ 15:51

  96. Mam ten sam problem a mianowicie “The mysql driver is not currently installed” w php.ini wysztstko jest ok. Co mam zrobić? Pozdrawiam

    Komentarz od Tasior — 18/11/2008 @ 13:22

  97. Ok śmiga jednak! Świetny tutek. Serio dobrze zrobiony.

    Komentarz od Tasior — 18/11/2008 @ 13:25

  98. Po co jest funkcja escape()
    np. w: escape($this->album->title); ?>

    Komentarz od theniel — 03/01/2009 @ 21:18

  99. Dostaje już na samym początku przy tworzeniu IndexController.php i wyświetlanie np. http://localhost/zf-tutorial/ błąd w stylu:

    Fatal error: Uncaught exception ‘Zend_View_Exception’ with message ’script ‘index/index.phtml’ not found in path (.\application\views\scripts\)’ in C:\Program Files\WebServ\httpd\zf-tutorial\library\Zend\View\Abstract.php:875 Stack trace: #0 C:\Program Files\WebServ\httpd\zf-tutorial\library\Zend\View\Abstract.php(783): Zend_View_Abstract->_script(’index/index.pht…’) #1 C:\Program Files\WebServ\httpd\zf-tutorial\library\Zend\Controller\Action\Helper\ViewRenderer.php(902): Zend_View_Abstract->render(’index/index.pht…’) #2 C:\Program Files\WebServ\httpd\zf-tutorial\library\Zend\Controller\Action\Helper\ViewRenderer.php(923): Zend_Controller_Action_Helper_ViewRenderer->renderScript(’index/index.pht…’, NULL) #3 C:\Program Files\WebServ\httpd\zf-tutorial\library\Zend\Controller\Action\Helper\ViewRenderer.php(962): Zend_Controller_Action_Helper_ViewRenderer->render() #4 C:\Program Files\WebServ\httpd\zf-tutorial\library\Zend\Controller\Action\HelperBroker.php(276): Zend_Controller_Action_Helper_ViewRenderer->postDispatch( in C:\Program Files\WebServ\httpd\zf-tutorial\library\Zend\View\Abstract.php on line 875

    jakieś pomysły??

    Komentarz od Gavu — 06/01/2009 @ 16:26

  100. Bez sensu… Po co utrudniać sobie życie i pisać 12049109 razy więcej kodu, w dodatku o wiele razy mniej przejrzystego i zrozumiałego dla programisty otwierającego źródła aplikacji.

    Uporządkowane Programowanie Strukturalne wg pewnej formy jest wiele razy lepsze, o wiele razy szybsze w tworzeniu, znajdywaniu błędów i przeprowadzaniu rozbudowy i edycji.

    Komentarz od Programista — 13/01/2009 @ 13:55

  101. […] zend framework - szukam kursu Na pocz

    Pingback od zend framework - szukam kursu | hilpers — 18/01/2009 @ 17:23

  102. @Programista
    Programowanie strukturalne jest szybsze, a pisanie obiektowo rzeczywiście wymaga większej ilości kodu. Jednak zastanów się, jak będziesz pisał kod większego projektu razem z kilkudziesięcioma innymi programistami. Jak będziesz go rozwijał i konserwował. Programowanie strukturalne jest dobre w sytuacji, kiedy największym priorytetem jest wydajność. Jednak używanie OOP, jest również uzasadnione w wielu przypadkach.

    Komentarz od Łukasz Adamczuk — 20/01/2009 @ 12:53

  103. @Gavu zignoruj ten błąd i idź dalej, w “Przygotowanie kontrolera” jest trochę mylący tekst, że niby jak w przeglądarce wpiszesz “http://localhost/zf-tutorial/” to coś zobaczysz. Ale najpierw musisz przygotować widok(kolejny akapit tutoriala).

    Komentarz od Jaro — 12/02/2009 @ 16:24

  104. Prosto i konkretnie wprowadza w framework, dzieki.

    Komentarz od bash — 12/03/2009 @ 01:45

  105. Nieźle napisany tutorial. Świetnie tłumaczy podstawowe pojęcia. Pozdrawiam p.s. czekam na więcej :)

    Komentarz od kamil — 30/03/2009 @ 12:20

  106. GENIALNY TUTORIAL!!! Wszystko działa należycie. Drobne poprawki kodu wynikają WYŁĄCZNIE z niedoskonałości kopiowania tekstu z ekranu i wklejanaia go do skryptu. Absolutnie nie umniejsza to chwały Autora, który poświęcił czas na kapitalny poradnik. Polecam wszystkim pragnącym poznać ZEND Framework. Dzięki Autorowi i szacunek!!!!

    Komentarz od Piotr_k — 31/05/2009 @ 13:43

  107. Wszystko śmiga, ale jest jeden problem - adres bazowy aplikacji to “http://localhost/ZF/index/”. Wszystkie akcje działają, jednak gdy wpiszę np “http://localhost/ZF/index/ss” to otrzymuję komunikat: “Fatal error: Uncaught exception ‘Zend_Controller_Action_Exception’ with message ‘Action “ss” does not exist and was not trapped in __call()’ in /home/user/www/ZF/library/Zend/Controller/Action.php:484 Stack trace: #0 /home/user/www/ZF/library/Zend/Controller/Action.php(514): Zend_Controller_Action->__call(’ssAction’, Array) #1 /home/user/www/ZF/library/Zend/Controller/Dispatcher/Standard.php(288): Zend_Controller_Action->dispatch(’ssAction’) #2 /home/user/www/ZF/library/Zend/Controller/Front.php(945): Zend_Controller_Dispatcher_Standard->dispatch(Object(Zend_Controller_Request_Http), Object(Zend_Controller_Response_Http)) #3 /home/user/www/ZF/index.php(33): Zend_Controller_Front->dispatch() #4 {main} thrown in /home/user/www/ZF/library/Zend/Controller/Action.php on line 484″. Głupia sprawa :) da się coś z tym zrobić?

    Komentarz od Piotr_k — 31/05/2009 @ 15:48

  108. Świetny tutorial. Dobry wstęp do Zenda. Nie miałem styczności nigdy przedtem z żadnym frameworkiem, ale mam zamiar teraz to nadrobić. Znacie może jakieś fajne kursy i tutoriale?

    Komentarz od tadek92 — 16/06/2009 @ 19:48

  109. mam problem na samym poczatku jestem przy tworzeniu IndexControllera
    gdy wpisuje adres http://localhost/zf/ to wyswietla mi “in IndexController::indexAction()” czyli tak jak powinno byc, natomiat jak wpisze http://localhost/zf/index/add/ lub edit,delete to mam komunikat
    że nie potrafi czegos takigo znalesc, pliki .htaccess mam utworzone,moduł ModRewrite aktywowany,
    nie mam pojecia co jest tego powodem
    prosze o pomoc

    Komentarz od przemo — 28/06/2009 @ 18:01

  110. Witam już przy samym początku tego tutoriala po utworzeniu wszystkich katalogów i plików mam błąd w przeglądarce:
    Your browser sent a request that this server could not understand.
    Invalid URI in request GET /~zend/zf/ HTTP/1.1

    Wyświetla się on po próbie uruchomienia pliku index.php gdy wpisuje w adres http://localhost/~zf
    Jestem początkujący wykonuje wszystko zgodnie z instrukcjami czy ktoś wie co z tym fantem zrobić ?

    Komentarz od Błąd — 12/07/2009 @ 20:04

  111. Sorry zapomniałem o katalogu zend : tak wpisuje: http://localhost/~zend/zf

    Komentarz od Błąd — 12/07/2009 @ 20:06

  112. Mam problem z baza danych czyli z widokiem ;(

    Komentarz od pozycjoner — 22/07/2009 @ 13:11

  113. Pojawia mi sie taki problem, czy mozna cos z tego wyśledzić?
    Przy okazji pojawia mi sie sporo dziwnych znakow ascii, tzn powiela sie kwadracik..
    Problem pojawil sie po dodaniu config.ini i dodaniu tabeli do struktury programu..

    Fatal error: Uncaught exception ‘Zend_View_Exception’ with message ’script ‘phtml�’ not found in path (.\application\views\scripts\)’ in C:\wamp\www\zf-tutorial\library\Zend\View\Abstract.php:925 Stack trace: #0 C:\wamp\www\zf-tutorial\library\Zend\View\Abstract.php(828): Zend_View_Abstract->_script(’phtml?’) #1 C:\wamp\www\zf-tutorial\application\views\scripts\index\add.phtml(3): Zend_View_Abstract->render(’phtml?’) #2 C:\wamp\www\zf-tutorial\library\Zend\View.php(107): include(’C:\wamp\www\zf-…’) #3 C:\wamp\www\zf-tutorial\library\Zend\View\Abstract.php(832): Zend_View->_run(’.\application\v…’) #4 C:\wamp\www\zf-tutorial\library\Zend\Controller\Action\Helper\ViewRenderer.php(902): Zend_View_Abstract->render(’index/add.phtml’) #5 C:\wamp\www\zf-tutorial\library\Zend\Controller\Action\Helper\ViewRenderer.php(923): Zend_Controller_Action_Helper_ViewRenderer->renderScript(’index/add.phtml’, NULL) #6 C:\wamp\www\zf-tutorial\library\Zend\Controller\Action\Helper\ViewRenderer.php(962): Zend_Controller_Action_Helper_ViewRen in C:\wamp\www\zf-tutorial\library\Zend\View\Abstract.php on line 925

    Komentarz od gaku — 21/08/2009 @ 01:16

  114. Jak więcej czytam o tych Frameworkach to po prostu mnie dziwi po co to komu jak to zawiłe i pomieszane - masakra ile tego trzeba się uczyć lat?

    Komentarz od jaro — 08/09/2009 @ 16:04

  115. Witam, mam mały problem jestem początkujący w ZendFramework. Wchodząc np. pod adres http://localhost/zf-tutorial/index/add wyświetla mi się error 404 a powinno: in IndexController::addAction(). Natomiast wchodząc na http://localhost/zf-tutorial/ wyświetla mi się to co powinno czyli: in IndexController::indexAction(). Gdzie tu może być błąd o_O

    Pozdrawiam

    Komentarz od Said — 25/10/2009 @ 17:24

  116. A czy powstał jakiś tutek jak zrobić rejestrację, logowanie i pobieranie np. nazwiska z sesji??

    Komentarz od WodzJarek — 26/10/2009 @ 21:10

  117. http://www.internetmaker.pl/artykul/4267,1,przewodnik_po_zend_framework_okienko_logowania_czyli_jak_uzyc_zend_auth.html

    Komentarz od Said — 01/11/2009 @ 09:16

  118. Witam, mam ten sam problem co Said znaczy się wchodząc np. pod adres http://localhost/zf-tutorial/index/add wyświetla mi się error 404 a powinno: in IndexController::addAction(). Natomiast wchodząc na http://localhost/zf-tutorial/ wyświetla mi się to co powinno czyli: in IndexController::indexAction(). Gdzie tu może być błąd … ?

    Pozdrawiam

    Komentarz od pio — 05/11/2009 @ 12:11

  119. Kiedy uruchamiam kod spod NetBeana zwraca np. dla edit przy poz. 2:
    /zf-tutorial/index.php/index/edit/id/2 i wszystko działa ok, chyba dlatego, że w adresie mam wtedy jawne wywołanie index.php a nie z automatu (DirectoryIndex index.php).
    Przy normalnym wywołaniu (wejściem do katalogu zf-tutorial)$this->baseUrl zwraca mi katalog /zf-tutorial/ adres jest:
    /zf-tutorial/index/edit/id/2
    Po zmianie kodu na:
    <!–<a href=”baseUrl; ?>/index.php/index/edit/id/id;?>”>Edit–>
    (dodanie /index.php)w zasadzie działa, ale czy o to chodzi? Jak mniemam coś jest nie tak chyba po stronie ustawień Apache’a, ale co? Wdzięcznym za podpowiedź

    Komentarz od Rydzu — 17/11/2009 @ 14:25

  120. Poprzedni błąd (komentarz 119) polegał na złej nazwie pliku .htacces zamiast .htaccess w katalogu bazowym :( . Teraz wszystko hula ;)

    Komentarz od Rydzu — 22/11/2009 @ 21:08

  121. Komentarz do 115 i 118. Musicie stworzyć widoki: add.phtml, delete.phtml i edit.phtml. Róbcie dalej tutorial i zobaczycie, że będzie dalej działać.

    Komentarz od IGotAPower — 29/11/2009 @ 21:52

  122. Prześledziłem uważnie polecany wyżej tutorial dotyczący Zend_Auth, ale potrzebowałbym pomocy w kwestii połączenia tej wiedzy z aplikacją stworzoną za pomocą powyższego tutoriala… Chciałbym, aby dostęp do powstałego systemu wymagał autoryzacji za pomocą loginu i hasła..

    Komentarz od ChuckTaylor — 21/03/2010 @ 03:23

  123. Naprawdę świetny tutorial, wielkie dzięki, właśnie czegoś takiego potrzebowałem.

    Komentarz od Michał — 18/04/2010 @ 19:15

  124. Class ‘Album’ not found

    czemu?
    co moze byc nie tak? jak inaczej sie do tego dostac. plis o majla z instrukcja

    Komentarz od ryhoo — 25/06/2010 @ 22:21

  125. gdyby ktos mial podobny problem uzywajac wersji 1.10.5
    $album = new Application_Model_DbTable_Album();
    $this->view->albums = $album->fetchAll();
    tak wyglada standard nazewnictwa
    warunkiem jest stworzenie katalogu models/DbTable i w nim trzeba umiescic plik. autoloader sie tym opiekuje stad takie nazewnictwo. pol dnia na tym stracilem :) ale bledy to najlepsza okazja do nauki

    Komentarz od ryhoo — 25/06/2010 @ 22:37

  126. […] 3.Szybki tutorial w którym jest opisane jak szybko rozpocząć pracę z ZF: http://akrabat.com/zend-framework-tutorial/ (polska wersja, ale niestety dotycząca starszej wersji ZF 1.5 dostępna jest tutaj: http://www.heavymind.net/zend-framework-tutorial/). […]

    Pingback od Zbieramy informacje o Zendzie! « Frozen – Mój devblog — 07/07/2010 @ 22:36

  127. Nie daje mi spokoju jeden bląd który za każdym razem mi się pojawia.Najgorsze w tym wszystkim jest to że nie wiem jak go usunąć. Wykonuję Projekt edycji, usuwania, zapisywania i wyświetlania danych z bazy danych. Wykonuję krok po kroku tak jak to Pan opisuję w tym artykule :www.heavymind.net/zend-framework-tutorial
    Za każdym razem pojawia mi się ten błąd :
    Fatal error: “Call to undefined method Zend_Config_Ini::_arrayMergeRecursive() in C:\xampp\htdocs\tutorial\library\Zend\Config\Ini.php on line 152″. Z mojej strony szukałem na różnych forach rozwiązanie takiego problemu, lecz nikt z nim się nie spotkał. Proszę o pomoc

    Komentarz od michaldaro — 17/07/2010 @ 19:25

  128. Cześć

    Tutorial przeczytałem w sumie dwa razy. Mam zainstalowy zf 1.7.5. Przepisałem kod źródłowy z tutoriala. Później dla pewności skopiowałem z repozytorium.
    Dałem opcję AllowOverride All. Pliki .htaccess są poustawiane. Zmienna baseUrl też ustawiona. Liczne kombinacje i wertowanie po Internecie nie pomogło.

    Strona główna projektu działa.

    Strony add/edit/delete _nie_ działają - Not Found 404.

    Czy ktoś umie zaradzić tej sytuacji?
    Dla informacji: zainstalowany jest apache2.2.15, php5.2.13 z obsługą pdo. System operacyjny gentoo.

    Komentarz od Kamil — 17/07/2010 @ 20:47

  129. Witam ponownie ;)

    Nadal nie wiem czemu ww. konfiguracja (komentarz 128.) powoduje błąd.
    Przeniosłem projekt na serwer nginx-0.7.65 z spawn-fcgi-1.6.3 i po ustawieniu rewrite w nginx.conf wszystko śmiga aż miło.

    Pozdrawiam i dziękuję za ten tutorial :)

    Komentarz od Kamil — 18/07/2010 @ 13:41

  130. @michaldaro

    Tutaj http://framework.zend.com/issues/browse/ZF-10011 ktoś podaje prawdobodobne rozwiązanie. Mówi, aby sprawdzić zmienną include_path w pliku php.ini.
    Sprawdzałeś to?

    Pozdrawiam

    Komentarz od Kamil — 18/07/2010 @ 13:47

  131. Witam. Jeśli ktoś ma błąd, że nie wyświetla mu się str. to:
    -Sprawdźcie czy macie dobrze nazwany plik .htaccess oraz czy jest w nim dobry kod.
    -Jeśli stworzyliście kontroler, który ma wyświetlać “in IndexController::indexAction()” (przy akcji /index/add) należy utworzyć w katalogu localhost/applications/views/scrips/index plik add.phtml i analogicznie dla innych akcji (plik może być pusty).

    Mam nadzieję, że nie zamieszałem za bardzo :)

    Komentarz od Kamil — 23/07/2010 @ 09:06

  132. Przy akcji index/index - tak ma być powyżej, wkradł się błąd.

    Komentarz od Kamil — 23/07/2010 @ 09:18

  133. Mam problem. Jestem na etapie WYŚWIETLANIA LISTY ALBUMÓW i wywala mi taki błąd:
    Parse error: parse error in D:\www\zft1\index.php on line 16
    16 wers jest następujący:
    $config = new Zend_Config_Ini(’./application/config.ini’, ‘general’);

    Komentarz od BobicSon — 25/07/2010 @ 21:16

  134. Odpisze ktoś

    Komentarz od bobicson — 17/08/2010 @ 14:17

  135. Kopiujac tekst prosto z tego tutoriala zwroc uwage na apostrofy. Zamiast normalnych pojedynczych prostych ‘, masz tutaj takie jakies dziwne ukosne :)
    Podmien je na normalne i zobacz czy bedzie smigac :)

    Komentarz od Son — 06/09/2010 @ 21:53

  136. Fajny tutorial, ale mały . Znacie jakieś jeszcze “polskie” albo spolszczone tutoriale. Jeśli nie to co bardziej polecanie “Zend In Action” czy “Beginning Zend Framework” czy może inny fajny tutorial ???
    Pozdra

    Komentarz od Rysiek — 11/09/2010 @ 20:01

  137. Niestety utknałem dość wcześnie i nie daje ruszyć dalej. Wyskakuje mi błąd:

    Fatal error: Uncaught exception ‘Zend_View_Exception’ with message ’script ‘index/index.phtml’ not found in path (./application/views\scripts/)’ in C:\xampp\htdocs\zf-tutorial\library\Zend\View\Abstract.php:980 Stack trace: #0 C:\xampp\htdocs\zf-tutorial\library\Zend\View\Abstract.php(876): Zend_View_Abstract->_script(’index/index.pht…’) #1 C:\xampp\htdocs\zf-tutorial\library\Zend\Controller\Action\Helper\ViewRenderer.php(897): Zend_View_Abstract->render(’index/index.pht…’) #2 C:\xampp\htdocs\zf-tutorial\library\Zend\Controller\Action\Helper\ViewRenderer.php(918): Zend_Controller_Action_Helper_ViewRenderer->renderScript(’index/index.pht…’, NULL) #3 C:\xampp\htdocs\zf-tutorial\library\Zend\Controller\Action\Helper\ViewRenderer.php(957): Zend_Controller_Action_Helper_ViewRenderer->render() #4 C:\xampp\htdocs\zf-tutorial\library\Zend\Controller\Action\HelperBroker.php(277): Zend_Controller_Action_Helper_ViewRenderer->postDispatch() #5 C:\xampp\htdocs\zf-tutorial\library\Zend\Controller\Action.php(523): Zend_Controller_ in C:\xampp\htdocs\zf-tutorial\library\Zend\View\Abstract.php on line 980

    Skrypty są tam gdzie powinny być (chyba:)), przestudiowalem wszystkie komentarze itd. ale nie potrafie sobie poradzic z tym błedem. Prosze o pomoc.

    pozdrawiam
    Kamil

    Komentarz od dow — 26/11/2010 @ 09:37

  138. dokładnie mam identyczny problem jak Kamil, odpalam na xammpie oraz innym serwerze i mam dokładnie ten sam błąd.

    Pozdrawiam

    Komentarz od Adam — 18/12/2010 @ 22:21

  139. @137,138
    Dodajcie pliki widoków(mogą być puste):

    zf-tutorial/application/views/scripts/add.phtml
    zf-tutorial/application/views/scripts/edit.phtml
    zf-tutorial/application/views/scripts/index.phtml
    zf-tutorial/application/views/scripts/delete.phtml

    Komentarz od iskramac — 06/01/2011 @ 19:33

  140. Mam ten sam błąd co w dwóch komentarzach powyżej. Jakaś niekompatybilność wersji może? Mam Zend 1.11.2

    Komentarz od Agnieszka — 06/01/2011 @ 23:23

  141. Witam próbuje połączyć sie do bazy ProgreSQL na innym komputerze i wyskakuje mi taki komunikat. Prosze o pomoc

    Fatal error: Uncaught exception ‘Zend_Db_Adapter_Exception’ with message ‘The pgsql driver is not currently installed’ in C:\xamp\xampp\htdocs\strony\berberis\library\Zend\Db\Adapter\Pdo\Abstract.php:104 Stack trace: #0 C:\xamp\xampp\htdocs\strony\berberis\library\Zend\Db\Adapter\Abstract.php(725): Zend_Db_Adapter_Pdo_Abstract->_connect() #1 C:\xamp\xampp\htdocs\strony\berberis\library\Zend\Db\Adapter\Pdo\Pgsql.php(152): Zend_Db_Adapter_Abstract->quote(’action’) #2 C:\xamp\xampp\htdocs\strony\berberis\library\Zend\Db\Table\Abstract.php(595): Zend_Db_Adapter_Pdo_Pgsql->describeTable(’action’, NULL) #3 C:\xamp\xampp\htdocs\strony\berberis\library\Zend\Db\Table\Abstract.php(528): Zend_Db_Table_Abstract->_setupMetadata() #4 C:\xamp\xampp\htdocs\strony\berberis\library\Zend\Db\Table\Abstract.php(264): Zend_Db_Table_Abstract->_setup() #5 C:\xamp\xampp\htdocs\strony\berberis\application\controllers\IndexController.php(12): Zend_Db_Table_Abstract->__construct() #6 C:\xamp\xampp\htdocs\strony\berberis\library\Zend\Controller\Actio in C:\xamp\xampp\htdocs\strony\berberis\library\Zend\Db\Adapter\Pdo\Abstract.php on line 104

    Komentarz od darekb — 19/01/2011 @ 11:36

  142. Odświeżę temat z zapytaniem jak wyglada integracja z nowymi smartami wersji 3, obecny artykuł nie działa z nowa wersją smarty

    Komentarz od igor — 25/03/2011 @ 14:47

  143. Witam,
    Podczas połączenia z bazą danych mam następujący błąd. Czy ktoś może spotkał się z podobnym problemem?

    Fatal error: Uncaught exception ‘PDOException’ with message ‘SQLSTATE[HY000] [2013] Lost connection to MySQL server at ‘reading initial communication packet’, system error: 111′ in
    #1 /homez.312/konkursy/testkonkursy/library/Zend/Db/Adapter/Pdo/Mysql.php(96): Zend_Db_Adapter_Pdo_Abstract->_connect() #2 /homez.312/konkursy/testkonkursy/library/Zend/Db/Adapter/Abstract.php(459): Zend_Db_Adapter_Pdo_Mysql->_connect() #3 /homez.312/konkursy/testkonkursy/library/Zend/Db/Adapter/Pdo/Abstract.php(238): Zend_Db_Adapter_Abstract->query(’DESCRIBE `album…’, Array) #4 /homez.312/konkursy/testkonkursy/library/Zend/Db/Adapter/Pdo/Mysql.php(156): Zend_Db_Adapter_Pdo_Abstract->query(’DESCRIBE `album…’) #5 /homez.312/konkursy/testkonkursy/library/Zend/Db/Table/Abstract.php(834): Zend_Db_Adap in /homez.312/konkursy/testkonkursy/library/Zend/Db/Adapter/Pdo/Abstract.php on line 144

    Komentarz od Gosia — 30/03/2011 @ 18:12

  144. robiłem krok po kroku ten tutorial ale w momencie bazy danych i modelu zaczęły się schody niby zrobiłem cały a coś nie działa właśnie przy bazie danych działam na środowisku netBeans + xamp może ktoś pomóc?

    Komentarz od nowicjusz — 31/03/2011 @ 20:32

  145. […] Jeśli chcesz zacząć zabawę z Zendem polecam stronę z serii ciężki umysł Ciekawa nazwa, ale jakość artykułów jest znacznie ciekawsza, naprawdę […]

    Pingback od Kilka słów o Zend Framework « MWL Blog — 11/04/2011 @ 13:30

  146. U mnie na problemy z “Internal Server Error…” oraz plikami .htaccess pomogło wywalenie tego:
    php_flag magic_quotes_gpc off
    php_flag register_globals off

    z pliku .htaccess dla głównego katalogu.

    Komentarz od Vifon — 09/05/2011 @ 22:27

  147. […] Polecam tutorial/kurs dotyczący frameworka Zend Framework 1.5.1, który jest pod tym adresem: http://www.heavymind.net/zend-framework-tutorial/ […]

    Pingback od Informacje IT – blog » Zend Framework – Tutorial — 10/05/2011 @ 13:03

  148. kawał dobrej roboty

    Komentarz od zenekhg — 20/05/2011 @ 11:26

  149. Witam i dziękuję :)
    Dopiero zabieram się za Zend-a, zawsze myślałem, że jest “diablo trudny”, ale teraz widzę, że to nie jest takie straszne jak malują :)
    Jeszcze raz wielkie dzięki za super tutka.
    Szkoda, że więcej się nie pokazuje :(
    Ale i tak bardzo dziękuję za to co już zostało umieszczone.

    Komentarz od bumerang07 — 28/05/2011 @ 21:50

  150. Fatal error: Uncaught exception ‘Zend_View_Exception’ with message ’script ‘index/index.phtml’ not found in path (./application/views\scripts/)’ in C:\wamp\www\zf-tutorial\

    aby aplikacja zaczęła działać bez błędnie musicie utworzyć w folderze zf-tutorial/application/views/scripts/ kolejny folder ‘index’ oraz dodać takie pliki:

    add.phtml
    edit.phtml
    index.phtml
    delete.phtml

    czyli ścieżka do nich powinna wyglądać tak

    zf-tutorial/application/views/scripts/index/add.phtml
    zf-tutorial/application/views/scripts/index/edit.phtml
    zf-tutorial/application/views/scripts/index/index.phtml
    zf-tutorial/application/views/scripts/index/delete.phtml

    Komentarz od 'index/index.phtml' — 02/06/2011 @ 14:29

  151. Witam,

    Przerabiajac ten tutorial ktory ogolnie jest naprawde dobry napotkalem szereg problemow errorow ktorych mozna bylo uniknac.
    Sprawa jak zauwazylem dotyczy niescislosci z textu a dokladniej wiekszosc problemow dotyczy albo driverow (bibliotek w php) badz zlych sceizek dostepu do poszczegolnych plikow. Mozna by bylo to poprawic bo naprawde przez takie pierdolety stracilem kupe czasu.

    Mozna by wyjasnic sciezki dostepu do katalogow, mozna by napisac ze najlpeiej postawic wszystko na virtualnym hoscie w apachu bo jak robilem inaczej to nie dzialalo prawidlow (strona startowa zenda dziala ale reszta juz nie) mozna by napisac czy zend zainstalowany na dysku osobno gryzie sie jakos z ZENDEM w xampp (bo zauwzylem ze chyba xampp posiada takowy) itd musialem zmienic nazwe do xampp/php/pear/zenda na inna … ogolnie bledy ktory wyskakuja psuja cala chec do nauki. W ogole co do zalozenia samego framevorka niby ok, ale trzeba wszystko zrobic dokladnie tak jak ktos zaplanowal bo inaczej error to troche bez sensu. Programuja samemu wszystkie tebledy dawno bym rozwiazal i nie denerwowal sie ze cos nie dziala przez jakis banal np ze pliki phtml musza byc w
    \application\views\scripts\index ale ze pliki phtml header.phtml i footer.phtml musza byc juz katalog wyzej bo inaczej dupa. Dlaczego ?
    Tego w tutku nie ma, samemu trzeba dojsc, wydaje sie ze to proste itd, ale najpierw autor pisze ze maja byc w tymze katalogu po czym robie tak jak pisze i nic nie dziala od razu.

    Moze sie przyda, Zwracajcie uwage na:
    1. Zrobcie na virtual hoscie
    2. W momencie braku plikow widoku w katalogi viev/script/index dostaniemy bledy jak ich nie bedzie
    3. dokladnie sprawdzajcie sciazki dostepu
    4. upewnic sie czy xampp w wersji powyzej 1.7 nie ma lub ma zenda i czy to nie stanowi problemu w dalszej pracy.
    5. pewnie duzo duzo wiecej :(

    pozdr

    Komentarz od Rafal — 20/06/2011 @ 20:18

  152. Proponuję dopisać do artykułu jedną rzecz. Po napisaniu controllera IndexController.php Zend domaga się widoku. Inaczej nie wyświetli “in IndexController::indexAction()” itp. ;( Muszą istnieć.pliki phtml w view/scripts/index/…. Potem można przejść do omawiania w szczegółach VIEW.

    Komentarz od Maveius — 28/07/2011 @ 14:21

  153. Do wszystkich którzy ośmieszają pisany wiele razy błąd typu:

    Fatal error: Uncaught exception ‘Zend_Controller_Dispatcher_Exception’ with message ‘Invalid controller specified (zf-tutorial)’ in F:\Programy\server2go\htdocs\zf-tutorial\library\Zend\Controller\Dispatcher\Standard.php:248 Stack trace: #0 F:\Programy\server2go\htdocs\zf-tutorial\library\Zend\Controller\Front.php(954): Zend_Controller_Dispatcher_Standard->dispatch(Object(Zend_Controller_Request_Http), Object(Zend_Controller_Response_Http)) #1 F:\Programy\server2go\htdocs\zf-tutorial\index.php(17): Zend_Controller_Front->dispatch() #2 {main} thrown in F:\Programy\server2go\htdocs\zf-tutorial\library\Zend\Controller\Dispatcher\Standard.php on line 248

    Skrypty widoku SĄ DODANE a pomimo to odpalenie adresów typu
    http://127.0.0.1:4001/zf-tutorial/index/index
    daje ciągle powyższy gruby error.
    Macie inny pomysł jak rozwiązać problem?

    http://127.0.0.1:4001/zf-tutorial
    oraz
    http://127.0.0.1:4001/zf-tutorial/index.php
    odpala stronę poprawnie.

    Komentarz od seismic — 16/09/2011 @ 09:02

  154. Wielkie dzięki za ten tutorial. Dzięki niemu zrozumiałem wreszcie tego całego Zenda :)

    Komentarz od Tomasz M. — 17/01/2012 @ 21:51

  155. na przykładzie kodu z tego artykułu, przy stworzeniu nowego kontrolera wyskakuje not found 404, w czym błąd?
    1) Stworzyłem nowy kontroler application/controllers/WlasnyController.php
    2) w nim:

    class WlasnyController extends Zend_Controller_Action {
    public function init() {}
    public function indexAction() {}
    }

    3) zrobiłem widok, czyli w application/views stworzyłem katalog wlasny(application/views/wlasny) i w nim index.phtml w ktorym wpisalem byle jaki tekst

    Szukałem w Internecie nawet i tak to powinno wyglądac, ale jednak nie działa. Dodam, że 127.0.0.1/zf-tutorial/ działa, tak samo …zf-tutorial/index, …zf-tutorial/index/add itd jest oki.

    A jak odowłuję się 127.0.0.1/zf-tutorial/wlasny albo …/wlasny/index to już nie działa.

    Pomóż ktos prosze!!!

    Komentarz od Konrad — 05/02/2012 @ 01:15

  156. […] po polsku o ZF nic sensownego nie ma, albo jest dobrze ukryte. Podobno o ZF traktuje 60 stron jakiejś książki Helionu. Widziałem też blog, z którego jednak ciężko się czegoś nauczyć i samouczek sprzed 5 lat. […]

    Pingback od Uczę się programować » Blog Archive » Zend Framework – zaczynamy — 08/05/2012 @ 22:27

  157. Wydaje mi się, czy na http://php.pl/Wortal/Artykuly/Framework/Pierwsze-kroki-z-Zend-Framework/Baza-Danych jest plagiat?

    Komentarz od xxx — 28/06/2012 @ 16:28

  158. Do wszystkich, którzy mają błąd 404 przy /index/add itd ale nie przy / + w dziwny sposób działa Wam na /index.php/add, ale niech każdy to sprawdzi: prawdopodobnie,tak jak u mnie wasz serwer działa na innym porcie niż 80, przez co należy poprawić plik .htaccess w rootcie strony na: (np.:)

    RewriteEngine on
    RewriteCond %{REQUEST_FILENAME} -s [OR]
    RewriteCond %{REQUEST_FILENAME} -l [OR]
    RewriteCond %{REQUEST_FILENAME} -d
    RewriteRule ^.*$ - [NC,L]
    RewriteRule .* http://%{HTTP_HOST}:%{SERVER_PORT}/sandbox/zf-tutorial/index.php [NC,L]

    php_flag magic_quotes_gpc off
    php_flag register_globals off

    To powinno pomóc. Tutorial dobry, ale polecam po przeczytaniu wersję po ang. (http://akrabat.com/wp-content/uploads/Getting-Started-with-Zend-Framework.pdf i kolejne do znalezienia na blogu)jest uaktualniona do wersji 1.11.10 (na ten moment przynajmniej) obejmuje większy zakres materiału i nowe, aktualnie zalecane praktyki pisania w ZF.

    Komentarz od marcin32 — 25/07/2012 @ 10:13

  159. Hej, piszę jeszcze raz, bo wygląda na to, że głupi system antyspamowy usunął mój komentarz. Ciekawe ile istotnych informacji poleciało w ten sposób z komentarzy :/

    Znalazłem rozwiązanie błędu 404 dla osób, którym działa root strony ( / ) ale podstrony już nie, oraz wersja z .php (/index.php/add) : przyczyną jest najprawdopodobniej inny niż domyślny port na którym działa serwer (w moim przypadku :8080), co można poprawić w pliku .htaccess znajdującym się w rootcie strony, u mnie wygląda teraz tak:
    RewriteEngine on
    RewriteCond %{REQUEST_FILENAME} -s [OR]
    RewriteCond %{REQUEST_FILENAME} -l [OR]
    RewriteCond %{REQUEST_FILENAME} -d
    RewriteRule ^.*$ - [NC,L]
    RewriteRule .* http://%{HTTP_HOST}:%{SERVER_PORT}/sandbox/zf-tutorial/index.php [NC,L]

    php_flag magic_quotes_gpc off
    php_flag register_globals off

    Tutorial dobry, ale mocno niektualny. Wersja ang, której to jest tłumaczeniem, została zaktualizowana do najnowszej wersji frameworku (1.11 na ten moment), zawiera o wiele większy zakres materiału + prezentuje wiele zalecanych praktyk programistycznych, polecam!

    Komentarz od marcin32 — 27/07/2012 @ 14:57

  160. Bardzo spoczko tutorial. Przegryzam się przez temat PHP i ten framework wydał mi się najbardziej sensowny. Miałbym jednak pare pytań jeśli można na privie. Buduje prostą aplikację, która zakłada, że edytowany obiekt będzie posiadał kilka atrybutów, które z kolei posiadały będą kilka cech z zadanej listy -> takie przypisanie wielu wartości przez multi select do danego atrybutu. Jak to najlepiej ugryźć ?

    Pozdrawiam BigoBigo.

    Komentarz od BigoBigo — 09/09/2012 @ 20:53

  161. Kurs bardzo fajny, można nauczyć się dobrze podstaw.
    Chiałbym dodac że strona po wykoniu wszystkich kroków w tego tutka mi nie działał. Wysypywały się dziwne błędy np takie jakie miał @krasnal — 23/08/2007.

    Rozwiązanie: okazało się że jak wklejałem z tej strony kod źródłowy to zamiast myślników ‘ wklejały mi sie jakieś psełdo ‘ i psełdo ” zamiast prawidłowych cudzysłowów. Trzeba wszystko pozamieniać na prawidłowe

    Komentarz od Przemysław77 — 12/01/2013 @ 19:34

Kanał RSS dla tego wpisu. TrackBack URL

Dodaj komentarz

Oparte na WordPress