Witaj, Gościu O nas | Kontakt | Mapa
Wortal Forum PHPEdia.pl Planeta Kubek IRC Przetestuj się!

Pierwsze kroki z Zend Framework

Praca z Get i Post

W tradycyjnej aplikacji php 'magiczne' zmienne globalne $_POST oraz $_GET używane są do pozyskiwania danych przesyłanych przez użytkownika. Problem w tym, że bardzo łatwo jest zapomnieć, by dane takie zweryfikować. Kiedy danych takich nie zweryfikujemy, tworzona jest seria problemów związanych z bezpieczeństwem lub zawieszeniem się aplikacji. Zend Framework udostępnia klasę Zend_Filter_Input, aby można było prosto zweryfikować dane pochodzące od użytkownika.

Użycie Zend_Filter_Input:

$postArray = new Zend_Filter_Input($_POST);
$username = $postArray->testName('username');
if ($username !== false) {
    // $username jest poprawny
}

Pamiętajmy jednak, że Zend_Filter_Input kasuje wartości zachowane w $_GET i $_POST. Teraz stworzymy filtry w pliku index.php oraz zachowamy je w Zend::registry, aby mieć do nich dostęp z każdego miejsca naszej aplikacji.

...
Zend::loadClass('Zend_Db');
Zend::loadClass('Zend_Db_Table');
Zend::loadClass('Zend_Filter_Input');
// Rejestruj filtry danych wejściowych
Zend::register('post', new Zend_Filter_Input($_POST));
Zend::register('get', new Zend_Filter_Input($_GET));
// Ładuj konfigurację...

Teraz wartość zachowaną w $_POST możemy wywołać następująco:

$post = Zend::registry('post');
$myVar = $post->testAlpha('myVar');

Dodawanie Alubumów

Kiedy stworzyliśmy już filtr wartości $_POST, możemy zakodować dodawanie nowych albumów w dwóch krokach:

  • Pokazać użytkownikowi formularz do wypełnienia
  • Przetworzyć wysłany formularz i zachować dane w bazie danych

Efekt ten uzyskamy korzystając z akcji addAction():

...
function addAction()
{
    $view = Zend::registry('view');
    $view->title = "Add New Album";
    if (strtolower($_SERVER['REQUEST_METHOD']) == 'post') {
        $post = Zend::registry('post');
        $artist = trim($post->noTags('artist'));
        $title = trim($post->noTags('title'));
        if ($artist != '' && $title != '') {
            $data = array('artist' => $artist,'title' => $title);
            $album = new Album();
            $album->insert($data);
            $url = '/zf-tutorial/';
            $this->_redirect($url);
            return;
        }
    }
    // wstaw 'pusty' album
    $view->album = new stdClass();
    $view->album->id = '';
    $view->album->artist = '';
    $view->album->title = '';
    // Dodatkowe pola$view->action = 'add';
    $view->buttonText = 'Add';
    $view->actionTemplate = 'indexAdd.tpl.php';
    echo $view->render('site.tpl.php');
}
...

Proszę zwrócić uwagę, a jaki sposób sprawdzana jest wartość $_SERVER['REQUEST_METHOD'], by dowiedzieć się, czy formularz został przesłany. Kiedy formularz został wysłany, uzyskujemy wartości artist i title funkcją noTags(), co zapewnia nas, że nie ma w nich kodu HTML, oraz że pola w ogóle zostały wypełnione. Teraz użyjmy klasy z naszego modelu, Album(), aby przesłane od użytkownika informacje dodać do bazy danych.

Na koniec tworzymy widok, który jest gotowy na użycie formularza w szablonie. Akcja edit (edycja) będzie bardzo podobna do tego, co zrobiliśmy powyżej, w związku z czym użyjemy wspólnego szablonu dla indexAdd.tpl.php oraz indexEdit.tpl.php:

Szablony dodawania albumów:

<h1><?php echo $this->escape($this->title); ?></h1>
<?php echo $this->render('_indexForm.tpl.php'); ?>
<form action="/zf-tutorial/index/<?php echo $this->action; ?>"method="post">
<div>
<label for="artist">Artist</label>
<input type="text" class="input-large" name="artist"value="<?php echo $this->escape(trim($this->album->artist));?>"/>
</div>
<div>
<label for="title">Title</label>
<input type="text" class="input-large" 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>

Kod tutaj przedstawiony został celowo uproszczony. Zamierzamy użyć _indexForm.tpl.php również dla akcji edycji. Użyliśmy zmiennej $this->action zamiast kodowania prosto w kodzie akcji. Podobnie użyliśmy zmiennej zawierającej tekst wyświetlający się na przycisku Submit.

Edycja Alubumu

Edycja albumu jest prawie identycznym zadaniem, jak dodawanie nowego CD, w związku z czym jej kod również będzie podobny:

...
function editAction(){
    $view = Zend::registry('view');
    $view->title = "Edit Album";
    $album = new Album();
    if (strtolower($_SERVER['REQUEST_METHOD']) == 'post') {
        $post = Zend::registry('post');
        $id = $post->testInt('id');
        $artist = trim($post->noTags('artist'));
        $title = trim($post->noTags('title'));
        if ($id !== false) {
            if ($artist != '' && $title != '') {
                $data = array('artist' => $artist,'title' => $title,);
                $where = 'id = ' . $id;
                $album->update($data, $where);
                $url = '/zf-tutorial/';
                $this->_redirect($url);
                return;
            } else {
                $view->album = $album->find($id);
            }
        }
    } else {
        // album id powinien byc $params['id]
        $params = $this->_action->getParams();
        $id = 0;
        if (isset($params['id'])) {
            $id = (int)$params['id'];
        }
        if ($id > 0) {
            $view->album = $album->find($id);
        }
    }
    // Dodatkowe pola
    $view->action = 'edit';
    $view->buttonText = 'Update';
    $view->actionTemplate = 'indexEdit.tpl.php';
    echo $view->render('site.tpl.php');
}
...

Zauważmy, że parameter id z tabeli $params uzyskujemy wtedy, kiedy nie jesteśmy w trybie post.

Przykładowy szablon może wyglądać następująco:

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

Refaktorowanie

W trakcie pracy nie powinniśmy zapomnieć o tym, że AddAction() i EditAction() są do siebie bardzo podobne, a ich szablony - wręcz identyczne. Czas więc na refactorowanie!

To zadanie jednak pozostawiam Tobie, drogi Czytelniku!

Kasowanie Albumu

Aby zakończyć naszą prostą aplikację potrzebujemy jeszcze zaimplementować kasowania. Mamy już link kasowania obok każdego albumu na naszej strone głównej, który usunie nam odpowiedni album. To podejście jest jednak ze wszech miar błędne! Przypomina specyfikację HTTP, a my nie powinniśmy wykonywać nieodwracalnych operacji zależnych od GET, a jedynie używać POST. Accelerator beta Googla uświadomił to już niestety wielu ludziom...

Zanim coś skasujemy, powinniśmy wcześniej ukazać użytkownikowi odpowiedni formularz kontrolny, który pozwoli mu potwierdzić chęć usunięcia danego wpisu, bądź też wycofać się z pochopnie podjętego kroku.

Kod będzie tutaj podobny do akcji edit i add:

...
function deleteAction(){
    $view = Zend::registry('view');
    $view->title = "Delete Album";
    $album = new Album();
    if (strtolower($_SERVER['REQUEST_METHOD']) == 'post') {
        $post = Zend::registry('post');
        $id = $post->getInt('id');
        if (strtolower($post->testAlpha('del')) == 'yes' && $id > 0) {
            $where = 'id = ' . $id;
            $album->delete($where);
        }
    } else {
        // album id powinien byc $params['id]
        $params = $this->_action->getParams();
        if (isset($params['id'])) {
            $id = (int)$params['id'];
            if ($id > 0) {
                $view->album = $album->find($id);
                $view->actionTemplate = 'indexDelete.tpl.php';
                // Pokaż tylko wtedy, kiedy mamy id
                echo $view->render('site.tpl.php');
                return;
            }
        }
    }
    // Wróć do listy albumów, 
    // kiedy nie wyświetlamy szablonu
    $url = '/zf-tutorial/';
    $this->_redirect($url);
}
...

