Nota do editor: Esta série foi originalmente publicada em 2006 e atualizada em 2007 e 2008. Desde sua última publicação, os desenvolvedores do CakePHP fizeram alterações no CakePHP, que resultaram nas diversas revisões desta série. Esta revisão foi escrita para o CakePHP V1.2.2.8120.
Esta série "Elabore Web sites rapidamente com o CakePHP" foi elaborada para desenvolvedores de aplicativos PHP que desejam começar a usar o CakePHP para facilitar suas vidas. No final, será possível aprender como instalar e configurar o CakePHP, o básico do design Model-View-Controller (MVC), como validar dados de usuários e usar os helpers no CakePHP, e como colocar um aplicativo em execução rapidamente usando o CakePHP. Pode parecer que há muito para aprender, mas não se preocupe — o CakePHP faz a maior parte do trabalho por você.
Este artigo considera que você já tenha concluído a Parte 1, Parte 2, Parte 3 e Parte 4, e que você ainda tenha o ambiente de trabalho configurado para estas partes. Se não tiver instalado o CakePHP, será necessário ler as Partes 1 e 2 antes de continuar.
Consideramos que você conheça o PHP, tenha um entendimento básico de design de bases de dados e que fique à vontade durante o trabalho.
Antes de começar, você precisa ter um ambiente em que possa trabalhar. O CakePHP tem requisitos de servidor razoavelmente mínimos:
- Um servidor HTTP que suporte as sessões (e, de preferência,
mod_rewrite). Este tutorial foi escrito usando o Apache V2.2.4 com omod_rewritehabilitado. - PHP V4.3.2 ou mais recente (incluindo PHP V5). Este tutorial foi escrito usando o PHP V2.3.
- Um mecanismo de banco de dados suportado. Este tutorial foi escrito usando o MySQL V5.0.4.
Também será necessário um banco de dados pronto para que seu aplicativo possa usá-lo. O tutorial fornecerá a sintaxe para criar todas as tabelas necessárias no MySQL.
O modo mais simples de fazer o download do CakePHP é visitar CakeForge.org e executar o download da última versão estável. Este tutorial foi escrito usando a versão 1.2.812.0. (Também estão disponíveis construções e cópias noturnas direto do Subversion. Os detalhes encontram-se no Manual do CakePHP (consulte Recursos).
Na Parte 4, você teve a oportunidade de simplificar o Tor. Como você se saiu?
Adicionando as ações e visualizações favoritas
Para exibir a lista de favoritos, é necessário adicionar uma ação de favoritos ao controlador de usuários. Isso pode parecer um
pouco com a Lista 1.
Lista 1. Adicionando uma ação de favoritos ao controlador de usuários
function favorites () { $username =
$this->Session->read('user'); $favorites = array(); if ($username) {
$this->User->recursive = 2; $results =
$this->User->findByUsername($username); foreach($results['Product'] as
$product) { $favorites[] = array('Product' => $product, 'Dealer' =>
$product['Dealer']); } $this->set('products', $favorites); } else {
$this->redirect(array('controller' => 'users', 'action' =>
'login')); } } |
Observe o redirecionamento se o usuário não tiver efetuado login. Isso impede que o usuário veja um erro ao visualizar a página sem efetuar login.
Também seria necessário o favorites.ctp no diretório app/views/users. Ele pode ser um pouco parecido com o que é mostrado abaixo.
Lista 2. Favorites.ctp.
<div
class='favorites'> <h2>Favorites</h2>
<table cellpadding="0" cellspacing="0"> <tr>
<th>Id</th> <th>Title</th>
<th>Dealer</th>
<th>Description</th> <th
class="actions">Actions</th> </tr> <?php
$i = 0; foreach ($products as $product): $class = null;
if
($i++ % 2 == 0) { $class
= ' class="altrow"'; } ?> <tr<?php echo
$class;?>> <td> <?php echo
$product['Product']['id'] ?> </td> <td>
<?php echo $product['Product']['title'] ?> </td>
<td> <?php echo $html->link($product['Dealer']
['title'], array('controller'=> 'dealers', 'action'=>'view', $product
['Dealer']['id'])); ?> </td> <td> <?php
echo $product['Product']['description'] ?> </td> <td
class="actions"> <?php echo $html->link('View', array
('controller' => 'products', 'action'=>'view', $product['Product']
['id'])); ?> </td> </tr> <?php endforeach;
?> </table> </div> |
Tudo o que a visualização realmente precisa fazer é mostrar a tabela de produtos. Porém, agora não há como remover um produto de sua lista de favoritos.
Inserindo o link Excluir de Favoritos
Sua outra tarefa foi inserir um link Excluir de Favoritos na tabela de produtos, configurando-o de modo que os usuários visualizassem o link Excluir, se um produto estivesse em sua lista de favoritos, e um link Adicionar, se o produto não estivesse nela. Olhando novamente para a visualização de produtos, a seção abaixo é a mais importante.
Lista 3. Tabela de produtos
<?php
if
( isset($ajax) )
{ echo $ajax->link('Add to Favorites', array('action'
=> 'addToFavorites/' . $product['Product']['id']), array('update' =>
'favMessage')); }
else
{ echo $html->link('Add to Favorites', array('action'
=> 'addToFavorites/' . $product['Product']['id'])); } ?> |
O link Excluir de Favoritos será muito parecido com o mostrado abaixo.
Lista 4. Link Excluir de Favoritos
echo $ajax->link('Remove From Favorites', array('action' =>
'removeFromFavorites/' . $product['Product']['id']), array('update' =>
'favMessage')); |
Será necessário adicionar também os helpers do JavaScript e do Ajax ao controlador de
usuários, e adicionar a ação removeFromFavorites ao
controlador de produtos.
Lista 5. A ação
removeFromFavorites
function removeFromFavorites($id) { $username =
$this->Session->read('user'); $success = false; $user =
$this->Product->User->findByUsername ($username, 'User.id');
$this->Product->User->id = $user['User']['id']; $success =
$this->Product->User->removeFavorite($id); if (
$this->RequestHandler->isAjax() ) { echo 'Removed product from
favorites'; exit; } else { if ( $success ) {
$this->Session->setFlash('Removed product from favorites');
$this->redirect('/users/favorites'); } else {
$this->Session->setFlash('Access denied');
$this->redirect('/products/index'); } } } |
Do mesmo modo, você precisa adicionar o método removeFavorite ao modelo de usuários.
Lista 6. Criando o método
removeFavorite
function removeFavorite($product_id) {
if($this->exists()) { $user = $this->read(); $fav = array();
foreach($user['Product'] as $product)
{ if ($product_id != $product['id']) { $fav[]
= $product['id']; } } $user['Product'] = array('Product'=> $fav);
if($this->save($user)) { return true; } else { return false; } } return
false; } |
Como você pode ter notado ao testar isso, quando você visualiza um produto, Adicionar a Favoritos é sempre exibido. Em vez disso, o usuário deve visualizar o link Excluir de Favoritos para produtos já adicionados à lista de favoritos. Como você faria isso?
Há grandes chances de que sua solução seja muito diferente. Não há problema algum. Agora vamos para o último tópico desta série: Armazenamento em Cache.
Conceitualmente, o armazenamento em cache pode ser confuso algumas vezes. Há muitos tipos de armazenamento em cache e cada um apresenta seu próprio conjunto de desafios e benefícios. É importante entender o significado do armazenamento em cache neste contexto.
O que significa armazenamento em cache?
Geralmente, o armazenamento em cache ocorre sempre que é feito um pedido, e o aplicativo que responde diz: "eu não preciso buscar isso. Já tenho um." Na maioria das vezes, quando um usuário de computador ouve a palavra "cache", ele pensa em um cache de navegador. Tipicamente, para acelerar a experiência do usuário, seu navegador manterá cópias do que ele acredita serem arquivos estáticos — geralmente imagens, folhas de estilo, HTML estático e arquivos de script. Embora este tipo de execução de cache às vezes possa causar problemas para os desenvolvedores de aplicativos da Web, ele não constitui nosso foco aqui.
Outro exemplo de armazenamento em cache seria quando o navegador faz um pedido de algum conteúdo a seu aplicativo da Web. Se seu aplicativo da Web usa armazenamento em cache, ele pode responder o pedido com uma cópia anteriormente gerada do conteúdo,eliminando o recurso de código extra envolvido na geração do conteúdo uma segunda vez. Este é o tipo de armazenamento em cache que constitui o foco deste artigo.
Geralmente, você usaria armazenamento em cache em seu aplicativo por dois motivos. Primeiro, porque ele ajuda a reduzir o consumo de recursos em seu servidor. Embora as economias possam ser pequenas na maioria dos casos, nos sites de alto tráfego que atendem pedidos em volume significativo, estas pequenas economias somam-se rapidamente em benefícios significativos de desempenho. O segundo motivo típico é a velocidade. Em razão de seu aplicativo não ter que passar pelo processo de gerar novamente o conteúdo para o pedido, o conteúdo pode ser servido com muito mais rapidez. Novamente, embora as economias possam ser pequenas na maioria dos casos, os sites de alto tráfego podem obter rapidamente benefícios de velocidade usando a execução de cache.
OK — você comprou a ideia. Você está pronto para fazer cache de toda e qualquer coisa. Como você faz isso? O que o CakePHP lhe proporciona para facilitar isso?
Para começar, você precisa ligar o cache. Por padrão, ele está desabilitado. Você
pode habilitá-lo em app/config/core.php. Procure a entrada a seguir: //Configure::write('Cache.check', true); e exclua as barras
de comentário da linha.
Estabelecendo Cache.check como verdadeiro, você estará
dizendo ao CakePHP que o armazenamento em cache está ativado agora. Vá em frente e
faça isso agora para poder iniciar o armazenamento em cache mais tarde. Ainda não
acabou: Você precisar dizer exatamente ao CakePHP o que deseja que fique em cache e
por quanto tempo.
Tendo ativado o armazenamento em cache, você precisa especificar o que deseja que
fique em cache. Isso começa no controlador para as visualizações que você deseja que
fiquem em cache, adicionando cache ao array dos helpers.
Por exemplo, para fazer cache nas visualizações dos produtos, você teria que incluir
Cache no array de helpers do controlador de produtos.
Quando construiu o controlador de produtos do Tor, você especificou que os helpers do HTML e formulários estavam em uso. Adicionando
Cache a esta lista, o array dos helpers ficaria assim:
var $helpers = array('Html', 'Form', 'Javascript', 'Ajax',
'Cache' );.
Agora que o helper do cache está em uso, você precisa especificar exatamente o que
deseja colocar em cache. Há muitas maneiras de fazer isso, mas todas elas se apóiam
no array $cacheAction.
Fazer cache de um pedido específico
Suponha que você quisesse fazer cache de um pedido específico. Por exemplo, haveria
três ou quatro produtos que têm alto tráfego na ação visualizar, e você deseja fazer
cache somente das visualizações Visualizar destes produtos. Nesse caso, você
especificaria os pedidos do que deseja fazer cache, como chaves de array para $cacheAction, e especificaria o tempo como valor da chave.
O array $cacheAction é uma variável de classe, como o
array $helpers. Para fazer cache destas visualizações
específicas, o $cacheAction poderia se parecer com a
Lista 7
Lista 7.
$cacheAction
<?php class ProductsController extends
AppController
{ ... var $cacheAction = array ( 'view/1/' => 3600, 'view/2/'
=> 3600, 'view/3/' => 3600 ); |
Este $cacheAction está dizendo ao CakePHP para fazer cache
das visualizações de Visualizar para os produtos 1-3 por 3.600 segundos (uma hora).
O tempo que você especifica pode estar em qualquer formato que o strtotime() possa interpretar. Você poderia dizer simplesmente 1 hora.
Fazer cache de uma ação inteira
Talvez não seja suficiente apenas fazer cache de alguns produtos. Talvez você queira fazer cache de todas as visualizações de uma ação específica. Suponha que você queira usar o armazenamento em cache nas visualizações da ação editar. Para isso, você especificaria a ação como uma chave de array e o tempo para manter as visualizações em cache, bem semelhante ao que fez acima.
var $cacheAction = array ( 'edit/' => '+1 hour' ); |
Você pode até misturar e combinar as duas.
Lista 8. Misturar e combinar
var
$cacheAction = array ( 'view/1/' => 3600, 'view/2/' => 3600, 'view/3/'
=> 3600, 'edit/' => '+1 hour' ); |
Isso ajuda a economizar um pouco de tempo. Agora você fez cache das visualizações de Visualizar dos produtos mais comumente visualizados e de todas as visualizações de editar. Mas talvez você deseje fazer mais.
Faça cache de tudo o que o controlador faz
Talvez você deseje fazer cache de tudo que o controlador faz. Se quiser, não é
necessário especificar cada ação no array $cacheAction.
Você pode simplesmente definir o valor de $cacheAction
para um tempo que mantenha tudo em cache: var $cacheAction = "+1
hour";.
O valor precisa ser uma cadeia de caractere que o strtotime() consiga interpretar. Definindo $cacheAction como um valor exclusivo, o CakePHP sabe como executar cache
de todas as visualizações do controlador.
Fazer cache de dentro de uma ação
Em razão de $cacheAction ser uma variável de classe, você
também pode acessar a variável de dentro de uma ação. Supondo que quisesse modificar
$cacheAction de dentro de uma ação, você usaria a
mesma sintaxe que usaria para modificar qualquer variável de classe.
function foo() { $this->cacheAction = array()... } |
Isso geralmente não seria necessário, mas você encontraria uma ocasião na qual isso é exatamente o que você precisa. Se for esse o caso, agora você sabe que pode. O CakePHP proporciona a você diversas maneiras de fazer cache de suas visualizações. Esta é a parte fácil. Aprender quando fazer cache — ou, mais especificamente, quando não fazer cache—, pode ser um pouco complicado.
O armazenamento em cache pode arrebatar você como a melhor coisa inventada desde o pão fatiado. Além disso, na maioria das vezes, a execução de cache é exatamente o que você deseja que ela seja. Então, quando você não deve fazer cache de suas visualizações?
Na maior parte do tempo, você não desejaria fazer um cache completo de dados que são atualizados constantemente. Por exemplo, suponha que os usuários do Tor estivessem adicionando produtos diversas vezes por minuto. Nesse caso, o armazenamento em cache da visualização do índice seria comprovadamente mais um problema do que uma ajuda. Se o conteúdo está sendo atualizado com tanta frequência que a página em cache nunca é realmente servida, tudo o que você fez foi adicionar o código extra para salvar a página em cache e checá-la para ver se foi atualizada para cada pedido.
Porém, isso não quer dizer que o armazenamento em cache seja inútil. Você só precisa ser mais específico quando disser ao CakePHP do que deseja fazer cache.
Visualizar a marcação <cake:nocache><cake:nocache>
Dentro de uma visualização ou layout, o CakePHP permite que você exclua
especificamente alguns conteúdos da execução de cache agrupando o conteúdo nas tags
<cake:nocache><cake:nocache>. O uso
apropriado desta marcação permitirá que o CakePHP faça cache das partes estáticas da
visualização ou layout enquanto assegura que as partes dinâmicas da página sejam
recuperadas em cada pedido.
Nem tudo pode ser agrupado nas tags <cake:nocache><cake:nocache>.
Especificamente, você não pode agrupar variáveis nas tags <cake:nocache><cake:nocache para torná-las
dinâmicas. Em termos gerais, as coisas que podem ser agrupadas nas tags cake:nocache><cake:nocache> são
construtos do CakePHP, como helpers e chamadas de elementos.
Por exemplo, no Tor, o layout padrão criado na Parte 4 continha uma saudação por nome de usuário.
Lista 9, Layout padrão
<!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"> <head> ... <div
id="header"> <h1><?php echo $html->link('Tor',
'/') ?> : Welcome <?php echo $session->read('user')
?></h1> ... |
Se o armazenamento em cache estiver desabilitado, na primeira vez que qualquer página
que utilizar o padrão for carregada, a saudação Bem-Vindo <?php echo$session->('user') ?> seria substituída
por algo como Bem-Vindo ou Bem-Vindo zaphod -- o que significa que, independente do
usuário tivesse efetuado login, ele sempre veria um nome de usuário em cache.
Para especificar que o nome do usuário não deve ficar em cache, você agruparia a
linha <?php echo $session->read('user')
?> nas tags <cake:nocache></cake:nocache>. O resultado
final ficaria assim:
Lista 10. Especificando que o nome do usuário não deve ficar em cache
<!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"> <head> ... <div
id="header"> <h1><?php echo $html->link('Tor',
'/') ?> : Welcome <cake:nocache><?php echo
$session->read('user')
?></cake:nocache></h1> ... |
Você pode testar isso especificando que o controlador de produtos use a execução de
cache para a ação visualizar. Adicione o cache à lista de
helpers e especifique uma visualização em $cacheAction.
Lista 11. Especificando que o controlador de produtos use o armazenamento em cache para a ação
visualizar.
<?php class ProductsController extends
AppController
{ var $name = 'Products'; var $helpers =
array('Html', 'Form',
'Javascript', 'Ajax', 'Cache' );
var $components =
array
('Acl','Security','RequestHandler');
var $cacheAction = array( 'view/'
=> '+1 hour' ); ... |
Agora, visualize um produto. Você deverá visualizar um arquivo criado em app/tmp/cache/views que corresponda ao produto que você visualizou. Faça login como um usuário diferente e visualize o mesmo produto. Você descobrirá que seu nome do usuário não está em cache. Edite o produto. Você descobrirá que o CakePHP sabe que você excluiu a exibição em cache. Não é eficiente?
Usar as tags <cake:nocache></cake:nocache>pode ajudá-lo a
encontrar o equilíbrio delicado entre fazer cache de suas visualizações e manter seu
conteúdo atualizado. Às vezes isso não é o bastante. Algumas vezes você mesmo
precisa limpar o cache.
Mesmo se você for esperto quanto ao que fica em cache e o que não fica, às vezes é necessário limpar o cache manualmente. Você pode estar pensando que isso será obviamente necessário quando os dados foram atualizados. Por exemplo, se um produto for editado, o visualizar ou editar visualizações daquele produto, bem como o índice de produtos, teriam que ser todos limpos do cache. E você tem razão. Eles precisam ser limpos.
Mas você não precisa fazer isso. O CakePHP faz isso por você. O CakePHP sabe quando os dados são inseridos, atualizados ou excluídos, e se isso afetar uma visualização em cache, o cache desta visualização será limpo. Isso economiza uma quantidade monstruosa de trabalho.
Mas pode ser necessário limpar o cache explicitamente. Por exemplo, se um processo
externo, como um script de batch planejado, estiver atualizando os dados diretamente
no banco de dados em vez de usar o aplicativo diretamente, o cache precisaria ser
limpo manualmente. Isso pode ser feito com o uso da função global clearCache.
Você normalmente nunca precisaria limpar o cache, pois o CakePHP limpa os arquivos relacionados ao cache quando há um INSERT, UPDATE ou DELETE para os dados destes arquivos.
Se você quiser limpar todo o cache, pode chamar a função Cache::clear()em uma ação de limpeza de cache específica, ou então pode
criar um controlador explicitamente para este propósito. Isso seria especialmente
prático se você precisasse automatizar o processo.
Parabéns! Você concluiu a série 'Elabore Websites rapidamente com o CakePHP" Você provavelmente está preparado para criar seu novo aplicativo.
Mas, antes de fazer isso, configure DEBUG como 2 em
appconfigcore.php. Isso dirá ao CakePHP para exibir algumas informações de depuração
do SQL na parte inferior de suas visualizações. Você pode encontrar as páginas em
cache em app/tmp/cache/views. Abra uma delas e dê uma olhada em como será a
aparência de uma página em cache. Exclua os arquivos em cache e visualize um
produto. Faça uma anotação de quantas queries foram executadas e quanto tempo elas
levaram. Agora, recarregue A visualização está em cache. Quantas queries foram
executadas desta vez? Quanto tempo isso levou? Familiarize-se com a execução de
cache. Procure maneiras de usá-lo no Tor. Quando acabar, jogue tudo fora e mergulhe
em seu próprio aplicativo.
Você aprendeu muito com esta série, mas nada colocará este aprendizado em perspectiva como escrever seu próprio aplicativo do zero no CakePHP.
| Descrição | Nome | Tamanho | Método de download |
|---|---|---|---|
| Part 5 source code | os-php-cake5.source.zip | 14KB | HTTP |
Informações sobre métodos de download
Aprender
- Consulte CakePHP para aprender mais.
- O CakePHP API
foi detalhadamente documentado. Este é o local para obter a documentação mais
atualizada.
- Há uma tonelada de informações disponíveis na The Bakery, a comunidade de usuários do
CakePHP.
-
CakePHP Data Validation
utiliza expressões regulares PHP compatíveis com Perl.
- Leia o tutorial intitulado "Como usar as expressões regulares em
PHP."
- Quer aprender mais sobre padrões de design?
Verifique Design Patterns:
Elements of Reusable Object-Oriented Software , também conhecido
como o livro da "Gang Of Four" (Gangue dos Quatro).
- Consulte algumas Fontes para criação
de usuários.
- Consulte Model-View-Controller na Wikipedia.
- Aqui estão mais algumas fontes úteis para Model-View-Controller.
- Consulte uma lista de padrões de
design de software.
- Leia mais sobre Padrões de
Design.
-
PHP.net é o recurso central dos desenvolvedores de
PHP.
- Consulte a "Lista de leituras recomendadas em PHP".
- Navegue por todo o conteúdo PHP do developerWorks.
- Siga o developerWorks no Twitter.
- Expanda suas habilidades em PHP consultando os recursos de projetos em PHP do IBM
developerWorks.
- Para ouvir entrevistas e discussões interessantes
para desenvolvedores de software, consulte os podcasts do developerWorks.
- Usando um banco de dados com PHP? Consulte Zend Core para
IBM, um ambiente de desenvolvimento e produção PHP perfeito, inovador e
fácil de instalar que suporta IBM DB2 V9.
- Mantenha-se atualizado com os eventos e webcasts técnicos do
developerWorks.
- Verifique as próximas conferências, feiras,
webcasts e outros Eventos em todo o mundo que sejam de
interesse dos desenvolvedores IBM de código aberto.
- Visite a Zona de código aberto do developerWorks
para informações extensivas sobre como fazer, ferramentas e atualizações de projetos
que o ajudarão a desenvolver com as tecnologias de código aberto e usá-las com os
produtos IBM.
- Assista e aprenda sobre a IBM e as tecnologias e
funções de produtos de código aberto com as demos on demand do developerWorks
grátis.
Obter produtos e tecnologias
- Inove em seu próximo
projeto de desenvolvimento em código aberto com o software de avaliação IBM, disponível
para download ou em DVD.
- Faça download das versões de avaliação de produtos IBM ou
explore as avaliações on-line no IBM SOA
Sandbox e utilize as ferramentas de desenvolvimento de aplicativos e
produtos de middleware do DB2®, Lotus®, Rational®, Tivoli® e
WebSphere®.
Discutir
- Participe dos blogs developerWorks e envolva-se na
comunidade do developerWorks.
- Participe de Fórum PHP developerWorks: Desenvolvendo
aplicativos PHP com produtos IBM Information Management (DB2,
IDS).