Nomeado ao Innovation Award no phpclasses.org!

Recebi um E-mail muito legal hoje(01-mar), avisando que fui indicado ao prêmio de inovação no PHPClasses.org. Que legal! O pacote indicado é o RestServer , implementação para webservices restful em php.

Fiquei bem feliz por que dediquei-me bastante neste pacote, e de fato o uso bastante, e recebo um feedback legal dele.

Quem for cadastrado no site pode votar na classe que achar mais inovadora através do link de votação

Uma boa maneira de começar o mês, huh? 

RESTServer: Pacote para criar sistemas RESTful em PHP

Como disse no texto sobre REST, a cerca de um ano comecei a estudar essa arquitetura. E que maneira melhor de conhecer uma tecnologia do que implementando-a?

Bom com esse intuito apliquei os principios de REST ao longo dos projetos que tive, em paralelo montei uma biblioteca com o pacote de classe uteis aos projetos, que consideirei estável este ano  e então publiquei. Pode conferir o projeto no PHPClasses ou se aventurar no GITHub

É um conjunto de classes para PHP que constitui o seguinte:

  • RESTAction – Uma interface para ações a serem tomadas
  • RESTController – Interface para os controllers que responderão as requisições
  • RESTView – Interface para as classes responsáveis pelas respostas
  • RESTRequest – Classe que contêm os dados da requisição feita
  • RESTResponse – Classe para controlar a resposta
  • RESTServer – Principal classe para o controle do fluxo das informações

O Objetivo principal é prover um meio fácil de mapear Métodos e URLs para Controller(ou métodos deste), assim o uso básico é o seguinte:

$rest = new RestServer;
$rest->addMap("GET","/user/[0-9]*","UserController");
$rest->addMap("POST","/user","UserController::insert");

Você escolhe um método HTTP, um padrão de URL (usando regex) e o controller ou até o método especifico.(Pode até mapear direto para uma View, mas isso é feio ;).

O RestServer é passado para o controller para este poder usar o que for necessário. RestServer prove as informações da requisição(URL, método, parametros, mime…) através do RESTRequest e permite configurar a resposta (headers, content…) pelo RESTReponse, além de possuir controle de autênticação.

Mais detalhes pode conferir nos arquivos do pacotes. 

Autoloading no PHP, por que sim e por que não.

Autoloading no PHP é uma forma prática de incluir classes ao contexto que ainda não tenham sido declaradas, eu já fiz um texto sobre isto. Serve para melhorar o problema de( lembrar de) fazer várias inclusões das várias classes relacionadas em um projeto Orientado a Objeto, e com a SPL o autoloading fica ainda mais flexível uma vez que se pode registrar mais formas de fazer essa inclusão (não use o modo tradicional, por favor prefira a SPL) .

Em sistemas de médio porte em diante(ou qualquer sistema com mais de 10 classes) o uso de autoloading é quase indispensável, já que é bem ruim a cada alteração na estrutura de classes atualizar os includes, mas pior que isso é ter que incluir muitas classes que provavelmente não serão usadas em determinados fluxos, gastando mais memória por requisição atoa. Esse é o principal argumento para o uso do autoload, e é suficiente.

Mas vamos além.

O primeiro problema no autoload é que a cada inclusão de classe a rotina escrita pelo desenvolvedor deve buscar a classe requisitada, isso pode levar a dois pontos:

  • Rotinas grandes ou complexas para flexibilizar a inclusão.
  • Padrões de nomenclaturas e pastas ruins e/ou restritivos.
  • Gambiarras, mas como qualquer coisa pode levar a gambiarras então deixemos esse de lado.

As rotinas grandes podem representar um problema de performance, já que vão ser executadas várias vezes durante a requisição. Para uma requisição chegar ao autoload já é uma “perda de tempo”, já que é o ultimo recurso do sistema e ele tem que deixar uma rotina interna do interpretador para executar uma do usuário.

E os padrões de nomenclaturas podem engessar seu sistema ou mesmo produzir um design ruim de pacotes. EU ( minha opinião apenas), por exemplo, ODEIO o padrão Pasta_Pasta_Arquivo(.php) de nomes de classe que é adotado por muitos frameworks e sistemas, da mesma forma que gosto de colocar as classes nas pastas de seus pseudos pacotes e com nomenclatura NomeDaClasse(.class.php).

