Anda di halaman 1dari 21

Iniciando com Zend Framework

Por Rob Allen, www.akrabat.com Traduo: Jos Luciano Brando Calazans Jr., luciano.calazans@gmail.com Reviso do documento 1.5.2 Copyright 2006, 2008 Este tutorial pretende dar uma introduo bsica ao uso do Zend Framework atravs de uma aplicao baseada em bancos de dados. NOTA: Este tutorial foi testado com a verso 1.5 do Zend Framework. Existe uma grande chance de ser compatvel com verses posteriores da srie 1.5.x, mas certamente no funcionar com verses anteriores a 1.5.

Arquitetura Model-View-Controller (Modelo-Viso-Controle)


A maneira tradicional de desenvolver uma aplicao PHP fazer algo parecido com o seguinte:
<?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"; ?>

Atravs do tempo de vida de uma aplicao, uma aplicao escrita desta forma se torna passvel de difcil manuteno conforme o cliente continue requisitando mudanas que so includas em diversos locais de seu cdigo. Um mtodo que melhora a manuteno de uma aplicao separar o cdigo de um arquivo em trs partes distintas (e normalmente arquivos separados): Model A parte de modelo de uma aplicao a parte que se preocupa com os dados especficos a serem mostrados. No cdigo de exemplo acima, o conceito de news. Dessa forma, model geralmente relacionado com a lgica de negcios de uma aplicao e administra o carregamento e o salvamento de dados em um banco de dados. A view consiste em uma pequena parte da aplicao que responsvel em mostrar a informao ao usurio. Normalmente, o HTML. O controller amarra o view e o model para garantir que as informaes corretas sejam mostradas na pgina.

View Controller

O Zend Framework usa a arquitetura Model-View Controller (MVC). Isto usado para separar as diferentes partes de sua aplicao para tornar o desenvolvimento e manuteno mais fcil.

Requisitos
O Zend Framework possui os seguintes requisitos: PHP 5.1.4 (ou superior) Um servidor web que suporte a funcionalidade de mod_rewrite (reescrita de URLs).

Pressupostos do Tutorial
Pressupomos neste tutorial que voc est executando o PHP 5.1.4 ou superior com o servidor web Apache. Sua instalao Apache deve ter a extenso mod_rewrite instalada e configurada. Voc tambm deve assegurar-se que o Apache est configurado para suportar arquivos .htaccess. Isto geralmente feito pela mudana na configurao: AllowOverride None para AllowOverride All no seu arquivo httpd.conf. Consulte a sua documentao da distribuio para detalhes precisos. Voc no ser capaz de navegar para qualquer pgina que no seja a pgina inicial neste tutorial se no tiver configurado o mod_rewrite e o .htacess corretamente.

Obtendo o Framework
O Zend Framework pode ser baixado de http://framework.zend.com/download nos formatos .zip ou .tar.gz.

Estrutura do Diretrio
Apesar de que o Zend Framework no designa uma estrutura de diretrio, o manual recomenda uma estrutura comum, assim que vamos proceder neste tutorial. Esta estrutura assume que voc tenha controle completo sobre a sua configurao do Apache, de modo que voc possa manter a maior parte dos arquivos fora do diretrio raiz da web. Comece criando um diretrio no diretrio raiz do servidor web chamado zf-tutorial e crie os seguintes subdiretrios para receber os arquivos da aplicao:

Como voc pode ver, temos diretrios separados para os arquivos do model, view e controller da nossa aplicao. O diretrio public/ o diretrio raiz do site, o que significa que a URL para a aplicao ser http://localhost/zf-tutorial/public/. Esse , portanto, o porque que a maior parte dos arquivos da aplicao no so acessveis diretamente pelo Apache e por isso so mais seguros. Note: Em um live site, voc iria criar um host virtual para o site e definir o documento raiz diretamente pasta pblica. Por exemplo, voc poderia criar um host virtual chamado zf-tutorial.localhost que parece algo assim:
<VirtualHost *:80> ServerName zf-tutorial.localhost DocumentRoot /var/www/html/zf-tutorial/public <Directory "/www/cs"> AllowOverride All </Directory> </VirtualHost>

O site passaria ento ser acessado pelo endereo http://zftutorial.localhost/ (certifique-se de atualizar seu /etc/hosts ou c:\windows\system32\drivers\etc\hosts, arquivo para que zfia.localhost seja mapeado para 127.0.0.1) Imagens, scripts e arquivos CSS so guardados em diretrios separados sob o diretrio public. Os arquivos do Zend Framework sero colocados no diretrio library. Se ns precisarmos utilizar outras bibliotecas, elas podero ser colocadas l. Extraia o arquivo descarregado, no meu caso, ZendFramework-1.5.0.zip, para um diretrio temporrio. Todos os arquivos foram colocados em um subdiretrio chamado ZendFramework-1.5.0. Copie o subdiretrio /library/Zend para zftutorial/library/. Seu diretrio zf-tutorial/library agora deve conter um subdiretrio chamado Zend.

