Upload
marcelo-andrade
View
6.212
Download
1
Embed Size (px)
DESCRIPTION
Apresentação para subsidiar equipe de desenvolvedores da Secretaria de Educação do Pará (SEDUC) na definição de framework PHP para desenvolvimento. A apresentação foca em aspectos práticos, compartilhando experiências de utilização do Zend Framework, sua configuração, utilização básica e análise de situações comuns.
Citation preview
2
ZEND FRAMEWORK:abordagem prática
MARCELO DE FREITAS ANDRADEhttp://mfandrade.wordpress.com [email protected]
12
CONFIGURANDO O ZF
OBS: Necessário habilitar o mod_rewrite para reescrita de URLs e o suporte a arquivos .htaccess no Apache, configurandoos de acordo com o tutorial.
13
/public/index.php
<?php// Passo 1define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application/'));set_include_path( APPLICATION_PATH . '/../library' . PATH_SEPARATOR . get_include_path());
// Passo 2require_once "Zend/Loader.php";Zend_Loader::registerAutoload();
(continua...)
14
/public/index.php
// Passo 3try { require '../application/bootstrap.php';} catch (Exception $exception) { echo '<html><body><center>' . 'Uma exceção ocorreu!.'; if (defined('APPLICATION_ENVIRONMENT') && APPLICATION_ENVIRONMENT != 'production' ) { echo '<br /><br />' . $exception->getMessage() . '<br />' . '<div align="left">Stack Trace:' . '<pre>' . $exception->getTraceAsString() . '</pre></div>'; } echo '</center></body></html>'; exit(1);}
// Passo 4Zend_Controller_Front::getInstance()->dispatch();
15
/application/bootstrap.php
<?php// Constantedefined('APPLICATION_PATH') or define('APPLICATION_PATH', dirname(__FILE__));
// Tipo de ambientedefined('APPLICATION_ENVIRONMENT') or define('APPLICATION_ENVIRONMENT', 'development');
// Inicia os controllers$frontController = Zend_Controller_Front::getInstance();
// Onde estão nosso controllers $frontController->setControllerDirectory(APPLICATION_PATH . '/controllers');
// Repassa a constante aos controllers$frontController->setParam('env', APPLICATION_ENVIRONMENT);
16
/application/bootstrap.php
(continuação...)
// Teremos layouts de site?Zend_Layout::startMvc(APPLICATION_PATH . '/layouts');
// Arquivo de configuração$configuration = new Zend_Config_Ini( APPLICATION_PATH . '/config.ini', APPLICATION_ENVIRONMENT);
// Registro$registry = Zend_Registry::getInstance();$registry->configuration = $configuration;$registry->dbAdapter = $dbAdapter;
// Limpa para encerrarunset($frontController);
17
/application/controllers/IndexController.php
<?php// application/controllers/IndexController.php
class IndexController extends Zend_Controller_Action { public function indexAction() { }}
<? // application/views/index/index.phtml ?><h1 align="center"> Hello, Zend Framework MVC!</h1>
/application/views/index/index.phtml
18
/application/controllers/ErrorController.php
<?php class ErrorController extends Zend_Controller_Action { public function errorAction() { $this->_helper->viewRenderer->setViewSuffix('phtml'); $errors = $this->_getParam('error_handler');
switch ($errors->type) { case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_CONTROLLER: case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ACTION:
$this->getResponse()->setHttpResponseCode(404); $this->view->message = 'Página não encontrada.'; break; default: $this->getResponse()->setHttpResponseCode(500); $this->view->message = 'Application error'; break; }
19
(continuação...)
$this->view->env = $this->getInvokeArg('env'); $this->view->exception = $errors->exception; $this->view->request = $errors->request; } }
/application/controllers/ErrorController.php
20
<h1>Ocorreu um erro!</h1> <h2><?= $this->message ?></h2>
<? if ('development' == $this->env): ?> <h3>Exceção ocorrida:</h3> <p> <b>Menssagem:</b> <?= $this->exception->getMessage() ?> </p>
<h3>Stack trace:</h3> <pre><?= $this->exception->getTraceAsString() ?></pre>
<h3>Parâmetros da requisição:</h3> <pre><? var_dump($this->request->getParams()) ?></pre> <? endif ?>
/application/views/error/error.phtml
21
<?= $this->doctype() ?><html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>ProjetoZF</title> <?= $this->headScript() ?> <?= $this->headLink()->appendStylesheet('/css/global.css') ?></head> <body> <div id=”header”>
<h1>Bem-vindo ao ProjetoZF!</h1><a href=”<?= $this->url(array('controller'=> 'index', 'action'=>
'index')) ?>“>Página inicial</a> </div>
<div id=”content”><?= $this->layout()->content ?>
</div></body></html>
/application/layouts/layout.phtml
24
;; /application/config.ini[producao]database.adapter = PDO_MYSQLdatabase.params.host = dbserver.example.comdatabase.params.username= usernamedatabase.params.password= passworddatabase.params.dbname = dbname
[teste : producao]database.params.dbname = dbname_test
[desenv : producao]database.params.dbname = dbname_desenvdatabase.params.host = dbtest.example.com
CONFIGURANDO O BANCO
26
<?phpclass GenericModel extends Zend_Db_Table{
// insere dados do array em campos homônimospublic function insert(array $data){
$fields = $this->info(Zend_Db_Table_Abstract::COLS);
foreach ($data as $field => $value)if (!in_array($field, $fields))
unset($data[$field]);
return parent::insert($data);}
}
PROGRAMANDO MODELS
28
<?phprequice_once APPLICATION_PATH . '/models/GenericModel.php';
class Post extends GenericModel{
// lógica de negócio “blug do futuro”public function publicar($data){
$data['created']= date('Y-m-d', strtotime('now +7 days');
return parent::insert($data);
}
}
PROGRAMANDO MODELS
30
<?phpclass PostController extends Zend_Controller_Action
{// definir referência ao modelprotected $_Post;
public function init(){
// instanciar os models e outras operaçõesrequire_once APPLICATION_PATH . '/models/Post.php';
$this->_Post= new Post();
}
ESCREVENDO CONTROLLERS
31
// (continuação...)// lista todos os posts e joga para a viewpublic function indexAction(){
$posts= $this->_Post->fetchAll();$this->view->posts= $posts->toArray();
}// action para visualizar um dado postpublic function verAction(){
$parms= $this->getRequest()->getParams();$postid= $parms['id'];$post= $this->_Post->find($postid);$this->view->post= $post;
}
ESCREVENDO CONTROLLERS
32
<!-- /application/views/post/index.phtml --><?php foreach($this->posts as $post): ?>
<h2><a href=”<?php echo $this->url(array('controller'=> 'post', 'action'=> 'ver', 'id'=> $post['id'])); ?>”>
<?php echo $post['titulo']; ?></a></h2>
<h3>Publicado em: <?phpecho $post['created']; ?></h3>
<p><?php echo nl2br($post['texto']); ?></p>
<?php endfor; ?>
DEFININDO VIEWS
33
● EXIBIÇÃO DE MENSAGENS● FILTROS E VALIDAÇÕES● POPULANDO CAMPOS● ASSOCIANDO MODELS● AUTENTICAÇÃO E AUTORIZAÇÃO
ANÁLISE DE SITUAÇÕES COMUNS
34
● EXIBIÇÃO DE MENSAGENS● FILTROS E VALIDAÇÕES● POPULANDO CAMPOS● ASSOCIANDO MODELS● AUTENTICAÇÃO E AUTORIZAÇÃO
http://framework.zend.com/manual/en/
ANÁLISE DE SITUAÇÕES COMUNS
36
EXIBIÇÃO DE MENSAGENS
<?phpclass GenericController extends Zend_Controller_Action
{protected $_mess; protected $_redir;
public function init(){
$this->_mens= $this->_helper->getHelper('FlashMessenger');
$this->_redir= $this->_helper->getHelper('Redirector');
}
37
EXIBIÇÃO DE MENSAGENS
// (continuação...)
protected function flash($msg, $to){
$this->_mess->addMessage($msg);$this->_redir->gotoUrl($to);exit;
}
public function postDispatch(){
$this->view->messages= join(' ', $this->_mess->getMessages());
parent::postDispatch();}
}
38
EXIBIÇÃO DE MENSAGENS<?= $this->doctype() ?><html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>ProjetoZF</title> <?= $this->headScript() ?> <?= $this->headLink()->appendStylesheet('/css/global.css') ?></head> <body> <div id=”header”>
<h1>Bem-vindo ao ProjetoZF!</h1><a href=”<?= $this->url(array('controller'=> 'index', 'action'=>
'index')) ?>“>Página inicial</a> </div>
<div id=”messages”><?= $this->messages ?></div>
<div id=”content”><?= $this->layout()->content ?>
</div></body></html>
40
// PostController.phppublic function novoAction(){
$req= $this->getRequest();if( $req->isPosted() ){
$data= $req->getParameters();$this->_Post->insert($data);
}}
FILTROS E VALIDAÇÕES
41
// PostController.phppublic function novoAction(){
$req= $this->getRequest();if( $req->isPosted() ){
$data= $req->getParameters();
$filters= array('*'=> 'StringTrim');$validators= array('titulo'=>'Alpha');$input= new Zend_Input_Filter($filters, $validators, $data);
if( $input->isValid() ):$this->_Post->insert($input);$this->flash('Sucesso!', '/index');
endif;}
}
FILTROS E VALIDAÇÕES
43
<!-- /appplication/views/post/novo.phtml --><?php echo $this->form('novoForm', array('method'=> 'post'));
echo $this->formErrors(); ?>
<fieldset><legend>Novo Post</legend>
<?php echo $this->formLabel('titulo', 'Título:');echo $this->formText('titulo');echo $this->formLabel('texto', 'Texto:');echo $this->formTextarea('texto', null, array('rows'=> 3, 'cols'=> 30));
echo $this->formSubmit('btnOk', 'Cadastrar'); ?>
</fieldset></form>
POPULANDO CAMPOS
44
<!-- /appplication/views/post/novo.phtml --><?php echo $this->form('novoForm', array('method'=> 'post'));
echo $this->formErrors(); ?>
<fieldset><legend>Novo Post</legend>
<?php echo $this->formLabel('titulo', 'Título:');echo $this->formText('titulo');echo $this->formLabel('texto', 'Texto:');echo $this->formTextarea('texto', null, array('rows'=> 3, 'cols'=> 30));
echo $this->formSelect('categoria_id', null, null, array('Dicas', 'Tutoriais', 'Artigos') );
echo $this->formSubmit('btnOk', 'Cadastrar'); ?></fieldset></form>
POPULANDO CAMPOS
45
POPULANDO CAMPOS
// PostController.phppublic function novoAction(){
$req= $this->getRequest();
$categorias= $this->_Post->findList();$this->view->categorias= $categorias;
if( $req->isPosted() ){
$data= $req->getParameters();
$filters= array('*'=> 'StringTrim');$validators= array('title'=>'Alpha');$input= new Zend_Input_Filter($filters, $validators, $data);
if( $input->isValid() )$this->Post->insert($input);
}}
46
POPULANDO CAMPOS
// GenericModel.php public function fetchList($first= 'Selecione...', $id= 'id', $description= 'descricao', $where= null, $order= null, $count= null, $offset= null) {
$fetchedOptions= $this->fetchAll($where, $order, $count, $offset);
if( $first != null ):$listOptions[' ']= $first;
endif;foreach( $fetchedOptions as $option ):
$listOptions[$option[$id]]= $option[$description];
endforeach;return $listOptions;
}
47
<!-- /appplication/views/post/novo.phtml --><?php echo $this->form('novoForm', array('method'=> 'post'));
echo $this->formErrors(); ?>
<fieldset><legend>Novo Post</legend>
<?php echo $this->formLabel('titulo', 'Título:');echo $this->formText('titulo');echo $this->formLabel('texto', 'Texto:');echo $this->formTextarea('texto', null, array('rows'=> 3, 'cols'=> 30));
echo $this->formSelect('categoria_id', null, null, $this->categorias );
echo $this->formSubmit('btnOk', 'Cadastrar'); ?></fieldset></form>
POPULANDO CAMPOS
49
ASSOCIANDO MODELS
<?phprequice_once APPLICATION_PATH . '/models/GenericModel.php';
class Post extends GenericModel{
protected $_referenceMap= array('Categoria'=> array(
'columns' => 'categoria_id', 'refTableClass'=> 'categoria', 'refColumns' => 'id'));
protected $_dependentTables=array('PostTag');
50
ASSOCIANDO MODELS
<?phpclass PostController extends Zend_Controller_Action
{// (...)
// lista todos os posts e joga para a viewpublic function indexAction(){
$posts= $this->Post->fetchAll();$this->view->posts= $posts;
}
51
ASSOCIANDO MODELS
<!-- /application/views/post/index.phtml --><?php foreach($this->posts as $post): ?>
...
<h3>Publicado em: <?phpecho $post->created; ?></h3>
<?php $categoria= $post->findDependentRowset('Categoria');echo $categoria->descricao; ?>
<p><?php echo nl2br($post->texto); ?></p>
<?php endfor; ?>
52
ASSOCIANDO MODELS
<!-- /application/views/post/index.phtml --><?php foreach($this->posts as $post): ?>
...
<h3>Publicado em: <?phpecho $post->created; ?></h3>
<?php $categoria= $post->findCategoriaByPost();echo $categoria->descricao; ?>
<p><?php echo nl2br($post->texto); ?></p>
<?php endfor; ?>
54
ASSOCIANDO MODELS
<!-- /application/views/post/index.phtml --><?php foreach($this->posts as $post): ?>
...
<h3>Publicado em: <?phpecho $post->created; ?></h3>
<?php $tags= $post->findManyToManyRowset('Tag', 'PostTag');echo implode(', ', $tags->toArray()); ?>
<p><?php echo nl2br($post->texto); ?></p>
<?php endfor; ?>
56
AUTENTICAÇÃO E AUTORIZAÇÃO
<?phprequice_once APPLICATION_PATH . '/models/GenericController.php';
class AuthController extends GenericController{
public function loginAction(){
// como autenticar um usuário...$req= $this->getRequest();if( $req->isPosted() ) {
$parms= $req->getParams();// método para validar campos login e senha$input= $this->__validate($parms);
57
AUTENTICAÇÃO E AUTORIZAÇÃO
// ... $db= Zend_Registry::get('dbAdapter'); $adap= new Zend_Auth_Adapter_DbTable($db); $adap->setTableName('usuario'); $adap->setIdentityColumn('login'); $adap->setCredentialColumn('senha');
$adap->setIdentity($input->usuario); $adap->setCredential(md5($input->senha));
$auth= Zend_Auth::getInstance(); $result= $auth->authenticate($auth);
if( $result->isValid() ) // trata a autenticação...
60
AUTENTICAÇÃO E AUTORIZAÇÃO
<?phprequire_once . APPLICATION_PATH . '/controllers/GenericController.php';
class PostController extends GenericController implements Zend_Acl_Resource_Interface
{// definir referência ao modelprotected $_Post;
public function getResourceId(){
return 'POST';}
// ...
62
AUTENTICAÇÃO E AUTORIZAÇÃO
// GenericController.php
private function __configPerms(){ // define perfis
$chefe= new Zend_Acl_Role('chefe');$escritor= new Zend_Acl_Role('escritor', $chefe);
$this->_acl= new Zend_Acl();$this->_acl->addRole($chefe);$this->_acl->addRole($escritor);// define recursos$this->_acl->add(new Zend_Acl_Resource('POST'));
// define as permissões$this->_acl->allow('chefe', 'POST', null);$this->_acl->deny('escritor', 'POST', 'novo');
}
63
AUTENTICAÇÃO E AUTORIZAÇÃO
// GenericController
public function preDispatch(){
// recuperar o usuário autenticado...$usuario= $this->__obterUsuarioAutenticado();$req= $this->getRequest();
if($this->_acl->isAllowed($usuario->perfil, strtoupper($req->getControllerName()), $req->getActionName()))
// trata a autorização...
66
MUITO OBRIGADO!
MARCELO DE FREITAS ANDRADEEspecialista em Desenv. de Aplicações para Internet