Por exemplo, se eu quero usar o Zend framework mais o Outlet e mais um pacote próprio, eu tenho três padrões de nomes a usar e um problemão para o meu autoload (falta de padrão na aplicação causa problemas de qualquer forma, não é culpa da ferramenta).

Isso é melhorado com a entrada dos Namespaces, já que podemos interpretar a estrutura de pastas de forma semelhante com a dos namespace e manter o nome de nossas Classes limpos e precisar de menos “advinhações” para saber aonde esta o arquivo desta classe. Tornamos o autoload mais rápido e prático e deixamos a definição de nomes mais flexíveis.

Apesar do que escrevi, nenhuma dessas razões faz deixar de valer a pena usar o autoload. Além disso, o autoload somado as capacidades de reflexões do PHP nos dá uma poderosa arma.

Já que, virtualmente, todas as classes vão passar pelo autoload, seria realmente fácil criar uma classe padrão que garantisse alguns métodos básicos e estender as classes requisitadas no tempo de carregamento, ou ainda uma classe base para cada pacote da aplicação, assim um controller já estenderia uma classe, uma view outra. Podemos ainda criar classes “onTheFly” ou avaliar anotações e comentários.

Enfim, isso nos traz boas possibilidades que os frameworks podem aproveitar, mas tentem não me obrigar a usar mais padrões próprios e nem alterar minha modelagem para isso ;)

Spaghetti* Framework em PHP: Vale a pena.

O Julio Greff e o Rafael Marin lançaram a pouco tempo (eu que demorei para fazer o post) o seu Framework PHP: O Spaghetti*. É open source, MVC e Orientado a Objetos.

 

Spaghetti, seu próximo framework

 

 Tenho que confessar que sou bem "chato" quanto a novos frameworks, só acredito vendo mesmo, e com este não foi diferente.  E vi, e gostei do que vi. Apesar de ainda estar no começo, acho que demonstra um bom potêncial!

Ele surgiu de uma necessidade real por uma ferramenta de qualidade para o desenvolvimento, então ele "não viaja" nos recursos. Vamos a alguns itens importantes(para o meu uso) sobre o framework:

  • PHP5 (isso é muito importante, retro-compatibilidade me mata).
  • Rápido setup da aplicação e pouca configuração(se quiser).
  • URLs amigáveis naturalmente.
  • Facilmente extensível e estimula o reuso ao máximo, através de Helpers e Componentes que funcionam de forma transparente e prática.
  • O Item acima me faz pensar que surgirão extensões facilmente.
  • Permite diferentes extensões(.xml,.json…) para a visão.
  • Acesso ao Banco de dados simplificado através do Model como repositório.
  • Templates através de simples PHP (mais que isso é apenas overhead).
  • Só carregue o que precisar.
  • A abstração de banco de dados suporta relacionamentos complexos de forma simples e transparente.
  • Funciona!

Sinceramente, a adoção de ferramentas de desenvolvimento a maioria dos frameworks que usei não me agradaram e foram abandonados. Salvo poucas exceções, é tudo muito mais-do-mesmo. Achei o Spaghetti* uma boa exceção, experimentei fazer um aplicação com ele, deu certo e eu não fiquei irritado.

A parte de Model para banco de dados é bem prática, mesmo sendo diferente do que costumo fazer(o Model é como um repositório aqui), e funciona sem que eu me preocupe. Mesmo os relacionamentos.

As URL são mapeadas para os Controllers automaticamente, mas você pode criar rotas alternativas e definir prefixos. Os Controllers são o centro das atenções, na minha opinião, eles carregam automaticamente o Model equivalente (você pode escolher outro, se quiser) e é simples de carregar Componentes adicionais. No fim, a View correspondente é carregada ou você pode passar a requisição adiante(redirect).

As Views são arquivos PHP comuns, você pode carregar Helpers ou usar variáveis que o Controller disponibilizar. Bom o bastante. Você pode ainda usar Elements, para criar elementos de Views reutilizáveis.

O conjunto todo simplesmente funciona, e a modelagem é bem simples(o que é bom!), sem overhead e nem dores de cabeça. O modelo de Components/Helpers/Elements são legais para o reuso e o MVC é prático e rápido de fazer.