Inicializando
O controller do Zend Framework, Zend_Controller projetado para dar suporte a websites com urls limpas. Para alcanar isso, todas as requisies precisam passar por um nico arquivo chamado index.php, conhecido como bootstraper. Isto nos prov um ponto central para todas as pginas da aplicao e garante que o ambiente est configurado corretamente para rodar a aplicao. Ns alcanamos isso usando um arquivo .htaccess no diretrio zftutorial/public/:
# Rewrite rules for Zend Framework RewriteEngine on RewriteCond %{REQUEST_FILENAME} !-f RewriteRule .* index.php # Security: Don't allow browsing of directories Options Indexes # PHP settings php_flag magic_quotes_gpc off php_flag register_globals off php_flag short_open_tag on

A RewriteRule muito simples e pode ser interpretada como para qualquer url, redirecione para index.php.

Ns tambm setamos um par de diretivas PHP para segurana e sanidade e setamos a configurao do short_open_tag para on para ser usado nos scripts do view. Estes valores j deveriam estar setados corretamente no php.ini, mas ns queremos ter certeza disso! Note que a flag php_flag no .htaccess s funcionar se voc estiver usando mod_php. Se voc usa CGI/FastCGI, ento voc dever se certificar que o seu php.ini est correto. Note que para que os arquivos .htaccess sejam usados pelo Apache, a diretiva de configurao AllowOverride precisa estar setada como All no seu arquivo httpd.conf.

O arquivo de inicializao: index.php


O arquivo zf-tutorial/public/index.php o nosso arquivo de bootstrap e ns o iniciaremos com o cdigo a seguir: zf-tutorial/public/index.php
<?php error_reporting(E_ALL|E_STRICT); ini_set('display_errors', 1); date_default_timezone_set('Europe/London'); // directory setup and class loading set_include_path('.' . PATH_SEPARATOR . '../library/' . PATH_SEPARATOR . '../application/models' . PATH_SEPARATOR . get_include_path()); include "Zend/Loader.php"; Zend_Loader::registerAutoload(); // setup controller $frontController = Zend_Controller_Front::getInstance(); $frontController->throwExceptions(true); $frontController->setControllerDirectory('../application/controllers'); // run! $frontController->dispatch();

Repare que ns no colocamos a tag ?> no final do arquivo porque isso no necessrio e deixar isso for a ir prevenir alguns erros difceis de debugar quando utilizar o redirecionamento via funo header() caso exista algum espao em branco aps a tag ?>. Vamos percorrer o arquivo.
error_reporting(E_ALL|E_STRICT); ini_set('display_errors', 1); date_default_timezone_set('Europe/London');

Estas linhas iro nos garantir que ns veremos qualquer erro que gerarmos. Ns tambm selecionamos nosso fuso-horrio corrente conforme requerido pelo PHP 5.1+. Obviamente voc deve escolher o seu fuso horrio.
// directory setup and class loading set_include_path('.' . PATH_SEPARATOR . '../library/' . PATH_SEPARATOR . '../application/models' . PATH_SEPARATOR . get_include_path()); include "Zend/Loader.php"; Zend_Loader::registerAutoload();

O Zend Framework projetado para que seus arquivos estejam no include_path. Ns tambm colocamos nosso diretrio de modelos (models) no include_path para que ns possamos carreg-los facilmente depois. Para iniciar, ns precisamos incluir o arquivo Zend/Loader.php que nos dar acesso classe Zend_Loader e depois chamar as funes

do registerAutoload()na ordem para carregar automaticamente todos os arquivos do Zend Framework que ns instanciamos.
// setup controller $frontController = Zend_Controller_Front::getInstance(); $frontController->throwExceptions(true); $frontController->setControllerDirectory('../application/controllers');

Ns precisaremos configurar o front controller para que ele saiba em qual diretrio se encontra os nossos controllers.
$frontController = Zend_Controller_Front::getInstance(); $frontController->setControllerDirectory('./application/controllers'); $frontController->throwExceptions(true);

Como isto um tutorial e ns estamos executando um sistema de testes, eu decidi instruir o front controller para disparar todas as excees que ocorrerem. Por padro, o front controller ir captur-los para ns e redirecion-los para o controller ErrorController para voc. Isto pode ser um pouco confuso para as pessoas que so novatas com o Zend Framework, ento mais fcil apenas re-jogar as excees. claro que em um servidor de produo voc no dever mostrar os erros ao usurio de forma nenhuma. O front controller utiliza uma classe de roteamento para mapear o URL solicitado para a funo PHP correta para ser usado para exibir a pgina. Na ordem do roteador para operar, ele precisa para verificar qual parte do URL o caminho para a nossa index.php para que ele possa enxergar os elementos URI aps este ponto. Isso feito pelo objeto Request (solicitante). Ele faz um trabalho muito bom de auto-detectar a URL base correta, mas se ele no funcionar para sua configurao, ento voc pode sobrepor-lo usando a funo $frontController->setBaseUrl(). Finalmente, ns chegamos no ponto principal e vamos rodar nossa aplicao:
// run! $frontController->dispatch();

