66
ZEND FRAMEWORK: abordagem prática

Zend Framework: abordagem prática

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

ZEND FRAMEWORK:abordagem prática

2

ZEND FRAMEWORK:abordagem prática

MARCELO DE FREITAS ANDRADEhttp://mfandrade.wordpress.com [email protected] 

3

ROTEIRO

● O padrão MVC● Configurando o ZF● Conhecendo o ZF● Análise de situações comuns

4

O PADRÃO MVC

Adaptado debetterexplained.com

5

CONFIGURANDO O ZF

6

CONFIGURANDO O ZF

7

Tutorial Zend Framework:

http://framework.zend.com/docs/quickstart/

CONFIGURANDO O ZF

8

CONFIGURANDO O ZF

9

CONFIGURANDO O ZF

10

CONFIGURANDO O ZF

http://framework.zend.com/download

11

CONFIGURANDO O ZF

Configurar esta pasta para a raiz doservidor web (DocumentRoot).

12

CONFIGURANDO O ZF

OBS: Necessário habilitar o mod_rewrite para reescrita de URLs e o suporte a arquivos .htaccess no Apache, configurando­os 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

22

CONHECENDO O ZF

23

MVC● Zend_Db_Table● Zend_Controller_Action● Zend_View_Helper

CONHECENDO O ZF

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

25

PROGRAMANDO MODELS

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

27

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

29

ESCREVENDO CONTROLLERS

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

35

EXIBIÇÃO DE MENSAGENS

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>

39

FILTROS E VALIDAÇÕES

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

42

POPULANDO CAMPOS

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

48

ASSOCIANDO MODELS

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; ?>

53

ASSOCIANDO MODELS

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; ?>

55

AUTENTICAÇÃO E AUTORIZAÇÃO

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...

58

AUTENTICAÇÃO E AUTORIZAÇÃO

59

AUTENTICAÇÃO E AUTORIZAÇÃO

AUTORIZAÇÃO● recursos (resources)● perfis (roles)

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';}

// ...

61

AUTENTICAÇÃO E AUTORIZAÇÃO

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...

64

65

PERGUNTAS?

66

 

MUITO OBRIGADO!

MARCELO DE FREITAS ANDRADEEspecialista em Desenv. de Aplicações para Internet

[email protected]