Resumindo recomendo testar, de uma olhada na documentação, vale a pena.

Você pode também conferir a aplicação que fiz usando esta ferramenta,  a simples ideias

Anotações em PHP

Anotações é uma forma de adicionar informações a alguma coisa. São meta-dados, ou seja, não chegam a fazer parte do conteúdo em si, mas descrevem algum atributo ou adicionam alguma informação a este. Em programação Anotações, ou annotations, são reconhecidas pelo símbolo "@", as vezes parte de um comentário ou não.

Geralmente é usado em Atributos(estados) ou Métodos(comportamento) de Objetos/Classes, para ser usado por algum framework ou outra parte da aplicação, adicionando alguma informação a ser usado por esse. É usado para agilizar o processo, sem ter que escrever muitas linhas apenas para um dado simples.

PHP Annotation 

Por exemplo podemos definir que um atributo deve ser persistido(ou não), ou que determinado método deve sempre ser disparado antes de outro. Anotações por si só são apenas informações, tanto como comentários, o que a aplicação ou framework faz com elas é o que importa.

PHP não implementa suporte a anotações por padrão, não faz parte do core. Mas a comunidade é grande e existe um framework muito bom para isto, o Addendum. Ele não tem dependências, é bem simples de usar e esta bem documentado, como anotações devem ser. Tenho usado-o em um par de projetos, e tem atendido muito bem.

Vejam como é simples o uso, supondo uma classe User, com os atributos $login e $passwd, queremos dizer que a classe é persistente, podemos fazer assim:

/** @Persistent **/
class User

E continuar a definir a classe, fazemos então o atributo $login a chave primaria:

/** @Persistent (pk=true) **/
private $login ;

E por ai vai. A classe Persistent precisa existir também, estendendo a Annotation.

Como disse antes, a anotação por si só não faz a mágica. O addendum "apenas" serve para recuperar as anotações da classe/atributo/método, o que fazer com ela depende de você(ou do seu framework).

Para recuperar as informações usa-se os seguintes métodos, entre outros:

$reflection = new ReflectionAnnotatedClass('User'); $anotation = $reflection->getAnnotation('Persistent'); $isPK = $anotation->pk;

Simples e direto, porém bem flexível. Apesar de bem útil, ainda não conheço nenhum framework ou projeto que use estes recursos.

Lendo arquivos de planilhas Excel com PHP

Um projeto bem interessante que terminei a pouco envolvia a atualização de um site através da leitura de uma série de Planilhas no Excel. Basicamente o Usuário faria o upload da planilha e o com PHP essa planilha seria usada como base de dados.

Questões de performace aparte, é uma solução bem simples, bastou trocar o PDO por um classe para leitura do excel e adaptar o Repositorio. Considerando que só tornou uma aplicação de leitura apenas.

Se fosse em outros dias eu pensaria: "Ferrou tudo, la vou eu escrever mais um leitor complexo!" , mas a algum tempo trombei com uma classe bem interessante, que como não sei quem é o autor inicial, fica aqui o primeiro link que achei: OLEREAD , que é parte de um projeto maior ao que parece. 

Salve a classe do link no arquivo "oleread.php" e vamos ao trabalho sujo, como ler um excel:

Primeiro, para começar a leitura do arquivo faça assim:

<?
include 'oleread.php' ;
$file = "arquivo.xls" ;
$data = new Spreadsheet_Excel_Reader();
$data->setOutputEncoding('CP1251');
$data->read($file);
?> 

Com isso a estrutura da planilha XLS será carregada no Objeto $data. Para acessar uma planilha você precisa acessar a propriedade "sheets" , um array com todas as planilha do arquivo(cada "aba" na  parte de baixo do excel) pela numero da ordem em que se encontram começando do 0. Exemplo de como pegar a primeira planilha da pasta de trabalho do excel:

<? $first = $data->sheets[0] ; ?>

Ou pode-se ainda percorrer todas as planilhas:

<? foreach($data->sheets as $sheet) { // código aqui } ?> 

Cada planilha(sheet) possui então uma propriedade chamada 'cells', que é um array muiltidimensional com todas as celulas da planilha, até aonde foi preenchida. O primeiro indice do array é a linha, o segundo a coluna, dessa vez começando do 1 ambos. Eis alguns exemplos:

<? $cells = $data->sheets[0]['cells'] ; 
echo "nTitulo da planilha (linha 1, coluna A):". $cells[1][1] ;
echo "nSubtitulo (linha 2, coluna C):".$cells[2][3] ;
?>

Como, por exemplo, tranformar em tabelas html as tabelas do excel(perdão pela falta de organização):

 <? foreach($data->sheets as $sheet) { // loop tabelas
echo "<table>";
foreach($sheet['cells'] as $lines) { // loop linhas
echo "<tr>";
foreach($lines as $col) { //loop colunas
echo "<td>".$col."</td>";
}// fim colunas
echo "</tr>" ;
}//fim linhas
echo "</table>" ;
} //fim tabelas ?> 

Básicamente é isso, e me ajudou bastante esta classe que transforma as planilha em um arquivo xls do excel em um array do php. Não tem grandes mistérios, é só não se perder entre tantas listas ;) 

Abraços! 

Frameworks para Persistência de Dados em PHP

Falando em Mapeamento Objeto Relacional e Persistência de dados… ah, ops, eu ainda não falei sobre isso.

Dica rápida: Para quem esta procurando um framework de persistência e/ou ORM para PHP, tenho usado dois que acho muito bons:

Os dois são BEM diferentes, mas ambos servem ao mesmo propósito: facilitar a vida do desenvolvedor, quando o assunto é banco de dados.

O Doctrine seque o padrão Active Record (aquele do rails, cake…), que é o padrão da moda. Este framework chegou a versão 1.0, é muito estável e traz uma gama imensa de recursos. Um exemplo rápido de como configurar uma classe com ele:

<?
class User extends Doctrine_Record {

public function setTableDefinition() {
$this->setTableName('users');
$this->index("id");
$this->hasColumn("id","integer",11,array("primary" => true,"unique" => true));
$this->hasColumn('name','string',220);
$this->hasColumn('email','string',220);
$this->hasColumn('pwd','string',220);
$this->hasColumn('phone','string',220);
$this->hasColumn('sip','string',220);
$this->hasColumn('callback','boolean');
$this->hasColumn('admin','boolean');
}

public function setUp() {
$this->hasMany("Contact as catalog",array("local" => "id", "foreign" => "id_user"));
}

}
?>

Está pronto. Como fazer uma query simples:

$users = Doctrine::getTable("User")->find($id);

E uma mais complexa(Artigos e Pontos são classes distintas, e existe um join em Artigos para Pontos):

$artigos = Doctrine_Query::create()->from("Artigos a")->innerJoin("a.pontos p")->limit($count)->orderBy("a.pontos DESC")->execute();

Interessante não? O resto é padrão do Active Record, para salvar por exemplo basta chamar save() no próprio objeto. Existe material sobre este framework na internet, e é relativamente bem documentado.

O doctrine ainda permite muito mais coisas, como arquivos de configurações, schemas, pode criar as tabelas para você, pode criar as classes…

Porem, eu não gosto do Active Record, acho que é uma falha de modelagem, dão muita responsabilidade para a classe do modelo. Por isso busquei uma outra opção, então depois de muito buscar (muito mesmo, já que AR é a moda) achei o Outlet.

O Outlet tem tudo que eu gosto em um framework, é simples, são poucos arquivos, desacoplado, api enxuta e bem flexivel. Ele faz apenas o que se propõe. Ainda não testei ele completamente, mas parece bem promissor.

O uso do outlet é bem simples, você constroi seu modelo normalmente(sem extender nada, sem modificar nada) e faz a configuração em um array descrevendo as classes, como este:

<?

return array (

 

'connection' => array(

'dsn' => 'mysql:host=localhost;dbname=libhertz',

'username' => 'admin',

'dialect' => 'sql',

'password' => '123'),

'classes' => array(

'User' => array(

'table'=>'users',

'props'=>array(

'id'=> array('id','int',array('pk'=>true,'autoIncrement'=>true)),

'name'=>array('name','varchar'),

'email'=>array('email','varchar'),

'phone'=>array('phone','varchar'),

'sip' =>array('sip','varchar'),

'callback'=>array('callback','int'),

'admin'=>array('admin','int'),

'pwd'=>array('pwd','varchar')

),

'associations'=>array(

array('one-to-many','Contact',array('key'=>'id_user','name'=>'catalog','plural'=>'catalog'))

)

),

'Contact' => array(

'table'=>'contacts',

'props'=>array(

'id'=>array('id','int',array('pk'=>true,'autoIncrement'=>true)),

'name'=>array('name','varchar'),

'id_user'=>array('id_user','int'),

'phone'=>array('phone','varchar'),

'fastPhone'=>array('fast_phone','varchar')

)

)

)

) ;