Se voc digitar http://localhost/zf_tutorial/public/ para testar, voc certamente encontrar um erro similar a: Fatal error: Uncaught exception 'Zend_Controller_Dispatcher_Exception' with message 'Invalid controller specified (index)' in Isto est nos dizendo que ns no configuramos nossa aplicao ainda. Antes de fazermos isso, ns iremos discutir o que ns iremos construir, ento vamos fazer isso a seguir.

O Website
Ns iremos construir um sistema muitos simples estoque para mostrar a nossa coleo de CD. A pgina principal ir listar a nossa coleo e nos permitir adicionar, editar e excluir CDs. Ns iremos gravar nossa lista em um banco de dados em um esquema como este: Campo Id Artist Titl Tipo Integer Varchar(100) Varchar(100) Null? No No No Descrio Primary key, Autoincrement

Pginas necessrias
As pginas a seguir sero necessrias. Home page Ir mostrar a lista dos lbuns e providenciar links para edit-los e deleta-los. Um link que permitir adicionar novos lbuns tambm estar disponvel. Mostrar um formulrio para adicionar um novo lbum Mostrar um formulrio para edio de um lbum Esta pgina ir confirmar que ns queremos deletar um lbum e ento o deletar.

Add New Album Edit Album Delete Album

Organizando as pginas
Antes de ns configurarmos nossos arquivos, importante entender como o framework espera que as pginas sejam organizadas. Cada pgina da aplicao conhecida como uma ao e aes so agrupadas em controllers. Ex: para a URL com o formato http://localhost/zf-tutorial/public/news/view, o controller news e a ao view. Isto permite um agrupamento de aes relacionadas. Por exemplo, o controller news pode ter aes de list, archived e view. O sistema de MVC do Zend Framework tambm suporta mdulos para agrupar controllers, mas esta aplicao no grande o suficiente para nos preocuparmos com isso. Por padro, o controller do Zend Framework reserva uma ao especial chamada index como uma ao padro. Isto , uma url como http://localhost/zf-tutorial/public/news/ executar uma ao index que est no controller news. O Controller do Zend Framework tambm reserve um controller padro para caso nenhuma seja solicitado. No nenhuma surpresa se ele se chamar index tambm. Dessa forma, a url http://localhost/zf-tutorial/ ir fazer com que a ao index no controller index seja executada. Como este um simples tutorial, ns no iremos nos incomodar com coisas complicadas como login! Isso pode esperar por um tutorial separado... Como ns temos quarto pginas que se aplicam a lbuns, ns iremos agrup-las em um nico controller como quatro aes. Ns devemos usar o controller default e as quatro aes sero: Pgina Pgina Adicionar novo lbum Editar lbum Excluir Album Controller Index Index Index Index Ao index Add Edit Delete

Bom e simples!

Configurando o Controle
Agora ns estamos prontos para configurar o nosso controller. No Zend Framework, o controller uma classe que precisa ser denominada {Nome do controller}Controller. Veja que {Nome do controller} precisa comear com uma letra maiscula. Esta classe precisa estar em um arquivo chamado {Nome do controller}Controller.php dentro do diretrio de controllers especificado. Novamente, {Nome do controller} precisa iniciar com uma letra maiscula e todas as outras precisam ser minsculas. Cada ao um mtodo pblico dentro da classe de controle e precisa se chamar {nome da ao}Action. Neste caso, {nome da ao} deve iniciar como uma letra minscula. Nomenclatura mista

(maisculas e mensculas) dos controllers e das aes so permitidas, mas tm regras especiais que voc deve compreender antes de us-las. Verifique a documentao primeiro! Assim, nossa classe de controle denominada IndexController que est definida em zftutorial/application/controllers/IndexController.php. Crie este arquivo para configurar o esqueleto: zf-tutorial/application/controllers/IndexController.php
<?php class IndexController extends Zend_Controller_Action { function indexAction() { } function addAction() { } function editAction() { } function deleteAction() { } }

Agora configuramos as quatro aes que vamos utilizar. Elas no iro funcionar at que seja criado as views. As URLs para cada ao so as seguintes: URL http://localhost/zf-tutorial/public/ http://localhost/zf-tutorial/public/index/add http://localhost/zf-tutorial/public/index/edit http://localhost/zf-tutorial/public/index/delete Action IndexController::indexAction() IndexController::addAction() IndexController::editAction() IndexController::deleteAction()

Ns temos agora um roteador funcionando e as aes esto sendo executadas corretamente para cada pgina de nossa aplicao. Caso isso no funcione com voc, confira na seo Defeitos que se encontra no final deste tutorial e veja se te ajuda. hora de construirmos a view.

