No PHP, usar var_dump(), print_r() e afins no meio do código não só é uma maneira pouco eficiente como pouco elegante de encontrar e reduzir erros no código. Depurar é uma boa maneira de fazer isso e temos uma ótima extensão do PHP chamada xDebug para nos ajudar.

Instalação

No Windows, a maneira mais simples de instalar o xdebug é baixar a extensão como dll no site oficial da extensão e configurar o php.ini para que o PHP possa reconhecer a extensão:

zend_extension_ts="C:/caminho/para/o/php/ext/php_xdebug.dll"

Para as versões até 5.2.x deve ser usado zend_extension_ts, enquanto que para a 5.3, zend_extension.

Além disso, podemos setar algumas configurações da própria extensão no arquivo. Algumas específicas, para permitir saber mais sobre o que acontece na execução:

xdebug.collect_includes = On
xdebug.collect_params = On
xdebug.collect_return = On
xdebug.collect_vars = On
xdebug.dump_globals = On
xdebug.show_local_vars = On
xdebug.dump.GET=*
xdebug.dump.POST=*
xdebug.dump.COOKIE=*
xdebug.dump.ENV=*
xdebug.dump.FILES=*
xdebug.dump.REQUEST=*
xdebug.dump.SERVER=*
xdebug.dump.SESSION=*

Dando um restart no Apache, o xdebug deve estar listado no phpinfo() com todas as configurações setadas.

Usos do xdebug

Podemos conseguir diversos tipos de informações sobre o que acontece em nossa aplicação. O mais comum é o xdebug mostrar no html quais erros acontecem. Faça o teste:

<?php

$teste = array("um", "teste", "qualquer");

include("umarquivonaoexistente.php");

var_dump($var);

?>

Rodando a página, ele nos diz que não encontrou o arquivo não existe e nos mostra os valores das variáveis até dar que o erro ocorresse. Além disso, podemos observar que o var_dump() foi sobrescrito pelo xdebug, tornando mais fácil a leitura dos valores.

Trace

Podemos também coletar informações sobre a execução do arquivo, guardando em um arquivo separado. O Trace pode ser feito tanto pelo arquivo de configuração:

xdebug.auto_trace=1
xdebug.trace_output_dir=/caminho

quanto individualmente, no arquivo:

<?php

xdebug_start_trace("/caminho/para/o/trace");

$soma = soma(1,2);

xdebug_stop_trace();

?>

Xdebug Remoting

Podemos também configurar o xdebug para ser usado com IDEs, permitindo assim acompanhar os valores de variáveis, colcoar pontos de parada como é normalmente feito no debug com outras linguagens.

Para permitir que isso aconteça, tem que adicionar nas configurações:

xdebug.remote_enable=1
xdebug.remote_host=127.0.0.1
xdebug.remote_port=9000
xdebug.remote_handler=dbgp

Diversas IDEs e editores já funcionam com o xdebug: Netbeans, Eclipse, Notepad++, o plugin para o VIM, entre outros.

Posted in php at dezembro 5th, 2009. No Comments.

Continuando do post passado, agora vou tratar de assuntos mais específicos do Smarty: arquivos de configuração e algo sobre cache. Aqui usarei a mesma classe e index utilizados no post passado.

Arquivos de Configuração

São arquivos úteis normalmente para que o designer possa setar variáveis globais para os templates, como por exemplo o título da página ou as cores de fundo. No post passado, registrei a pasta ‘configs’ para isso.

Para começar, um exemplo bem simples:

# arquivo my.conf
pageTitle = "Teste Smarty"

[Test]
pageTitle = "Artigo Smarty"

[Production]
pageTitle = "Tutorial Smarty"

Temos aí grande parte das regras dos arquivos configuração:

  1. na primeira linha temos um comentário, que deve sempre ser feito com o #;
  2. na linha seguinte, temos o nome da nossa variável(pageTitle) e um valor para ela, que poderia estar tanto sem quanto com aspas ou mesmo com apóstrofos. Se tivesse mais de uma linha, o valor deveria ter 3 aspas como delimitador;
  3. e as chamadas seções, que são strings entre colchetes []. No meu exemplo, temos 2 seções, e suas variáveis são carregadas apenas quando chamamos a seção em específico. Tudo o que vem antes das seções faz parte das variáveis globais, que são sempre chamadas quando o arquivo de configuração é setado no smarty. Quando uma variável global possui o mesmo nome de uma variável de seção, o valor usado pelo smarty é sempre o da seção.

