Zend Framework Tutorial


Interakcja z bazą danych

Ponieważ komponenty Zend Framework obsługujące bazę danych są jeszcze niestabilne, a chciałbym aby ta przykładowa aplikacja była prosta, użyłem prostej klasy która używa SQLite do dodawania i pobierania newsów oraz komentarzy:

PHP:
  1. <?php
  2.  
  3. class Database
  4. {
  5.     private $_db;
  6.  
  7.     public function __construct($filename)
  8.     {
  9.         $this->_db = new SQLiteDatabase($filename);
  10.     }
  11.  
  12.     public function addComment($name, $comment, $newsId)
  13.     {
  14.         $name = sqlite_escape_string($name);
  15.         $comment = sqlite_escape_string($comment);
  16.         $newsId = sqlite_escape_string($newsId);
  17.  
  18.         $sql = "INSERT
  19.                 INTO   comments (name, comment, newsId)
  20.                 VALUES ('$name', '$comment', '$newsId')";
  21.  
  22.         return $this->_db->query($sql);
  23.     }
  24.  
  25.     public function addNews($title, $content)
  26.     {
  27.         $title = sqlite_escape_string($title);
  28.         $content = sqlite_escape_string($content);
  29.  
  30.         $sql = "INSERT
  31.                 INTO   news (title, content)
  32.                 VALUES ('$title', '$content')";
  33.  
  34.         return $this->_db->query($sql);
  35.     }
  36.  
  37.     public function approveNews($ids)
  38.     {
  39.         foreach ($ids as $id) {
  40.             $id = sqlite_escape_string($id);
  41.  
  42.             $sql = "UPDATE news
  43.                     SET    approval = 'T'
  44.                     WHERE  id = '$id'";
  45.  
  46.             if (!$this->_db->query($sql)) {
  47.                 return FALSE;
  48.             }
  49.         }
  50.  
  51.         return TRUE;
  52.     }
  53.  
  54.     public function getComments($newsId)
  55.     {
  56.         $newsId = sqlite_escape_string($newsId);
  57.  
  58.         $sql = "SELECT name, comment
  59.                 FROM   comments
  60.                 WHERE  newsId = '$newsId'";
  61.  
  62.         if ($result = $this->_db->query($sql)) {
  63.             return $result->fetchAll();
  64.         }
  65.  
  66.         return FALSE;
  67.     }
  68.  
  69.     public function getNews($id = 'ALL')
  70.     {
  71.         $id = sqlite_escape_string($id);
  72.  
  73.         switch ($id) {
  74.             case 'ALL':
  75.                 $sql = "SELECT id,
  76.                                title
  77.                         FROM   news
  78.                         WHERE  approval = 'T'";
  79.                 break;
  80.             case 'NEW':
  81.                 $sql = "SELECT *
  82.                         FROM   news
  83.                         WHERE  approval != 'T'";
  84.                 break;
  85.             default:
  86.                 $sql = "SELECT *
  87.                         FROM   news
  88.                         WHERE  id = '$id'";
  89.                 break;
  90.         }
  91.  
  92.         if ($result = $this->_db->query($sql)) {
  93.             if ($result->numRows() != 1) {
  94.                 return $result->fetchAll();
  95.             } else {
  96.                 return $result->fetch();
  97.             }
  98.         }
  99.  
  100.         return FALSE;
  101.     }
  102. }
  103.  
  104. ?>

Oczywiście masz wolną rękę, aby zamiast tej klasy zastosować własne rozwiązanie. Jest ona tu dołączona tylko po to aby pokazać przykład kompletnej aplikacji.

Konstruktor tej klasy wymaga podania pełnej ścieżki i nazwy pliku bazy SQLite, który wpierw musisz stworzyć:

PHP:
  1. <?php
  2.  
  3. $db = new SQLiteDatabase('/path/to/db.sqlite');
  4.  
  5. $db->query("CREATE TABLE news (
  6.                 id       INTEGER PRIMARY KEY,
  7.                 title    VARCHAR(255),
  8.                 content  TEXT,
  9.                 approval CHAR(1) DEFAULT 'F'
  10.             )");
  11.  
  12. $db->query("CREATE TABLE comments (
  13.                 id       INTEGER PRIMARY KEY,
  14.                 name     VARCHAR(255),
  15.                 comment  TEXT,
  16.                 newsId   INTEGER
  17.             )");
  18.  
  19. ?>

Musisz to zrobić tylko raz, potem wystarczy że przekażesz pełną ścieżkę i nazwę pliku do konstruktora klasy Database:

PHP:
  1. <?php
  2.  
  3. $db = new Database('/path/to/db.sqlite');
  4.  
  5. ?>