Configurando a Viso
O Componente de viso do Zend Framework chamado, de certa forma sem surpreender, Zend_View. O componente de viso nos permitir separar o cdigo que mostra a pgina do cdigo dos mtodos de ao. O uso bsico do Zend_View :
$view = new Zend_View(); $view->setScriptPath('/path/to/view_files'); echo $view->render('viewScipt.php');

Podemos observar facilmente que se ns colocarmos este esqueleto diretamente em cada um de nossos mtodos de ao, ns iremos repetir o cdigo de configurao, o que no de interesse da ao. Ns devemos de preferncia, fazer a inicializao da viso em algum local e ento acessar o nosso objeto que j est inicializado, em cada um dos mtodos de ao. Os projetistas do Zend Framework previram este tipo de problema e a soluo foi criada no action helper para ns. Zend_Controller_Action_Helper_ViewRenderer teve o cuidado de

inicializar uma propriedade do view ($this->view) para ns e ir renderizar um script do view tambm. Para a renderizao, ele tambm configura o objeto Zend_View para procurar em views/scripts/{nome do controller} pelos scripts de viso(view) que devem ser renderizados e ir (por padro, ao menos) renderizar o script que est nomeado depois da ao com extenso .phtml ({ao}.phtml). Isto , o script do view renderizado views/scripts/{nome do controller}/{nome da ao}.phtml e anexar isso ao corpo do objeto Response. O Objeto Response usado para combinar todos os cabealhos HTTP, contedo de corpo e excees geradas como resultado do uso do sistema de MVC. O front controller ento automaticamente envia os cabealhos e em seguida o corpo do contedo no final. Para integrar a viso na nossa aplicao ns precisamos criar alguns arquivos de views e ento assegurar que isto funciona, ns adicionaremos alguns contedo especfico do action (o ttulo da pgina) dentro das aes do controller. As mudanas no IndexController sero mostradas a seguir (mudanas em negrito): 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"; } }

Em cada mtodo, ns determinamos uma varivel title propriedade view e ento isso! Repare que a exposio no ocorre neste ponto - Isto feito pelo front controller no final do processo. Agora ns precisamos adicionar quatro arquivos de viso para a nossa aplicao. Estes arquivos so conhecidos como scripts ou templates como referido anteriormente, cada arquivo de template nomeado aps esta ao e ter a extenso .phtml para demonstrar que este um arquivo de template. O arquivo precisa estar em um subdiretrio que foi criado aps o controller, ento os quatro arquivos so: 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>

O teste para cada controle/ao dever mostrar os quatro ttulos em negrito.

Cdigos HTML comum


Rapidamente notamos que existem muito cdigo HTML comum em nossas views. Isto um problema muito comum e o componente Zend_Layout desenvolvido para resolver este problema. Zend_Layout nos permite mover todos os cdigos comuns dos cabealhos(header) e rodaps(footer) para um layout do view script que inclui o cdigo do view, que especfico para a ao ser executada. As seguintes alteraes so necessrias. Primeiramente temos de decidir onde colocar os nossos scripts de layout do view. O local recomendado no diretrio application, com isso crie um diretrio chamado layouts no diretrio zf-tutorial/application. Temos que inicializar o sistema Zend_Layout no arquivo de inicializao, assim adicionamos em public/index.php, como isto: zf-tutorial/public/index.php:
... $frontController->throwExceptions(true); $frontController->setControllerDirectory('../application/controllers'); Zend_Layout::startMvc(array('layoutPath'=>'../application/layouts')); // run! $frontController->dispatch();

A funo startMvc()faz alguns trabalhos nos bastidores para configurar um plugin front controller que ir garantir que o componente Zend_Layout renderize o script de layout com os scripts de ao do view dentro dele no final do processo dispatch.

Agora precisamos de um script de layout do view. Por padro, ele chamado de layout.phtml e fica no diretrio de layouts. Ele assim: zf-tutorial/application/layouts/layout.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"> <h1><?php echo $this->escape($this->title); ?></h1> <?php echo $this->layout()->content; ?> </div> </body> </html>

Note que fizemos o nosso cdigo XHTML compatvel e o cdigo HTML padro para a exibio de uma pgina. Como o ttulo da pgina na tag <h1> exibido em todas as pginas, passamos ele para o arquivo de layout e utilizaremos o ajudante (helper) do view escape() para assegurar que ele est codificado adequadamente. Para obter o script do view para a ao atual para exibio, ns exibiremos o contedo do placeholder usando o ajudante (helper) do view do layout():echo $this->layout()-> content; o que faz o trabalho por ns. Isto significa que os scripts do view para a ao esto executando do script de layout do view. Podemos agora esvaziar os 4 scripts de ao pois ainda no temos nada especfico para colocar nele, assim prosseguimos e esvaziamos os arquivos index.phtml, add.phtml, edit.phtml e delete. phtml. Agora voc pode testar todas as 4 URLs novamente e poder ver que no tem nenhuma diferena da ltima vez que voc testou! A diferena chave que desta vez, todo trabalho feito no layout.

Estilos
Mesmo que isso seja somente um tutorial, ns precisaremos de um arquivo CSS para tornar a nossa aplicao um pouco apresentvel! Isso causa um pequeno problema porque atualmente ns no sabemos como referenciar o arquivo CSS porque a URL no aponta para o diretrio raiz correto. Para resolver isso, ns criamos nosso prprio ajudante (helper) do view, chamado baseUrl() que coleta a informao que solicitamos do objeto solicitado. Isto nos proporciona o bit da URL que ns no conhecemos. Os ajudantes (helpers) do view ficam no subdiretrio application/views/helpers e nomeado {Nome do ajudante}.php (a primeira letra deve ser maiscula) e a classe dela deve ser chamada Zend_Controller_Helper_{Nome do ajudante} (novamente, a primeira letra maiscula). Deve haver uma funo na classe chamada {nome do ajudante}() (primeira letra minscula - no esquea!). Em nosso caso, o arquivo chamado BaseUrl.php e assim: zf-tutorial/application/views/helpers/BaseUrl.php
<?php class Zend_View_Helper_BaseUrl { function baseUrl() {

$fc = Zend_Controller_Front::getInstance(); return $fc->getBaseUrl(); } }

No uma funo complicada. Ns simplesmente recriamos uma instancia para o front controller e retornamos a funo membro getBaseUrl(). Ns precisamos adicionar o arquivo CSS para a seo <head> do arquivo application/layouts/layout.phtml: zf-tutorial/application/layouts/layout.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();?>/css/site.css" /> </head> ...

Finalmente, ns precisamos de alguns estilos CSS: zf-tutorial/public/css/site.css