Para ver o funcionamento do arquivo de configuração, precisamos chamá-la pelo smarty. Podemos fazer isso de 2 maneiras:
ou no próprio php:

// com base na classe criada no primeiro passo, usamos o $this
// mas se não for o $this, será a variável que representa o objeto do smarty
// na função, colocamos o nome do arquivo e, opcionalmente, a seção
$this->config_load('my.conf', 'Test');

ou direto no tpl:

{config_load file="my.conf" section="Test"}

Feito isso, podemos chamar a variável no tpl com 2 sintaxes diferentes:

{#pageTitle#}
ou
{$smarty.config.pageTitle}

Executando de qualquer uma dessas maneiras, teremos como resultado Artigo Smarty no tpl, pois o valor da variável da seção substituiu o da variável global.
Bem, sobre arquivos de configuração é isso: dei um exemplo de arquivo que é normalmente usado em back-end, de configurações para diferentes níveis de uso (Teste e Produção), mas para o smarty é mais usado para diferenciar páginas (index, cadastro, login, etc).

Caching

Outra importante funcionalidade do Smarty é o seu sistema de caching: em geral, o cache é um local de armazenamento temporário na qual dados que são frequentemente acessados possam ser armazenados para rápido acesso. Uma vez que esse dado esteja em cache, ele pode ser acessado diretamente ao invés de refazer todo o processo que gerou os mesmos dados anteriormente.

O Smarty faz exatamente isso: quando habilitamos o cache e ele executa o display(), é criado um arquivo em puro html e pronto para ser retornado. Dessa maneira, conteúdos que não mudam constantemente podem ser recuperados rapidamente. Porém, como estamos lidando com php, e consequentemente teremos conteúdos dinâmicos (principalmente quanto a banco de dados), precisamos controlar o cache para conseguir tornar o conteúdo dinâmico e de rápido acesso.

Caching Simples

Para habilitar o cache no Smarty, vamos alterar a nossa classe usada no post anterior:

// lembrando que o $this se refere ao objeto da classe Smarty
$this->caching = true;

Dessa maneira, o nosso cache estará habilitado e o arquivo será gerado novamente a cada hora na pasta ‘cache’, conforme definimos no post passado. Podemos alterar o tempo de geração com outra variável do Smarty:

$this->cache_lifetime = 10;

Setamos portanto, 10 segundos para que a página seja gerada novamente. Claro que esse tempo depende de que conteúdo estamos lidando e qual a necessidade de tê-lo sempre atualizado.
Vamos então a um exemplo prático… no nosso php, vamos setar um valor randômico entre 0 e 100, que a cada execução geraria um número diferente:

$smarty->assign('random', mt_rand(0, 100));

Chamando a variável {$random} no Smarty, podemos observar que o valor randômico permanece o mesmo durante 10 segundos e depois se altera novamente. Mas tem um detalhe: o cache está funcionando, mas de qualquer forma, dentro do php, o nosso conteúdo dinâmico ainda está sendo executando, tornando o cache do Smarty ainda não muito eficiente. Para isso, o Smarty nos proporciona a função is_cached(), que poderíamos chamar na nossa index:

if( !$smarty->is_cached('index.tpl') ) {
    $smarty->assign('random', mt_rand(0, 100));
}

Dessa forma, podemos verificar se o arquivo tpl já está em cache ou não… se não estiver, então mandamos executar o conteúdo dinâmico, mas se já estiver ele só lerá o arquivo gravado em cache e exibirá ao usuário.

Cachings múltiplos

Pode acontecer de precisarmos ter mais de um arquivo de cache para cada página: imagine que temos um site artigos, e que temos vários usuários que podem cadastrar artigos. Se tivermos uma página que retorna todos os artigos do usuário, precisaremos de um arquivo de cache para cada usuário, uma vez que a mesma página poderá ter vários conteúdos diferentes.

Para tornarmos isso útil, usaremos o segundo parâmetro do display():

// para não fugir do tema, vamos considerar que só usuários logados acessam a página
// e vamos considerar que $_SESSION['id_usuario'] sempre retornará um valor válido
$id_usuario = $_SESSION['id_usuario'];
// verificamos se já existe o arquivo em cache para esse usuário
if( !$smarty->is_cached('arquivo.tpl', $id_usuario) ) {
    // como não existe, vamos ao banco em busca dos artigos
    $contents = get_database_contents($id_usuario);
    $smarty->assign('contents', $contents);
}
$smarty->display('arquivo.tpl', $id_usuario);

O que acontece é que se não existir conteúdo em cache, o php vai pegar os dados do banco e quando chegar no display(), o arquivo cache será criado para o usuário testado. Se já existir o cache, então o display apenas retornará o arquivo em cache.

Observação: é preciso ter cuidado com múltiplos caches! Use-o apenas quando realmente precisa ter vários tipos de conteúdos em uma mesma página, como no exemplo. Colocar IDs em caches significa gerar mais arquivos, e se não for corretamente usado, pode ocupar um espaço desnecessariamente grande no servidor. No exemplo passado, se for um site grande, podemos ter milhares de arquivos, mas em compensação, evitaríamos acessos desnecessários ao banco que poderiam prejudicar a visita dos usuários. Já no caso de um site que não terá um fluxo de visitas suficientemente grande, aplicar essa técnica não traria uma vantagem significativa.

Desistindo do cache

Para finalizar, se por acaso quisermos parar de usar o cache, basta setar:

$this->caching = false;

podemos limpar todos os arquivos do cache com:

$smarty->clear_all_cache();

ou então, para limpar individualmente:

$smarty->clear_cache('arquivo.tpl');

Concluindo

Chegamos ao fim de mais um artigo: vimos ao longo dele 2 funcionalidades que tornam o Smarty um excelente sistema de templates, facilitando e melhorando o nosso site. Talvez depois eu faça uma terceira parte sobre a criação de plugins no Smarty.

Posted in php at novembro 14th, 2009. No Comments.

Já demonstrei em tópicos anteriores que o Zend_View é um ótimo componente para facilitar a nossa camada view de um projeto MVC. Porém, ela não é a única: de fato, esse tipo de sistema é o que não falta para PHP, e o Smarty é uma das que se destaca.

O Smarty é uma biblioteca de template que facilita a aplicação do modelo MVC, que permite a separação do HTML e do PHP, facilitando o trabalho dos designers, que não precisam conhecer a linguagem para poder alterar o visual do site. Outras vantagens do Smarty:

  • É rápido: evita o overhead que muitos sistemas de template têm, pois compila apenas uma vez
  • É facilmente configurável: com pouco código podemos especificar onde estão as pastas necessárias para o funcionamento, as tags delimitadores (por padrão são “{}”), etc.
  • É extensível: podemos facilmente criar plugins, e portanto, podemos adequá-lo ao nosso projeto

Primeiros Passos

  1. Baixe a última versão estável do Smarty e extraia para uma pasta separada.
  2. Crie uma pasta separada para o nosso projeto, e detro dela crie uma pasta chamada Smarty
  3. Da pasta extraída, copie o que está dentro da pasta lib/ para a pasta Smarty do nosso projeto
  4. Na pasta do projeto, crie as pastas ‘templates’, ‘templates_c’, ‘configs’ e ‘cache’
  5. Crie um arquivo index.php, ainda sem nada
  6. Crie um arquivo index.tpl, também sem nada

Deve ficar assim:
Exemplo de projeto implementado com Smarty
Apenas lembrando: eu estou usando essa estrutura apenas para facilitar as chamadas, tanto que não é recomendável deixar essas pastas na raíz. Eu poderia ter chamado o Smarty de fora do projeto, ter outros nomes de pastas auxiliares e deixá-los em outros lugares também, mas deixei assim mesmo porque a minha intenção era apenas simplificar a explicação.

Entendendo

Temos a pasta ‘Smarty’, que possui todos os arquivos da biblioteca, e temos outras 4 pastas que são usadas pelo Smarty com diferentes objetivos:

  • cache: pasta usada pelo Smarty para armazenar os arquivos usados quando a opção de cache está habilitada
  • configs: pasta que deve conter os arquivos de configuração ‘.conf’
  • templates: pasta em que devem estar os arquivos ‘.tpl’, onde ficam os códigos html e do próprio smarty
  • templates_c: pasta usada pelo Smarty para armazenar as páginas compiladas

Lembrando que eu uso esses nomes porque são ‘padrões’ de quem usa o Smarty, mas podemos muito bem alterar os nomes na hora de configurá-lo.

Mãos à obra

Vamos então fazer um pouco de código: primeiro temos que chamar o Smarty e configurá-lo, e farei isso em uma classe isolada, apenas para não precisar fazer isso em todas as páginas que usaremos o Smarty:

<?php

require('Smarty/Smarty.class.php');

class Meu_Smarty extends Smarty {

    public function Meu_Smarty()
    {

        $this->Smarty();

        $this->template_dir    = 'templates';
        $this->compile_dir     = 'templates_c';
        $this->cache_dir       = 'cache';
        $this->config_dir      = 'configs';

        $this->left_delimiter  = '{{';
        $this->right_delimiter = '}}';

    }

}

Agora, a página index.php, que fazemos a chamada à classe e configuramos uma variável que chamaremos no tpl:

<?php

require('smarty.php');
$smarty = new Meu_Smarty();
// aqui dizemos que quermos uma variável chamada 'name' com o valor 'World'
$smarty->assign('name', 'World');
// especificamos o nome do tpl que será usado
$smarty->display('index.tpl');

?>

E finalmente o arquivo .tpl:

<html>
<head>
<title>Tutorial Smarty - Index
</head>
<body>

Hello {{$name}}!

</body>
</html>

Nada de muito trabalhoso: no index.php ‘dizemos’ ao Smarty para reconhecer uma variável chamada $nome, e no tpl chamamos-a.

Dificultando o nosso exemplo

Vamos a um processo mais difícil, mas também mais comum: queremos pegar dados de um banco de dados. Eu não vou entrar no mérito de conectar ao banco e tudo mais, mas normalmente quando fazemos isso, recebemos um array e usamos ele para mostrar os dados… então farei apenas isso, sem mudar o foco para o banco.

No index.php, teremos:

$resultado_banco = array(
    array(
        'id' => 1,
        'name' => 'Diego'
    ),
    array(
        'id' => 2,
        'name' => 'Tiago'
    ),
    array(
        'id' => 3,
        'name' => 'Paulo'
    )
);

$smarty->assign('resultado', $resultado_banco);

e no index.tpl:

<table>
    <tr>
        <th>ID</th>
        <th>Nome</th>
    </tr>
    {{section name="i" loop=$resultado}}
    <tr>
        <td>{{$resultado[i].id}}</td>
        <td>{{$resultado[i].name}}</td>
    </tr>
    {{/section}}
</table>

A grande diferença foi que usamos um comando pronto do Smarty, o {section}. Ele faz a função do loop no template, de forma que houve a iteração na variável $resultado, que era o array de resultados.
Uma coisa que precisa ser observada é a regra dos arrays no tpl, que no nosso exemplo foi o “{{$resultado[i].name}}”. A primeira vez que vi isso me perguntei “por que não {{$resultado[i]['name']}}, ou {{$resultado.i.name}}??”, mas bastou notar que ele trata índices numéricos com os conchetes e índices não numéricos com o ponto: aquele ‘i’ não é uma variável de fato, apenas um identificador de qual índice do array está sendo iterado no momento, enquanto que o ‘nome’ é o nome do índice que queremos pegar.

Conclusão

Acaba por aqui a primeira parte sobre o Smarty. Mostrei o básico, para quem não conhece, de como usar um ótimo sistema de templates para facilitar o uso das suas views, de maneira a desenvolver sem ficar aquele amontoado de código php junto do html.
Futuramente devo falar sobre coisas mais específicas do Smarty, como o uso do cache, arquivos de configuração e como criar plugins, recurso importantíssimo para estender o smarty com funcionalidades mais específicas.

Até a próxima!

Posted in php at novembro 1st, 2009. 4 Comments.

Meio que uma continuação do post passado, vou abordar um pouco mais do Zend_View, o componente do Zend Framework responsável pela camada de Visão do modelo MVC implementado.

Obs.:  Este post está sendo feito com base na versão 1.9.4 do framework.

Um Simples Exemplo

Simples mesmo: passar uma informação do controller para a view.

No Controller, dentro da Action desejada:

// cria algumas variáveis
$valor1 = 123.45;
$valor2 = array(
    array('id' => '1', 'titulo' => 'Teste 1'),
    array('id' => '2', 'titulo' => 'Teste 2'),
    array('id' => '3', 'titulo' => 'Teste 3')
);
// inclui as variáveis na view
// podemos atribuir o valor como objeto
$this->view->valor1 = $valor1;
// ou usar o método assign... assign('nome dentro da view', $valor);
$this->view->assign('valor2', $valor2);

E na view:

<p><?php echo $this->valor1 ?></p>
<table>
    <tr>
        <th>Código</th>
        <th>Título</th>
    </tr>
    <?php foreach ($this->valor2 as $registro){ ?>
    <tr>
        <td> <?php echo $this->escape($registro['id']); ?>
        <td> <?php echo $this->escape($registro['titulo']); ?>
    </tr>
    <?php } ?>
</table>

Ou seja: no Controller indicamos quais variáveis queremos que a instância do Zend_View “enxergue”, de maneira que na view só precisamos dar um escape para mostar. Esse escape, por padrão, é o htmlspecialchars()  para evitar que os valores das variáveis causem alguma quebra no html.

View Helpers

Como foi visto no exemplo, as coisas são bem simples: setamos variáveis e usamos-as na view. Mas o problema é: e se quisermos fazer algo mais complexo, como por exemplo, alterar a cor das linhas da tabela do nosso primeiro exemplo?

Para evitar soluções como, por exemplo, criar um contador com um if para verificar se é par ou impar, temos os helpers, que são implementações em classes de funcionalidades complexas que não queremos colocar explicitamente na view.

Neste caso, já temos o Zend_View_Helper_Cycle, um helper já implementado. Assim, basta alterar uma única linha:

<tr style="background-color: <?php echo $this->cycle(array("#FF0000","#00FF00"))->next()?>">

Apenas com um comando dentro do <tr>, o nosso exemplo já nos mostra uma tabela que alterna o fundo em vermelho e verde.

Esse é apenas um dos já implementados: caso queira aprender quais são e como usá-los, recomendo dar uma olhada na referência oficial dos View Helpers. Não gostaria de colocar todos aqui porque qualquer explicação seria mera repetição, e minha intenção mesmo é mostrar a criação de um helper.

Então vamos lá: usando o primeiro exemplo, estamos mostrando um número, mas queremos mostrá-lo como um preço. Para isso, contaremos com o Zend_Currency, que é um componente próprio para tratar disso, mas como não queremos fazer isso no controller, vamos facilitar nossa vida e chamar esse helper.

Na instalação, o framework já nos deixou uma pasta própria para ele em application/views/helpers/ e é nele que deve ser criado o seguinte arquivo:

<?php

class Zend_View_Helper_Currency extends Zend_View_Helper_Abstract
{

    /*
     * por convenção do framework, o método deve ser o nome da
     * classe (Currency) em minúsculo
     */

    public function currency($valor)
    {

        // instanciamos a classe que trata, explicitando o locale
        $currency = new Zend_Currency('pt_BR');
        // devemos SEMPRE retornar valores, nunca mostrar na saída
        return $currency->toCurrency($valor);

    }

}

Eu não vou mudar muito o foco para o Zend_Currency, mas só para não deixar dúvidas, o método retorna o valor formatado em reais, com o formato português do Brasil.

Feito isso, mudamos na view apenas a linha que chamamos o $valor1:

<p><?php echo $this->currency($this->valor1); ?></p>

Deve ser mostrado na tela algo como ‘R$123,45′.

Obs.: Muitas pessoas (inclusive eu) acham prático criar uma pasta dentro do library com todas as classes próprias que não façam parte do Controller e do Model. Caso queira deixar seus helpers dentro de uma pasta dessas, crie um método no Bootstrap instanciando o Zend_View e use o método addHelperPath para que o framework encontre-os:

protected function _initView()
    {
        $view = new Zend_View();
        $view->addHelperPath('path/to/my/view/helper', 'My_View_Helper');

        $viewRenderer = new Zend_Controller_Action_Helper_ViewRenderer();
        $viewRenderer->setView($view);
        Zend_Controller_Action_HelperBroker::addHelper($viewRenderer);

        return $view;
    }

Conclusão

Vimos que o  Zend_View é um poderoso componente de templates que permite de maneira muito simples a incorporação de funções complexas novas. Apesar de ter sido uma visão superficial, baseada nos view helpers, já é possível criar uma camada de visão de maneira limpa e eficiente.

Mesmo assim, os próximos posts devem complementar algumas das informações passadas aqui, então fiquem atentos!

Posted in php at outubro 25th, 2009. 1 Comment.

Apesar do que eu tinha dito no post anterior, voltarei na idéia de instalação do Zend, já que nas últimas versões o Zend_Tool tem se mostrado uma ótima opção por ser rápido e prático para iniciar projetos, de forma muito mais eficiente que no tutorial passado.

Obs 1.: Desta vez eu fui mais específico quanto a instalação, mas não muito didático quanto a Controllers, Actions, View e o outras idéias do framework. Caso você não conheça muito sobre o framework, recomendo a leitura do meu post Começando com o Zend Framework 1.8 antes de continuar com esse.
Obs 2.: Faço este tutorial supondo que a versão usada no php é igual ou superior ao 5.2.4 e que o módulo mod_rewrite do Apache está habilitado.

Instalação em Windows:

Faça o download da última versão do Zend Framework, e extraia em uma pasta de fácil acesso. No caso do tutorial, eu estou usando a pasta C:\www\ZendFramework-1.9.4-minimal (foi usada a versão 1.9.4, a última versão lançada no momento de criação do tutorial).

Feito isso, precisamos certificar que o caminho para o arquivo .bat usado pelo Zend_Tool está no Path: para isso, vá em Painel de Controle > Sistema > Avançado > Variáveis de ambiente. Em “Variáveis do sistema”, edite o registro “Path”, colocando ao final ;C:\www\ZendFramework-1.9.4-minimal\bin.

Agora no prompt de comando (Iniciar > Executar > cmd), vamos testar se ele está encontrando o Path… digite:

zf show version

Se tudo der certo, ele deve mostrar a versão que será instalada. Se deu erro, certifique-se que o caminho que está no Path é correto.

Agora vá com o prompt até a pasta em que você deseja que seja criada a pasta do novo projeto. No caso, criei ele em C:\www\

cd C:\www\

Agora o comando para criar o projeto… eu o chamei de projeto_zf1.9.4:

zf create project projeto_zf1.9.4

Se tudo ocorreu corretamente, uma pasta com o mesmo nome do projeto foi criada e os arquivos básicos foram criados na estrutura padrão, conforme a imagem:

Estrutura Padrão - Zend Framework

Agora só falta ligar a biblioteca do zend ao projeto. Podemos fazer isso de 2 maneiras: chamando a biblioteca externamente, adicionando-a ao path de execução do php (uma das maneiras de fazer isso é adicionando o caminho da biblioteca dentro do set_include_path() do index.php); ou copiando a pasta da biblioteca (que está em C:\www\ZendFramework-1.9.4-minimal\library) para a pasta library do projeto.

Pronto! Para vê-lo rodando, acesse a pasta /public. Pelo meu exemplo, basta acessar: http://localhost/projeto_zf1.9.4/public

Configurações básicas do Framework

Agora que temos a base já instalada e funcionando, as configurações são dependentes apenas das necessidades do projeto. Vou apresentar algumas dicas e opções que o framework nos proporciona, mas sem me aprofundar muito. Quem sabe depois eu faço alguns posts especificando alguns deles.

  1. Criando Controllers e Actions: Ao contrário do que acontecia antes, não é preciso mais criar controllers e actions manualmente. Isso é realmente uma maravilha, quem leu o post sobre o Zend 1.8, viu que era muito Ctrl+C Ctrl+V, pra criar a classe do Controller, criar o método do Action, depois encontrar a pasta das views e criar o .phtml… enfim, agora tudo isso se resolve com o Zend_Tool, em apenas 2 comandos no prompt (Não se esqueça de ir para a pasta do projeto antes de executar):
    zf create controller nomecontroller

    e

    zf create action nomeaction nomecontroller
  2. Zend_Application: é o pontapé inicial da aplicação. Ele é chamado no index.php com o objetivo de inicializar a aplicação e chamar o Bootstrap. O componente nos permite criar recursos e executar alguns já disponíveis, como é o caso dos controllers, conexão ao banco, etc. Quem precisar criar ou usar recursos que sejam necessários durante a execução de todo o site, precisa saber mais sobre ele.
  3. Zend_Layout: Recurso muito usado com o Zend_View, que possibilita o uso de um layout padrão para todas as páginas. Para usá-lo, basta colocar as seguintes linhas no arquivo de configuração:
    ; nome do arquivo de layout padrão
    resources.layout.layout = "layout"
    ; caminho para uso dos layouts
    resources.layout.layoutPath = APPLICATION_PATH "/layouts/scripts"
    ; seta o encoding do view
    resources.view.encoding = "UTF-8"
    ; seta o caminho das views
    resources.view.basePath = APPLICATION_PATH "/views"

    Um exemplo de Layout (lembrando que deve ser um arquivo .phtml):

    <?php echo $this->doctype('XHTML1_STRICT'); ?>
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <?php echo $this->headTitle('Layout Title') ?>
        <?php echo $this->headLink() ?>
        <?php echo $this->headStyle() ?>
        <?php echo $this->headScript() ?>
    </head>
    <body>
        <?php echo $this->layout()->content ?>
    </body>
    </html>
  4. Conexão com o Banco de Dados:  Outro recurso já implementado pelo Zend_Application. Para usá-lo, basta escrever no arquivo de configurações os parâmetros que o Zend_Db precisa para conectar ao banco de dados. Uma configuração para MySQL:
    resources.db.adapter = "pdo_mysql"
    resources.db.params.host = "localhost"
    resources.db.params.username = "usuario"
    resources.db.params.password = "senha"
    resources.db.params.dbname = "nomedobanco"

Conclusão

Certamente faltam detalhes para rodar uma aplicação mesmo que básica a partir dessas informações, mas espero que seja uma boa contribuição para aqueles que procuram uma maneira rápida de ter seu framework pronto para ser usado.

Nos próximos posts devo entrar em usos mais específicos de Zend_Db e Zend_View para podermos enfim criar aplicações mais “ricas”.

Posted in php at outubro 12th, 2009. 9 Comments.

Há muito ouço da necessidade do uso de frameworks para o desenvolvimento, e isso não ocorre a toa: eles facilitam muito essa tarefa por já possuírem a “base” que todos precisamos.

Temos vários exemplos de frameworks para PHP, como CakePHP, Symfony, CodeIgniter e Prado, mas vamos falar dessa vez do Zend, o framework da empresa responsável pelo PHP. Não que isso a torne melhor que as demais, mas tratarei dele porque vejo nele a solução para muitos problemas de maneira flexível e simples. Nesse post, falarei do básico para começar a usá-lo.

Antes de começar

Como a minha intenção nesse artigo não é explicar o MVC, padrão de arquitetura usado não só no Zend, como em outros frameworks, indico 2 links em que o assunto é melhor abordado: Wikipedia e O que é MVC um bicho de 10 cabeças ou produtividade???

É necessário habilitar no Apache o uso de .htacces e o mod_rewrite.

Para isso, abra o httpd.conf e procure a linha:

LoadModule rewrite_module modules/mod_rewrite.so

Se estiver com o famoso ‘jogo da velha’ (#) antes desse código, retire-o.

Agora procure a linha:

<directory "xxx">

onde xxx é a pasta que o Apache enxerga as suas páginas web (por padrão, é a htdocs). Certifique-se de que nas linhas abaixo contenha:

Options Indexes FollowSymLinks
AllowOverride All

Primeiros Passos

Considerando que está tudo configurado no ambiente, baixe o Framework aqui e extraia-o. Agora vamos definir a estrutura de diretórios a ser usada:

Obs.: essa é uma forma quase padrão de diretórios para o Zend. Entretanto, podemos fazer a estrutura da maneira que preferirmos, pois isso é configurado no Bootstrap, que veremos mais a frente.

meuprojeto/
    /application
        /config
        /controllers
        /models
        /views
            /helpers
            /scripts
                /index
    /library
        /Zend
    /public
        /css
        /img
        /js

Nos arquivos que você extraiu, procure pela pasta library/Zend e copie seu conteúdo para a pasta Zend indicada na estrutura.

Bootstrap!

O Bootstap nada mais é que o ponto de partida do nosso projeto, a index.php: todas as urls desse site agora passarão primeiro pelo Bootstrap, que por sua vez chamará o Controller, que chamará a View e os Models, se necessários forem.

O index.php seria:

<?php
// configura as mensagens de erro
error_reporting(E_ALL|E_STRICT);
// chamamos todos os diretórios com classe que possamos usar
// isso é muito vantajoso já que poderemos carregar tudo como se estivesse na mesma pasta
set_include_path('.' . PATH_SEPARATOR . './library'
                     . PATH_SEPARATOR . './application/models'
                     . PATH_SEPARATOR . get_include_path());
// chama a classe do Zend, responsável por carregar as demais
include "Zend/Loader.php";
// carrega as classes necessárias
Zend_Loader::loadClass('Zend_Controller_Front'); // classe de Controllers
Zend_Loader::loadClass('Zend_Registry'); // classe que registra objetos
Zend_Loader::loadClass('Zend_View'); // classe da View

// instancia a View
$view = new Zend_View();
// coloca o caminho onde estarão as views
$view->addScriptPath('./application/views/scripts/');
// registra o objeto view
Zend_Registry::set('view', $view);

// instancia o Controller
$controller = Zend_Controller_Front::getInstance();
// seta o diretório onde estão os Controllers
$controller->setControllerDirectory('./application/controllers');
// roda o Controller e Action desejados
$controller->dispatch();

É um exemplo talvez dos mais simples de como fazer um bootstrap. O Zend nos proporciona muito mais possibilidades, mas ainda não vou me estender a elas, ficarei no básico das views e controllers.

Assim que é chamado o dispatch(), o bootstrap nos envia para o Controller que requisitamos quando acessamos o site. Mas talvez a grande dúvida seja: como sabemos onde a requisição do dispatch vai parar? A resposta é: a URL.

No Zend Framework, o controller a ser chamado depende da URL chamada. Mas para isso funcionar, precisaremos de um arquivo .htaccess, como o abaixo:

RewriteEngine on
RewriteRule !\.(js|ico|gif|jpg|png|css|htm|html)$ index.php
php_flag magic_quotes_gpc off
php_flag register_globals off

Os dois exemplos abaixo, nos levam para o Controller index (classe IndexController)
http://localhost/meuprojeto/
http://localhost/meuprojeto/index/

Enquanto que o exemplo abaixo nos levará para um Controller de usuários (classe UsersController)
http://localhost/meuprojeto/users/

Mas isso ainda não nos mostra nada na tela além de erros: precisamos criar o controller e a view da index.

O Controller

No Zend, Controllers são classes simples, que devem seguir algumas regras:

  • O nome da classe deve ter o sufixo Controller
  • Deve estender a classe Zend_Controller_Action
  • As actions (métodos do controller, que serão as páginas de fato) devem ter o sufixo Action

O nosso Controller Index ficaria:

<?php

class IndexController extends Zend_Controller_Action
{

    public function indexAction()
    {
    	// pega a variável view registrada no bootstrap
        $view = Zend_Registry::get('view');
        // cria atributos, que serão visíveis na view
        $view->title = 'Página Inicial';
        $view->body = 'Hello World';
        // chama a view criada
        echo $view->render('index/index.phtml');

    }

}

Assim, criamos um controller simples, que basicamente chama uma view. Note que actions são as páginas propriamente ditas: então se você quiser criar uma página de contato por exemplo, basta criar uma action para ela. A diferença na hora de passar isso pela URL é bem simples:

http://localhost/meuprojeto/index/ vai para a action padrão do controller (que é setada por padrão como index, mas que pode ser alterada graças ao método setDefaultAction() da classe Zend_Controller_Front)

http://localhost/meuprojeto/index/index/ especifica que deve ir ao Controller Index e Action index

http://localhost/meuprojeto/users/subscribe/ especifica que deve ir ao Controller Users e Action subscribe

A partir daí, já fica também a idéia de como passar parâmetros para a Action…

View

Estamos quase lá: já temos uma página inicial, mas não temos nada para mostrar ao usuário além de erros até o momento. No Zend, o padrão para a View é o phtml, uma extensão normalmente usada para indicar que estamos usando php e html juntos.

A view para a nossa página inicial (index.phtml) ficaria:

<html>
<head>
<title><?php echo $this->escape($this->title); ?>
</head>
<body>

escape($this->body); ?>
</body>
</html>

Lembrando que as views ficam dentro do applications/views/scripts, e essa em específico dentro de uma pasta chamada index, o que não é obrigatório, mas por organização gosto de criar páginas com os mesmos nomes dos controllers.

Rodando

Feitos todos os passos anteriores, basta chamar por http://localhost/meuprojeto/ que deve aparecer uma página de Hello World.

Com certeza o Zend tem muito mais a nos oferecer que isso, mas aqui tivemos um começo para o nosso site e espero ter colocado de maneira sucinta e informativa a base do framework. Apesar da Zend atualmente guiar seus usuários para o uso da classe Zend_Application_Bootstrap_Bootstrapper, ainda acho que o bootstrap da maneira abordada é mais fácil de entender para quem está conhecendo.

Nos próximos posts devo abordar sobre recursos mais específicos, como o Zend_DB para a conexão com Banco de Dados ou o uso do Smarty no lugar do Zend_View (é certo que a Zend está mandando muito bem nessas últimas versões com bibliotecas específicas para o Zend_View, mas gosto muito do Smarty e em algumas pesquisas vejo que não sou o único).

Posted in php at julho 15th, 2009. 5 Comments.