1 2 3 4 5 6

Informacje oraz linki


Inne artykuły
Zend Framework 0.1.4
Warsztaty PHP vs. ASP
Polecane
Zend Studio - The premiere PHP IDE

Dodaj komentarz

Poświęć chwilę i wyraź swoją opinię. Możesz użyć niektórych znaczników HTML.

Komentarze czytelników

To miłe, że pofatygowałeś się z przetłumaczeniem tutoriala do Zend Framework. Czytanie tego rodzaju opracaowań jest bardziej przyjazne niż sucha lektura dokumentacji, a czytanie w rodzimym języku to wręcz luksus. Robisz fajną robotę ulatwiajac pierwszy kontakt z tym frameworkiem - mowie tu zarówno o powyższym tekscie, jak i o strone http://zf.naruniec.info/. Tak przy okazji czy to (http://framework.zend.com/developer/changeset/589) tlumaczenie tez jest Twojego autorstwa?

Ciesze się, że się podoba :) Mam nadzieję, że niedługo strona z przykładami się nieco rozwinie. Co do tłumaczenia manuala to jest także mojego autorstwa, jednak przetłumaczonych jest dopiero kilka rozdziałów. Myślę że w lipcu uda się zakończyć prace i możliwe, że wraz z wersją frameworka 0.1.5 ukaże się polski manual.

To by było miłe.

To by było super z tą dokumentacją. Co do arta to dzięki wielkie… jak napisał bigZbig - LUKSUS :D

Mógłbyś to gdzieś jeszcze opublikować, np. tu: http://www.secondrenesans.com/c18.html

Nice. Tylko jak najlepiej zabrać się za napisanie strony, która wyświetli jednocześnie generowane menu, skrót ostatnich wpisów z forum itp. oprócz newsów?

Gratuluję, świetny tutorial, naprawdę.

Dołączam się do pytania, które zadał Tuner. FrontControler ZF jest fajny do pisania prostych stron, ale jak przy jego pomocy zbudować aplikację modularną? Chodzi mi oczywiście o taką oraganizację kodu aby poszczególne moduły były w jak największym stopniu od siebie niezależne.

Generalnie to już MVC wymusza jakąś tam modułowość, jednak w aplikacji z tutoriala każda część modułu (model, widok i kontroler) są przechowywane w różnych katalogach.

Domyślam się, że chodzi o możliwość takiego napisania modułów aby wszystkie pliki danego modułu były ładnie wydzielone, np. tak:

moduł1
    models
    views
    controllers
moduł1
    models
    views
    controllers

itd.

Żeby to osiągnąć trzeba by pogrzebać przy kontrolerze frontowym i routerze. Dość wygodnie będzie można to zrobić w oparciu o nowy router (RewriteRouter), który ma pojawić się w dzisiejszej wersji 0.1.5.

Dodatkowo wtedy można do każdego modułu jakiś meta plik XML wrzucić z podstawowymi informacjami o module i działałoby to całkiem fajnie.

Co do pytania Tunera: napisanie takiej aplikacji nie różni się od każdej innej. Piszesz modele wyciągające dane menu i skrót wpisów z forum, w kontrolerze przekazujesz to do szablonu i gotowe. Jeśli np. menu ma być generowane dla wszystkich kontrolerów to wtedy najlepiej użyć plugina (Zend Framework Plugins), a jeśli tylko dla konkretnego kontrolera to najlepiej pobranie danych menu i przekazanie ich do widoku rozwiązać w konstruktorze kontrolera.

Wojciechu!

Skoro tak bardzo dobrze idzie Tobie tłumaczenie angielskich tekstów zwracam się do Ciebie w imieniu wielu początkujących w ZF.

Proszę przetłumacz artykuł Luke Dawson-a o Pluginach jak również gdybyś mógł napisać gdzie i jakie pliki trzeba umieścić i jak je ponazywać, żeby ten plugin zadziałał.

Myślę, że nie tylko ja będę Tobie wdzięczny!

Proszę bardzo :) Nie jest to tłumaczenie tylko luźna wariacja na temat, ale mam nadzieję, że się przyda.

A ja mam jedno pytanko: mam mianowicie sytuację:

Wszystkie pliki nie są umieszczone w głównym katalogu serwera (,że odwołuje sie do nich w sposób :www.strona.pl/controller/action) a w jakimś podkatalogu (np. http://www.strona.pl/podkatalog1/podkatalog2/controller/action). Niestety nie potrafię skonfigurować tak ModRewrita żeby mi to “chytał”.

Bardzo proszę o pomoc :-)