Ponownie używamy tutaj sztuczki przy sprawdzaniu metody zapytania, by zadecydować, czy ukazać formularz potwierdzenia, czy też od razu kasować wpis poprzez klasę Album(). Podobnie jak dodawanie i edycja, tak i kasowanie tak naprawdę odbywa się poprzez wywołanie Zend_Db_Table::delete().

Zauważmy tutaj, że po wywołaniu funkcji render() od razu wracamy do punktu wyjścia, by móc wyświetlić listę albumów po operacji kasowania. Jeżeli nie powiedzie się którykolwiek z testów weryfikujacych poprawność wysłanych danych, również wrócimy do listy albumów bez konieczności wielokrotnego wywoływania funkcji _redirect().

Szablon składa się z prostego formularza:

<h1><?php echo $this->escape($this->title); ?></h1>
<?php if ($this->album) :?>
<form action="/zf-tutorial/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;?>
Informacje na podobny temat:
Wasze opinie
Wszystkie opinie użytkowników: (7)
Proponuję alternatywę
Wtorek 09 Luty 2010 1:23:49 pm - siema1980

Proponuję zapoznać się z moim kursem na temat ZF, jest to blog na temat podstaw i myślę, że wszystkim początkującym się przyda - szczególnie tym którzy nie wiedzą jak w ogóle postawić pierwsze kroki w używaniu tej technologii.

http://zend-framework.web-portals.pl

Zapraszam serdecznie.

Zmiany w stosunku do ZF 1.0
Sobota 07 Lipiec 2007 11:41:02 am - elem84

$config->db->config->asArray() ta część jest nieaktualna dla wersji 1.0 należy ją zastąpić $config->db->config->toArray()

Zend
Poniedziałek 26 Luty 2007 10:15:26 am - mrm

czy na pewno to działa ?, stworzyłem odpowiedni pliki, katalogi, skopiowałem cały kod, i nie działa...;/, wydaję mi się że może być 5 przyczyn takiego stanu rzeczy:
1 - źle skopiowałem kod, przeoczyłem cos...
2- mam coś nie tak z serwerem
3- korzystam z wersji 0.8
4- to po prostu nie działa
5 -inne

Szkoła kononowicza
Poniedziałek 29 Styczeń 2007 4:03:22 am - MARIO77 <manius162_at_wp.pl>

cytat:
"Zend Framework rezerwuje również domyślny controller i nie powinno być dla nas niespodzianką, że też się nazywa się on index."

Szkoła KONONOWICZA :D

Wspólny kod HTML
Sobota 16 Grudzień 2006 11:52:21 pm - vallthore

Wspólny kod HTML jest chyba trochę ucięty, a dokładnie początek strony 10 z oryginalnego pdf'a

hehe
Piątek 24 Listopad 2006 4:29:49 pm - sabistik <wiktorski_at_poczta.php.pl>

hehe, ano dobre, dobre. Już poprawiam.

tworzymy widok
Środa 22 Listopad 2006 1:48:14 am - orideith

cytuje ..w związku z czym nie ma seksu używać akcji. hmm seks i zend :)
Nie mogłem się powstrzymac.

Mentax.pl    NQ.pl- serwery z dodatkiem świętego spokoju...   
O nas | Kontakt | Mapa serwisu
Copyright (c) 2003-2022 php.pl    Wszystkie prawa zastrzeżone    Powered by eZ publish Content Management System eZ publish Content Management System