?>

Chamamos o outlet através de seu singleton:

$outlet = Outlet::getInstance();

E então usamos seus recursos, como:

  • $outlet->save($obj);
  • $user = $outlet->load('User',$id);
  • $users = $outlet->load('User','Where {User.name} = ?',array('Diogo'));
  • $users = $outlet->load('User',”Where {User.name} = 'Diogo'”);
  • $outlet->delete($obj);

A documentação no site do Outlet é muito boa na minha opnião, este é , atualmente, meu favorito.

Ficam ai as dicas, alguêm tem algum para recomendar?

UPDATED!!!

Com a dica do Luiz nos comentários lembrou o Framework Brasileirissimo Lumine de mapeamento de banco de dados para PHP. que merece destaque.

Com uma forte inspiração do Hibernate do java, um mega-framework de persistência para java, e do DB_DataObject, do PEAR. Mas  sem a pior parte(na minha opnião) do Hibernate: Sem XML! Ele usa um recurso de engenharia reversa do banco de dados para gerar a configuração.

Ainda não tive a oportunidade de usa-lo, mas entrou na lista de tarefas com boa prioridade. Então espere em breve comentários sobre este Framework, o Lumine

ArrayAccess, Iterator e SPL: Classes como array.

Parte muito interessante do PHP é a SPL. A Standart PHP Library veio para suprir varias necessidades de classes e interfaces úteis a qualquer sistema, como Classes para Array, iteradores, iteradores para sistemas de arquivos entre varios outros. E qual a real utilidade disso? Varias.

Agora, você pode ter um meio padrão para listar diretorios, sem funçoes que mais parecem gambiarras. Também trás melhores recursos para iteradores recursivos, por exemplo. E o titulo?

Como parte de SPL, têm duas classes que eu tenho usado em especial: ArrayAccess e Iterator.

Iterator é uma interface que permite que você itere(ande, avançe, se mova) em um objeto de forma básica, como se fosse um array mesmo. Normalmente fazer por exemplo foreach($obj as $property=>$value),  você navegaria pelos atributos definidos da classe. No caso do iterator, é um objeto que saber como fazer isso, de forma personalizada. Pode-se por exemplo definir um Iterator que ao invés de avançar pelos métodos do objeto passado, navegue por apenas elementos especificos, ou em uma propriedade que tenha uma lista. Enfim, basta usar a criatividade.

O ArrayAccess também é muito especial, esta interface permite o acesso a seu objeto como se fosse um array mesmo com "$obj[1]" ou mesmo "$obj[]". 

Existem outras também, que em outra oportunidade vou falar, mas essas eu estou em maior contato e aconselho a todos que usam PHP prestar alguma atênção a SPL, quem sabe não facilite sua vida um pouco.

Dito isto, eu tenho uma Classe, um tanto generica, chamada Collection. Ela, como o nome diz, é uma classe para lidar com listas, vetores e etc… Ela implementa estas duas interfaces, logo é capaz de se comportar com todos os recursos de um array, mais as vantagens de um Objeto. 

Na pagina da classe têm o arquivo de exemplo, onde podes ver alguns de seus usos. Eu pessoalmente uso em algo mais assim:

<?
class PageList extends Collection {
  function __construct() {
    $pageDAO = new PageDAO ;
    $pages = $pageDAO->select();
    $this->merge($pages);
  }
}
?>

Ou seja, eu posso em meu código usar apenas $pages = new PageList, e já vou ter um objeto totalmente manipulavel, iteravel e fazer coisas como foreach($pages as $page) ou while($page = $pages->fetch()) naturalmente e sem gambiarras.

Posso ainda sobrescrever os metodos add() e set() para ter maior controle sobre a coleção… novamente são muitas possibilidades.