Użyj nowego RewriteRoutera, tam jest coś takiego jak RewriteBase.

Teraz pytanie za 100 pkt. Co zrobić żeby Zend_Db dobrze odsługiwał polskie znaki. Baza MySQL w UTF-8 a chce żeby znaki wyświetlał w iso-8859-2 czy w latin2, jak kto woli.

funkcja iconv(), nie działa, chyba że źle dobieram parametry.

Z góry wielkie dzięki za pomoc!

Dla potomnych, wystarczy to:

$db->query(’SET NAMES latin2′);
$db->query(’SET CHARACTER SET latin2′);

Dzięki za stworzenie tutoriali do ZF - bardzo mi pomogły :D

Piotrku, jeśli baza jest w UTF-8 to lepiej chyba już całą aplikację zrobić przy użyciu UTF-8 :)

Seba, małe sprostowanie - powyższy tutorial jest tylko tłumaczeniem, jego autorem jest Chris Shiflett.

Witajcie, mam następujący problem: w jaki sposób przy takiej konfiguracji jak ta w artykule powyżej można dostać się do parametru “c” w tak skonstruowanym adresie: adres.domena/a/b/c
Jak wiemy: a - to nazwa kontrolera, b - nazwa akcji, c - no właśnie?
Chodzi mi tu dokładnie o możliwość tworzenia akcji typu: adres.domena/admin/delete/5 (co możnaby porównać do aprove w powyższym tekście, jednakże chciałbym przekazywać id rekordu w aresie, a nie jak tutaj poprzez formularz, metodą POST).

To jeszcze raz ja ;), poszukałem już i znalazłem - metoda Zend_Controller_Action::_getParam
pozdrawiam.

A propo’s umieszczania strony w podkatalogu serwera. Wystarczy zamiast Zend_Controler_Routera uzyc Zend_Controler_RewriteRoutera i plik .htaccess wrzucic do tego podkatalogu zamiast do katalogu glownego. RewriteRouter powinien sam rozpoznac sciezke, ale wrazie czego mozna ustawic recznie RewriteBase. RewriteRouter teoretycznie zostal stworzony w celu wyeliminowania koniecznosci stosowania mod_rewrite, ale nie znaczy to ze ta nowa wersja ZF Routera nie bedzie wspolpracowac z plikami .htaccess

przykład fajny, ale ja szukam już któryś dzień jak zrobić taką operację

if($sesja->zalogowany)
{
$frontController->dispatch();//idź gdzie sobie chcesz
}
else
{
// idź do strony z logowaniem
}

do tej pory nie wiem jak to wykonać - nie mam pojęcia nie znalazłem przykładów na to - nie wiem co zrobić
dzięki jednej osobie dotarłem do strony

http://www.nabble.com/Zend_Acl—Zend_Auth-example-scenario-tf3165728s16154.html

przykład rozbudowany - z rozbudowanym systemem, ale dalej nie rozumiem jak to wykonać

jest tam przykład

->setControllerDirectory(array(’default’ => realpath(’../application/controllers/default’),
‘admin’ => realpath(’../application/controllers/admin’)))

i nie wiem, czy z tego wynika, że ja powinienem zrobić dwie ścieżki do kontrolera? jedną dla zalogowanych druga dla niezalogowanych

normalnie było prosto szybko i zwyczajnie
if(!$_SESSION[’zalogowany’)
header(’location:index.php?action=login’);

a przy ZF nad takim czymś męczę się prawie trzy dni i nie wiem jak to zrobić - na jakiej zasadzie ma się to oprzeć itp

Dzięki za tutorial ZF zaczyna mi się krystalizować w umyśle ;)

[…] Zend Framework Tutorial - Wojciech Naruniec […]

Do ktorego zend-a to bylo pisane?

W 1.0.3 nie dziala od poczatku ten tutek, mimo ze zmienilem Zend::loadClass na Zend_Loader::loadClass? Moze jest jakis Tutorial do 1.0.3??

Dzieki

jaskooo, to rozwiązuje problem…
$controller=Zend_Controller_Front::getInstance()
->setControllerDirectory(’../app/controllers’)
->setParam(’noViewRenderer’,true) //recepta
->dispatch();

Pytanie: http://www.costam.pl/controller/action, jak zrobić tak że jak user zapoda w przeglądarce controller/action.html to wykona się ta sama akcja?

Gdy próbuję dostać się na drugą podstronę wyrzuca błąd iż jej nie ma..

jakaś awaria ? można znaleźć tutorial gdzieś indziej ?

Błąd w nawigacji po podstronach poprawiłem. Dodałem też informacje o tym, że tutorial jest nieaktualny.

amateurcumshots thumblogger com,