body,html { margin: 0 5px; font-family: Verdana,sans-serif; } h1 { font-size:1.4em; color: #008000; } a { color: #008000; } /* Table */ th { text-align: left; } td, th { padding-right: 5px; } /* style form */ form dt { width: 100px; display: block; float: left; clear: left; } form dd { margin-left: 0; float: left; } form #submitbutton { margin-left: 100px; }

Isto deve tornar ligeiramente mais bonito!

O Banco de dados
Agora que temos o controle da aplicao separado da viso, hora de olhar a seo de modelo (model) da nossa aplicao. Lembre-se que o modelo a parte que lida com o ncleo da aplicao (tambm chamado de regras de negcio) , no nosso caso, lida com o banco de dados. Ns faremos uso da classe Zend_Db_Table do Zend Framework que usada para pesquisar, inserir, alterar e excluir linhas de uma tabela do banco de dados.

Configurao
Para usar a Zend_Db_Table, ns precisamos dizer a ela qual o banco de dados que usaremos e tambm o usurio e a senha. Como ns preferimos no colocar estes dados dentro da nossa aplicao, ns usaremos um arquivo de configurao para guardar esta informao. O Zend Framework oferece a classe Zend_Config para oferecer um acesso orientado a objetos a arquivos de configurao. O arquivo de configurao pode ser um arquivo INI ou um arquivo XML. Ns usaremos o arquivo INI chamado config.ini e armazenaremos ele no diretrio application/: zf-tutorial/application/config.ini
[general] db.adapter = PDO_MYSQL db.params.host = localhost db.params.username = rob db.params.password = 123456 db.params.dbname = zftest

Obviamente voc deve usar o seu nome de usurio, senha e banco de dados, no o meu! Para aplicaes maiores com muitos arquivos de configurao voc pode decidir criar um diretrio separado, como application/config e armazenar todos seus arquivos de configurao juntos, fora do jeito. muito fcil usar o Zend_Config:
$config = new Zend_Config_Ini('config.ini', 'section');

Repare que neste caso, Zend_Config_Ini carrega uma seo do arquivo INI e no todas as sees do arquivo (mas todas as sees podem ser carregadas se voc desejar). Ele suporta uma notao no nome da seo para permitir que sejam carregadas sees adicionais. Zend_Config_Ini tambm trata o ponto no parmetro como separadores hierrquicos que permite o agrupamento de parmetros de configurao relacionados. No nosso config.ini, os parmetros servidor (host), usurio (username) e o nome do banco de dados (dbname) sero agrupados em $config->params->config. Ns iremos carregar o nosso arquivo de configurao no nosso arquivo de inicializao (public/index.php): Parte relevante de zf-tutorial/public/index.php
... include "Zend/Loader.php"; Zend_Loader::registerAutoload(); // load configuration $config = new Zend_Config_Ini('../application/config.ini', 'general'); $registry = Zend_Registry::getInstance(); $registry->set('config', $config);

// setup controller $frontController = Zend_Controller_Front::getInstance(); ...

As mudanas esto em negrito. Ns carregamos as classes que vamos utilizar (Zend_Config_Ini e Zend_Registry) e ento carregar a sesso general de application/config.ini em nosso objeto $config. Finalmente ns atribuimos o objeto $config ao registro para que possamos recuper-lo em qualquer lugar da aplicao. Nota: Neste tutorial, ns no precisamos guardar o $config no registro, mas uma boa prtica em uma aplicao real que voc ter mais que uma configurao de banco de dados no arquivo INI. Porm, esteja avisado que o registro um pouco global e causa dependncias entre objetos que no deveriam depender um do outro, se voc no for cuidadoso.

Configurando Zend_Db_Table
Para usar a Zend_Db_Table, ns precisaremos informar a configurao de banco de dedos que ns carregamos. Para fazer isso ns precisamos criar uma instncia da Zend_Db e ento registra-la usando a funo esttica Zend_Db_Table::setDefaultAdapter(). Novamente, ns fazemos isso no arquivo de inicializao (adies em negrito): Parte relevante de zf-tutorial/public/index.php
... $registry = Zend_Registry::getInstance(); $registry->set('config', $config); // setup database $db = Zend_Db::factory($config->db); Zend_Db_Table::setDefaultAdapter($db); // setup controller $frontController = Zend_Controller_Front::getInstance(); ...

Como voc pode ver, a Zend_Db_Table tem uma funo esttica factory()que interpreta os dados a partir do objeto $config->db e instancia o adaptador correto do banco de dados para ns.

Criando a tabela
Eu estarei usando MySQL e ento o comando SQL para criar a tabela :
CREATE TABLE albums ( id int(11) NOT NULL auto_increment, artist varchar(100) NOT NULL, title varchar(100) NOT NULL, PRIMARY KEY (id) );

Execute o comando em um client MySQL como o phpMyAdmin ou o cliente de linha de comando MySQL padro.

Inserindo albums de teste


Ns precisaremos inserir algumas linhas na tabela para que ns possamos testar a funcionalidade de recuperao da pgina principal. Eu estarei pegando os primeiros dois CDs do Top Sellers do site Amazon.co.uk:

INSERT INTO albums (artist, title) VALUES ('Duffy', 'Rockferry'), ('Van Morrison', 'Keep It Simple');

O Modelo
Zend_Db_Table uma classe abstrata, ento ns temos que derivar nossa classe que especfica para gerenciar os albums. No importa como denominaremos a nossa classe, mas faz sentido que ela tenha o mesmo nome que a tabela do banco de dados. Assim, nossa classe ser denominada Albums como a nossa tabela que se chama albums. Para informar a Zend_Db_Table o nome da tabela que iremos gerenciar, ns temos que setar a propriedade protegida $_name para o mesmo nome da tabela. Tambm, Zend_Db_Table assume que a chave primria da sua tabela seja denominada id que auto-incrementada pelo banco de dados. O nome deste campo pode ser mudado tambm se necessrio. Ns iremos guardar nossa classe Album num arquivo chamado Album.php no diretrio applications/models: zf-tutorial/application/models/Albums.php zf-tutorial/application/models/Albums.php
<?php class Albums extends Zend_Db_Table { protected $_name = 'albums'; }

No muito complicado, n?! Felizmente para ns, nossas necessidades so muito simples e a Zend_Db_Table fornece toda a funcionalidade que precisamos. De qualquer forma, se voc necessita de alguma funcionalidade especfica para gerenciar seu modelo, ento nesta classe que voc deve coloc-la. Geralmente, as funcionalidades adicionais que sero mtodos como find que retornaro colees de dados que voc precisa. Voc tambm pode informar a Zend_Db_Table sobre relacionamentos de tabelas e ela busca os dados relacionados tambm.

Listando os albums
Agora que ns j fizemos a configurao e as informaes do banco de dados, ns podemos ir para a parte a aplicao que mostra alguns lbuns. Isto sera feito na classe IndexController e ns iniciamos listando os albums numa tabela na funo indexAction(): zf-tutorial/application/controllers/IndexController.php
... function indexAction() { $this->view->title = "My Albums"; $albums = new Albums(); $this->view->albums = $albums->fetchAll(); } ...

A funo fetchAll() retorna a Zend_Db_Table_Rowset que nos permitir fazer a iterao das linhas retornadas no arquivo de script das aes do view. Agora ns podemos preencher o arquivo ndex.phtml

zf-tutorial/application/views/scripts/index/index.phtml
<p><a href="<?php echo $this->url(array('controller'=>'index', 'action'=>'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->url(array('controller'=>'index', 'action'=>'edit', 'id'=>$album->id));?>">Edit</a> <a href="<?php echo $this->url(array('controller'=>'index', 'action'=>'delete', 'id'=>$album->id));?>">Delete</a> </td> </tr> <?php endforeach; ?> </table>

A primeira coisa que faremos criar um link para adicionar um novo lbum. A url() fornecido pelo framework e ajuda a criar links incluindo a URL base correta. Ns simplesmente passamos em um array dos parmetros que. Ns ento criaremos uma tabela html para mostrar cada ttulo do lbum, artista e fornecer links para permitir a edio e apagar o registro. Um loop padro foreach usado para fazer a iterao da lista de lbuns, e utilizaremos a forma alternativa usando um colon endforeach. Novamente, a url()do helper do view usado para criar os links de editar e apagar. http://localhost/zf-tutorial/ (ou de onde voc estiver chamando!) dever mostrar agora uma bela lista de (dois) lbuns, como esta:

Adicionando novos lbuns


Ns poderemos agora codificar a funcionalidade para adicionar novos albums. Abaixo duas partes: Mostrar um formulrio para o usurio fornecer os detalhes Processar a submisso do formulrio e gravar em um banco de dados

Usamos Zend_Form para fazer isto. O componente Zend_Form nos permite criar um formulrio e validar a entrada (input). Ns criamos um novo classe do model AlbumForm que se estende do Zend_Form para definir nosso formulrio: zf-tutorial/application/models/AlbumForm.php
<?php class AlbumForm extends Zend_Form { public function __construct($options = null) { parent::__construct($options); $this->setName('album'); $id = new Zend_Form_Element_Hidden('id'); $artist = new Zend_Form_Element_Text('artist'); $artist->setLabel('Artist') ->setRequired(true) ->addFilter('StripTags') ->addFilter('StringTrim') ->addValidator('NotEmpty'); $title = new Zend_Form_Element_Text('title'); $title->setLabel('Title') ->setRequired(true) ->addFilter('StripTags') ->addFilter('StringTrim') ->addValidator('NotEmpty'); $submit = new Zend_Form_Element_Submit('submit'); $submit->setAttrib('id', 'submitbutton'); $this->addElements(array($id, $artist, $title, $submit)); } }

Dentro do construtor do AlbumForm, criamos quatro elementos de formulrio para a id, artista, ttulo, e boto submit. Para cada item ns definiremos vrios atributos, incluindo o rtulo a ser exibido. Para os elementos de texto, acrescentamos dois filtros, StripTags e StringTrim para eliminar indesejadas HTML e espaos em branco desnecessrios. Ns tambm iremos configur-los para ser necessrio e adicionar um validador NotEmpty a fim de garantir que o usurio insira a informao necessria. Precisamos agora obter o formulrio para exibir e depois process-lo na submisso. Isso feito no addAction():

zf-tutorial/application/controllers/IndexController.php
... function addAction() { $this->view->title = "Add New Album"; $form = new AlbumForm(); $form->submit->setLabel('Add'); $this->view->form = $form; if ($this->_request->isPost()) { $formData = $this->_request->getPost(); if ($form->isValid($formData)) { $albums = new Albums(); $row = $albums->createRow(); $row->artist = $form->getValue('artist'); $row->title = $form->getValue('title'); $row->save(); $this->_redirect('/'); } else { $form->populate($formData); } } } ...

Vamos examinar isto com um pouco mais de detalhes:


$form = new AlbumForm(); $form->submit->setLabel('Add'); $this->view->form = $form;

Ns instanciamos nossa AlbumForm, setamos o label do boto submit para Add e, em seguida, atribumos a view para renderizar.
if ($this->_request->isPost()) { $formData = $this->_request->getPost(); if ($form->isValid($formData)) {

Se os objetos solicitados do mtodo isPost()for true, ento o formulrio foi submetido e, por isso, ns recuperamos os formulrios de dados do pedido usando getPost() e verificar para ver se ele vlido usando a funo membro isValid().
$albums = new Albums(); $row = $albums->createRow(); $row->artist = $form->getValue('artist'); $row->title = $form->getValue('title'); $row->save(); $this->_redirect('/');

Se o formulrio for vlido, ento instanciamos a classe Albums do model e utilizamos createRow() para obter uma linha vazia e, em seguida, preencher o artista (artist) e ttulo (title) antes de salvar. Depois de salvar a nova linha do album, redirecionamos usando o mtodo _redirect() do controller para voltar pgina inicial.
} else { $form->populate($formData); }

Se os dados do formulrio no for vlido, ento ns preencheremos o formulrio com os dados que o usurio preencheu reexibiremos. Precisamos agora renderizar o formulrio no script add.phtml do view. zf-tutorial/application/views/scripts/index/add.phtml
<?php echo $this->form ;?>

Como voc pode ver, renderizar um formulrio muito simples, como o formulrio sabe como ser mostrado na tela.

Editando um lbum
Editar um lbum quase idntico a adicionar um, ento o cdigo muito similar: zf-tutorial/application/controllers/IndexController.php
... function editAction() { $this->view->title = "Edit Album"; $form = new AlbumForm(); $form->submit->setLabel('Save'); $this->view->form = $form; if ($this->_request->isPost()) { $formData = $this->_request->getPost(); if ($form->isValid($formData)) { $albums = new Albums(); $id = (int)$form->getValue('id'); $row = $albums->fetchRow('id='.$id); $row->artist = $form->getValue('artist'); $row->title = $form->getValue('title'); $row->save(); $this->_redirect('/'); } else { $form->populate($formData); } } else { // album id is expected in $params['id'] $id = (int)$this->_request->getParam('id', 0); if ($id > 0) { $albums = new Albums(); $album = $albums->fetchRow('id='.$id); $form->populate($album->toArray()); } } } ...

Vamos analisar as diferenas em adicionar um album. Primeiramente, ao exibir o formulrio para o usurio ns precisamos de recuperar o artista do lbum e o ttulo do banco de dados e preencher os elementos do formulrio:
// album id is expected in $params['id'] $id = (int)$this->_request->getParam('id', 0); if ($id > 0) { $albums = new Albums(); $album = $albums->fetchRow('id='.$id); $form->populate($album->toArray()); }

Isto feito se o pedido (request) no um POST e utiliza o modelo (model) para recuperar a linha do banco de dados. A classe Zend_Db_Table_Row tem uma funo membro toArray() que podemos utilizar para preencher o formulrio diretamente. Finalmente, precisamos salvar o dado na linha direita do banco de dados. Isto estar concludo pela recuperao da linha de dados e depois salv-la novamente.
$albums = new Albums(); $id = (int)$form->getValue('id'); $row = $albums->fetchRow('id='.$id);

O template do view o mesmo de add.phtml.


<?php echo $this->form ;?>

Agora voc j poder adicionar e editar lbuns.

Excluindo um lbum
Para deixar nossa aplicao redonda, ns precisamos adicionar a excluso. Ns temo um link Delete perto de cada lbum em nossa pgina da listagem e ele tem que executar uma excluso quando ele clicado passando os parmetros por GET. Isto pode estar errado. Relembrando nossa especificao HTTP, ns no devemos fazer uma ao irreversvel usando GET e devemos usar POST. Ns mostraremos um formulrio de confirmao quando o usurio clicar em excluir e se ele clicar em sim, ns faremos a excluso. Como este formulrio trivial, ns iremos apenas criar o formulrio HTML no script do view. Vamos iniciar com o cdigo da ao: zf-tutorial/application/controllers/IndexController.php
... function deleteAction() { $this->view->title = "Delete Album"; if ($this->_request->isPost()) { $id = (int)$this->_request->getPost('id'); $del = $this->_request->getPost('del'); if ($del == 'Yes' && $id > 0) { $albums = new Albums(); $where = 'id = ' . $id; $albums->delete($where); } $this->_redirect('/'); } else { $id = (int)$this->_request->getParam('id'); if ($id > 0) { $albums = new Albums(); $this->view->album = $albums->fetchRow('id='.$id); } } } ...

Utilizaremos o mtodo de requisio isPost() para o funcionamento se ns queremos exibir o formulrio de confirmao ou se ns quisermos fazer uma excluso atravs da classe Albm(). A real excluso feita atravs de uma chamada para o mtodo delete() da Zend_Db_Table. Se a requisio no um post, ento ns olharemos para um parmetro id e recuperaremos o registro correto do banco de dados e atribuiremos para o view.

O Template (script) um simples formulrio: zf-tutorial/application/views/scripts/index/delete.phtml


<?php if ($this->album) :?> <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> <form action="<?php echo $this->url(array('action'=>'delete')); ?>" method="post"> <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;?>

Neste script, apresentaremos uma mensagem de confirmao para o usurio e, em seguida, um formulrio com os botes sim e no. Na ao, verificamos especialmente para o valor Sim ao fazer a excluso. isso a voc j tem uma aplicao completa funcionando.

Defeitos
Se voc est tendo problemas ao executar outra ao diferente de index/index, ento o problema que o roteador est incapaz de determinar em qual subdiretrio seu website est. Das minhas investigaes, isso normalmente acontece quando a url para seu website difere do caminho para o diretrio raz do servidor web. Se o cdigo padro no funcionou para voc, ento voc deve setar a varivel $baseURL para o valor correto do seu servidor: zf-tutorial/public/index.php
... // setup controller $frontController = Zend_Controller_Front::getInstance(); $frontController->throwExceptions(true); $frontController->setControllerDirectory('../application/controllers'); $frontController->setBaseUrl('/mysubdir/zf-tutorial/public'); Zend_Layout::startMvc(array('layoutPath'=>'../application/layouts')); ...

Voc dever substituir '/mysubdir/zf-tutorial/public' pela URL correta para o index.php. Por exemplo, se a URL para seu index.php http://localhost/~ralle/zf_tutorial/public/index.php ento o valor correto para $baseUrl '/~ralle/zf-tutorial/public'.

Concluso
Isto conclui nossa viso geral construindo uma aplicao MCV simples, mas completamente funcional usando o Zend Framework. Eu espero que voc tenha achado interessante e informativo. Se voc achou que algo est errado, por favor, me envie um email para: rob@akrabat.com!

Este tutorial mostrou apenas o bsico do Zend Framework; ainda existem muitas classes a serem exploradas. Voc realmente deveria ir e ler o manual (http://framework.zend.com/manual) e olhar o wiki (http://framework.zend.com/wiki) para mais introspeces! Se voc est interessado no desenvolvimento do framework, ento o wiki de desenvolvimento (http://framework.zend.com/developer) o seu lugar.