Além, é claro, de ser útil para estudar ;) 

Netbeans para PHP

A uma semana, mais ou menos, tenho usado o Netbeans como minha principal IDE para desenvolver em PHP. O Netbeans é , assim como o eclipse , uma ambiente de desenvolvimento em JAVA (e para Java, originalmente) com plugins e aceita uma variedade de outras linguagens.

A diferença principal é que o Eclipse possui muito mais plugins e suporta mais linguagens, além de ter uma comunidade mais ativa. O Netbeans tem o "suporte" da própria Sun. Entre os dois o Netbeans sempre me pareceu melhor em recursos do que o eclipse, mas a falta de plugins e o "peso" do sistema me fizeram sempre escolher o eclipse.

Com o lançamento da versão 6.1 do Netbeans, saiu também a versão Early Access do Netbeans para PHP , Early Access (ou “ea”) é ainda uma versão beta, e eu resolvi testar este suporte ao PHP. O Download pode ser obtido aqui. Veja que entre as varias versões escolha a para PHP (penúltima), com apenas 16mbs. Vamos a análise, que será obviamente comparando ao Eclipse:

Primeiro, não sei qual é o melhor. São duas IDEs distintas. As duas são ótimas, hoje minha opinião é uma, mas basta um plugin ou um update para mudar de idéia.

O primeiro ponto a favor é o seguinte, são 16Mbs de download, só! E isso conta. Eu diria que isso é sem "bloatware", e realmente é, mas a lentidão ainda é bem chata, correndo o risco de falar besteira, mas o swing me irrita e eu acho que a culpa é dele.

Começando com PhpGtk

O Php-gtk é um pacote para construir interfaces gráficas com PHP usando GTK . Nada mais obvio, e nada poderia ser mais interessante. PHP sendo uma linguagem rápida, fácil e flexivel e GTK sendo também um ótimo kit gráfico, fica uma combinação ótima.

A parte interessante é que o php-gtk funciona como stand-alone, ou seja, roda sem um servidor nem nada, apenas com o próprio pacote, que tem entre 8~14Mb. Já vem com o PHP mais recente (atualmente vem com o 5.2.4, com as principais extênsões, e GTK2 (agora 2.12). Também pode-se instalar outras extênsões conforme necessidade.

Com esses 14Mbs, você já têm o necessário para contruir aplicações gráficas de qualquer tamanho, com acesso a banco de dados, uso de webservices e tudo mais a que tem direito. Como opção ainda mais interessante, pode-se usar como banco de dados SQLite .

O SQLite é um banco de dados leve e rápido, que depende apenas do próprio conteúdo do banco de dados, que fica em apenas um arquivo, e pode-se ser totalmente usado apenas com as funções de banco de dados do próprio php, com o PDO ou as funções especificas(o aconselhavel é o PDO).

Para construir a interface você pode ainda contar com o Glade , que permite desenhar interfaces gráficament, arrastando e soltando. Muito rápido desenvolver assim. O glade esta nos repositórios de quase todas as distros.

Ficando assim simples de distribuir o sistema criado, que será leve e rápido.

Como instalar: Baixe a opção devida em http://www.php-gtk.com.br/linux , veja de acordo com sua biblioteca gclib, no debian e derivados (ubuntu,kurumin, etc) use:

# dpkg -l | grep libgtk2

Feito o download da versão correta, vamos a instalação:

# mv php-gtk2* /usr/local/

# tar -xzvf php-gtk2*

# chmod 777 php-gtk2 -Rf

# ln -s /usr/local/php-gtk2/bin/php /usr/bin/php-gtk

Como criar uma aplicação: Crie um arquivo php normal, para aprender sobre a api do GTK consulte sites como o php-gtk.com.br. Um exemplo é assim:

<?php
$janela 
= new GtkWindow;
$janela->show_all();
Gtk::Main();
?>

 Bem simples, salve como teste.php e de permissão de execução (chmod 755), então o execute com:

$ php-gtk2 teste.php 

Para facilitar basta colocar no começo do arquivo  a seguinte linha:

#!/usr/bin/php-gtk2

Agora você pode lançar o aplicativo com dois cliques ou apenas com:

$ ./teste.php

Agora divirta-se, eis alguns links interessantes: