Archive for janeiro \20\-02:00 2010

PHP – Melhores práticas parte 1: MVC

Posted on janeiro 20, 2010. Filed under: PHP |

Nessa nova série de artigos vamos abordar assuntos referentes a melhorar a qualidade de nossos códigos. Alguns exemplos do que vem pela frente: MVC, Unit Testing, Coding Standard, Segurança, entre outros. Espero que aproveitem.

Arquitetura MVC

Vamos abordar os principais conceitos relacionados ao MVC. O artigo é mais teórico do que prático. A intenção é concientizar sobre a melhor maneira de utilizar o MVC. Não há necessidade de implementar um MVC do zero. Utilize um dos diversos frameworks MVC existentes para PHP. Use os conceitos abordados aqui no seu framework de preferência. Durante este artigo vamos citar classes do Zend Framework para exemplificar alguns pontos.

O objetivo do MVC é separar o Modelo (Model) da apresentação (View) com a ajuda de um Controller. View é aquilo que o usuário enxerga: formulário web, lista de produtos, etc. Geralmente formados por códigos HTML/CSS e Javascript. O Controller recebe a requisição do usuário e decide qual modelo chamar, obtem as informações necessárias e então atualiza o View. Um ponto importante aqui é que o Modelo não deve depender da View. A View pode mudar sem ter que precisar de alterar o Modelo.
O Modelo não se refere somente acesso ao banco de dados. Ele pode conter chamadas para webservices, acessar arquivos em disco, etc. Ele compôe também as regras de negócio da aplicação.

O Controller

Nos principais framewors atuais temos um “Front Controller” que recebe os parâmetros da requisição e despacha para uma classe que irá fazer o devido processamento.Estas classes, que fazem o processamento do input, são conhecidas como “Controllers”, são as Action Classes.
Perceba a diferença que existe entre “Front Controller” e “Controller”. O Front Controller recebe a requisição e dispara para uma action, um Controller, que irá tratar o input. O Front Controller determina qual action chamar de acordo com a “Query String” da requisição. Por exemplo: A requisição para o página http://localhost/admin/new será recebida pelo Front Controller e irá despachar para o método “newAction” do Controller “Admin”.

Precisamos tomar cuidado para não colocar regras de negócio no controller. Este não é o seu propósito. Regras de negócio no controller não poderão ser reutilizados fora dele. Além disso, poderemos ter código duplicados. Lembre-se destes pontos e caso haja necessidade faça o refactoring do código.

View

Após o processamento dos dados enviados pela requisição, nós precisamos apresantá-los para o usuário. É aqui que entra o nosso View, ou camada de apresentação. Exemplo: Formulários, textos, listas, css, javascript, etc. Todos pertencem a camada View.

Ao trabalhar com templates na camada view temos que lidar com diversas maneiras de apresentar os dados. Por exemplo, fazer um loop para exibir items de uma coleção. Exibir um texto de acordo com a permissão do usuário ou se o usuário esta logado ou não. Exibir um estilo css diferente de acordo com determinada situação. Ou seja, existem situações que devemos escrever diferentes tipos de lógicas em nossa camada de apresentação.

Porém a regra da camada de apresentação é fornecer uma maneira simples e fácil para a interação com um Webdesigner. Conforme formos adicionado estas lógicas na camada de apresentação, vamos perdendo este foco, deixando nosso template difícil de manter. A regra é que devemos utilizar o mínimo de código possível em nossos templates. Uma maneira de resolver esse problema é mover a lógica dos templates para classes Helpers. Além de manter o template em uma linguagem mais simples, podemos reutilizar o código que estão nos Helpers.

O Zend Framework permite a criação de Helpers de maneira fácil. Além de criar seus próprios Helpers, é possível utilizar diversos Helpers já prontos, distribuídos junto com o framework. Exemplo: Helpers para criação de formulários (form, formButton, formCheckBox, fidlset, formHidden, formFile, formRadio, formPassword, formRadio, formSelect,formText, etc.). Disparar ações para controllers. Doctype. HeadTitle, etc.

Em sua utilização do MVC você deve permitir que a camada de apresentação tenha diversas representações sem que haja necessidade de mudar o Modelo para que isto seja possível. Você pode querer representar a camada View em XML e em HTML ou em outro formato. Caso você precise alterar o Modelo para que se possível manter diversas representações da View, então você deve rever seu código e fazer o devido refactoring.

Model

Muitos programadores tem em mente que o Modelo é o lugar onde deve-se colocar código que irá interagir com o banco de dados. Sim, isto é verdade. Você pode colocar código para interagir com banco de dados no modelo. Porém não é somente isso. Você pode colocar código para trabalhar com webservice, acessar o sistema de arquivos e, o mais importante, colocar as regras de negócio da sua aplicação. O Modelo deve conter o código reutilizável de seu aplicativo. Usando o Modelo corretamente facilita o uso de testes unitários. Você pode testar de forma isolada as regras contidos no Modelo.

Exemplos

Segue abaixo exemplo de algumas situações e em qual camada devem ser tratadas:

Sua aplicação permite que o usuário faça upload de imagens. Toda vez que o usuário fizer o upload de uma imagem,nós inserimos um registro no banco de dados, armazenamos a imagem no sistema de arquivos e enviamos um e-mail para o usuário notificando que o upload ocorreu com sucesso.

Em qual camada deve estar ?

Com certeza na camada de Modelo. Imagine se esta lógica estivesse no Controller ?

  • A query estaria no controller!
  • A lógica utilizada no upload de imagem não poderia ser usada fora do Controller.
  • O código não poderia ser testado sem ter que chamar a aplicação inteira.

Muitas desvantagens, certo ?

Outra situalção:

Filtrando e validando o Input do usuário ?

Você deve responder logo de cara: Controller. Isto esta correto ? Sim, em partes. O filtro e a validação podem ser realizadas no controller, porém a lógica utilizado no filtro ou na validação devem estar em uma classe separada. O objetivo é que a lógica de validação e filtro possam ser reutilizáveis. Por exemplo: validação de cpf, telefone, email, data, etc..
O Zend Framework possui classes para tratar validação e filtros: Zend_Filter e Zend_Validate. Diversos filtros e validações já estão prontos para uso. Porém como qualquer framework flexível, ele permite a criação de seus próprios filtros e validações.

Ler Post Completo | Make a Comment ( 2 so far )

Exim retry time not reached for any host after a long failure

Posted on janeiro 14, 2010. Filed under: Linux |

Esta erro do exim diz que o e-mail não foi entregue devido o servidor smtp de destino não conseguiu ser alcançável por um perído de 4 a 5 dias. O Exim agenda uma nova checagem para o servidor em um determinado intervalo de tempo. Enquanto isso todas mensagens que chegam serão devolvidas imediatamente, sem serem entregas.

Para verificar a próxima data/horário de checagem ao servidor de e-mail de destino, execute o comando baixo:

# exinext xxxuser@xxxdomino.com.br

R: dnslookup for xxxuser@xxxdominio.com.br
Transport: mail.xxxdominio.com.br [200.200.200.200] error 110: Connection timed out
first failed: 31-Dec-2009 01:03:12
last tried: 08-Jan-2010 11:03:06
next try at: 08-Jan-2010 17:03:06
past final cutoff time

Caso o servidor de smtp do destino já esta funcionando normalmente e você não queira esperar até a próxima checagem do exim para que os e-mails para esse smtp sejam entregues, execute o comando abaixo para limpar os registros referentes ao tempo da próxima checagem.

# /usr/sbin/exim_tidydb -t 0d /var/spool/exim4 retry
Tidying Exim hints database /var/spool/exim4/db/retry
deleted T.....................
....................
Tidying complete

Atenção para o path do spool do exim. No exemplo anterior é /var/spool/exim4. Mas pode ser diferente dependendo da instalação, versão ou distribuição.

Pronto, agora os e-mails já podem ser entregues imediatamente. Lembre-se que o smtp de destino já deve estar funcionando normalmente.

Ler Post Completo | Make a Comment ( None so far )

PHP 5.3 parte VI: Outras melhorias

Posted on janeiro 10, 2010. Filed under: PHP | Tags:, |

Neste último artigo da série vamos abordar algumas melhorias pequenas incluídas na versão 5.3 do PHP. Nos artigos anteriores já abordamos os principais recursos incluídos, como, por exemplo, Namespaces, Static Late Binding, Lambda e Closures, Arquivos Phar e mysqlnd. Espero que tenham aproveitado e se diertido com os conhecimentos expressados nessa série. Implementem, testem, aprendam e boa sorte em seus projetos.

Linha de comando.

No php 5.3 a interface de linha de comando, conhecida como CLI (Command Line Interface), teve algumas melhorias. A principal melhoria foi a função getopt que se tornou independente de plataforma. Ou seja, agora funciona também no Windows.

Ainda na função getopt, agora é possível especificar parâmetros no script php, pela linha de comando, usando o caractere de atribuição “=”. Veja o exemplo abaixo:

Arquivo teste_opt.php:
<?php
$options = getopt("i:");
var_dump ($options);

# php teste_opt.php -i="valor teste123"

array(1) {
  ["i"]=>
  string(14) "valor teste123"
}

Veja que chamamos o script php passando o parâmetro -i com um determinado valor, usando o caractere de atribuição “=”.Poderiamos ter usado da seguinte forma também: -i “valor teste123”.

Também é possível que o valor de um parâmetro passado pela linha de comando seja opcional. Para isso devemos utilizar a sequência :: após o nome do parâmetro. Veja o exemplo abaixo:

Arquivo testes_opt.php:
<?php
$options = getopt("i::");
var_dump ($options);

Veja que passamos a sequencia :: após o nome do parâmetro i

# php teste_opt.php -i

array(1) {
  ["i"]=>
  bool(false)
}

# php teste_opt.php -i "valor teste123"

array(1) {
  ["i"]=>
  string(14) "valor teste123"
}

Criamos os dois exemplos acima demonstrando que o valor para o parâmetro i pode ser opcional.

Novos Error Levels

Na versão 5.3 do PHP finalmente E_STRICT faz parte de E_ALL. Agora E_ALL compõe todos errors levels. Nas versões anteriores E_STRICT era um error level separado de E_ALL.

Foram criados dois novos levels: E_DEPREACTED e E_USER_DEPRECATED. E_DEPRECATED alerta sobre funções e recursos que serão descontinuados em versões futuras do PHP, no caso a versão 6 do php. E_USER_DEPRECATED tem a intenção de indicar recursos que serão descontinuados relacionados ao código do usuário.

Algumas fuções que serão descontinuadas em versões futuras: ereg, ereg_replace, split, session_register, session_unregister, etc. Para uma lista completa acesse: http://www.php.net/manual/pt_BR/migration53.deprecated.php

O exemplo abaixo demonstra a utilzação de uma função que será descontinuada da versão 6 do php. Veja o retorno obtido após a execução do script.

c:\php5\error\teste.php:
<?php

echo ereg("[0-9]", "d0uglas");

Resultado:

Deprecated: Function ereg() is deprecated in C:\php5\error\teste.php on line 3
1

__callstatic

__callstatic é um método mágico incluso na versão 5.3. Sua função é tratar chamadas para métodos estáticos inexistentes na classe. Quando você fizer uma chamada para um método estático em uma classe onde o método não existe o php irá procurar pela existência de um método mágico chamado __callstatic, passando como parâmetro o nome do método e os argumentos passados caso haja algum. Esse método é semelhante a outros médotos mágicos como __call, __set, __get.

Veja o exemplo abaixo onde demonstramos a utilização do método estático. Estamos fazendo a chamada para dois métodos estáticos. O primeiro, printText(), existe na classe StaticClass e portanto é executado normalmente. Já a chamada para o segundo método, createUser(), não existe na classe StaticClass, portanto será chamado o método __callstatic passando os devidos parâmetros.

<?php

class StaticClass {
   public static function printText() {
     var_dump("PrintText static function called");
   }

   static function __callstatic($methodname, $args) {
     var_dump($methodname);
     var_dump($args);
   }
}

StaticClass::printText();
StaticClass::createUser("Elizandra");

Segue a saída do script anterior:

string(32) "PrintText static function called"
string(10) "createUser"
array(1) {
  [0]=>
  string(9) "Elizandra"
}

Chamadas variáveis estáticas

Agora é possível fazer chamadas estáticas onde o nome do método esta contido em uma variável. Já podiamos fazer isso com variável variáveis e chamada de método variável. Agora pode utilizar esse conceito em métodos estáticos.

Veja a utilização no exemplo abaixo: (Estamos aproveitando a classe utilizada como exemplo no tópico anterior).

<?php
$class_name = "StaticClass";
$static_method_name = "printText";
$class_name::$static_method_name();

Segue a saída do script anterior:

string(32) "PrintText static function called"

Veja como ficou a chamada para nosso método estático usando variável no nome: $class_name::$static_method_name();

Novas funções

Duas novas funções inclusas foram array_replace e array_replace_recursive.
A função array_replace irá atualizar os dados do primeiro array de acordo com os dados dos arrays seguintes. Se uma chave do primeiro array existe no segundo, o valor da chave no primeiro array será atualizado. Caso exista a chave somente no segundo array e não no primeiro, será criado um novo elemento no primeiro array.

A função array_replace_recursive atualiza os elementos da primeira array procurando nos arrays de forma recursiva.

Novos recursos SPL

SPL significa Standard PHP Library. É uma coleção de interfaces e classes com o objetivo de resolver problemas padrões e implementar de uma forma eficiente o acesso à dados de classes e intefaces.

Segue abaixo as classes SPL inclusas no php 5.3:

  • SplFixedArray
  • SplStack
  • SplQueue
  • SplHeap
  • SplMinHeap
  • SplMaxHeap
  • SplPriorityQueue

Segue abaixo links onde vocês poderão encontrar mais informações sobre as classes SPLs incluídas na versão 5.3 do php.

http://www.php.net/manual/en/class.splstack.php
http://www.slideshare.net/tobias382/new-spl-features-in-php-53

Ler Post Completo | Make a Comment ( 1 so far )

Liked it here?
Why not try sites on the blogroll...

%d blogueiros gostam disto: