Dicas para desenvolvimento de extensão em PHP

23 03 2007

É, não é complicado…

Pra quem já começou ou pretende começar, segue 4 ótimos links:

Extension Writing Part I: Introduction to PHP and Zend
Introdução, falando desde o mais básico da criação de uma extensão.

PHP and Zend Engine Internamente
Seção no manual do PHP com bastente informação sobre APIs

Extending and Embedding PHP
Livro da mesma autora do primeiro artigo (Sara Golemon). É o típico livro “must have”.

PHP Cross Reference
Fonte “navegavel” do PHP. A forma mais fácil de compreender o que se passa internamente, é lendo o fonte enquanto se desenvolve, ver o que é cada macro ( há centenas de macros ), entender cada struct, e por aí vai.

Com apenas estes quatro links, acredito ser possível desenvolver bastante coisa interessante.





Validação de campos usando XML

23 03 2007

Há quanto tempo pessoas!
Pois é, a vida está bastante corrida, e o tempo anda curto… quando sobra algum, a gente acaba dormindo : | Meleca viu… Mas, lamentações a parte, vamos falar sobre o que realmente interessa: PHP!
Bom, como ando meio sem criatividade para postar, decidi que vou demonstrar uma maneira de realizar validação de campos, utilizando xml para caracterizar essa validação, fazendo com que você não precise sair que nem louco caçando as validações no meio do seu código o dia que precisar alterar alguma. Esse é o tipo de validação que o E. Silva e eu temos utilizado em nosso framework do qual ele já comentou ai em alguns comentários (frase linda).
Algumas idéias aqui, poderão parecer confusas de início para quem não está muito acostumado com PHP, mas como sempre digo, se tem alguma duvida, fique a vontade para mandar email ou deixar comentário que a gente resolve como pode.
Como sempre, gosto de começar com exemplos, então, vamos começar com o XML de exemplo:

validador.xml

<validator>
    <field name=‘nome’ validation=‘validator::isFilled’ when=‘insert,update’ />
    <field name=‘cpf’ validation=‘validator::isCpf’ when=‘insert,update’ />
    <field name=‘data’ validation=‘validator::isData’ when=‘insert’ />
</validator>

Esse ai será o xml que iremos usar para validar nossos campos. Vamos entender algumas coisas:
A propriedade ‘name’, identifica o nome do campo que será validado
A propriedade ‘validation’, define o método que será utilizado para validação
A propriedade ‘when’ define quando a validação deverá ocorrer. Essa propriedade será identificada através da ação que o botão do formulário fornece.

Os exemplos que serão trabalhados, utilizam o método POST para envio dos dados, e tem o action definido na própria página. Preparem-se, pois hoje teremos bastante código.
Vamos dar uma olhada agora, no código do formulário, que ficará no script que chamaremos de index.php

index.php

<form method=“POST”>
<input type=“text” name=“nome” /><br />
<input type=“text” name=“cpf” /><br />
<input type=“text” name=“data” /><br />
<!– agora vem o botão de submit, que identificará a ação que ocorre –>
<input type=“submit” name=“acao” value=“Insert” />
</form>

Esse script ainda não está pronto. Falta ainda o código PHP do mesmo. Agora, vou esclarecer um pouco melhor como será o funcionamento do script.
Todo o formulário, será (ou não), preenchido, e será feito o envio das informações ao se clicar no botão de Inserir. Quando o script receber esses dados, será invocada a classe, que lê o xml de validação, e aplica essa validação aos campos que foram recebidos. Os campos serão validados conforme descrição feita pelo XML, e a partir dai serão geradas as mensagens do sistema. O script que será demonstrado é um exemplo, para dar uma idéia de como se utilizar esse método de validação. Não estou demonstrando exatamente igual ao funcionamento do nosso framework, pelo simples fato, de que eu iria precisar de muitas classes do framework para isso, e então deixaria de ser um post de blog, para virar um livro : |
Veja então a classe que irá fazer o parse do arquivo xml, e validará as entradas fornecidas pelo usuário:

action.class.php


<?php

class Action {

    // Essa propriedade da classe, ira conter
    // o resultado da validacao de cada um dos
    // campos.
    
private $validacao = array( );

    // Essa propriedade ira dizer se ocorreu algum erro
    // para o script 
    
private $error null;

    // Retorna o valor da propriedade $error
    
public function getError( ) {
        return 
$this->error;
    }

    // Retorna o valor da propriedade $validacao
    
public function getValidacao( ) {
        return 
$this->validacao;
    }

    public function run( ) {
        
// normalmente, possuimos uma classe para trabalhar
        // com metodo POST e GET. No nosso caso, de forma a 
        // simplificar a quantidade de codigo, vamos usar a 
        // variavel $_POST diretamente

        // Essas aqui serao as acoes que iremos validar. Como
        // ja comentado, as acoes sao definidas atraves do valor
        // do botao que faz o metodo POST
        $validActions = array(
                            
'insert',
                            
'update',
                            
'delete' 
                        
);

        $acao strtolower$_POST['acao'] );
        if( 
in_array$acao $validActions ) ) {
            
// Inicializar a variavel de controle de erro
            
$this->error true;

            // Se chegou nesse ponto, significa que a acao realizada
            // foi uma das acima. Agora deve-se carregar o xml e começar a
            // fazer o seu parsing
            
$xml simplexml_load_file'validador.xml' );

            // A partir de agora, vamos avaliar cada uma das linhas do xml
            // e realizar a validacao.
            
foreach( $xml->field as $campo ) {

                // Aqui, vamos procurar pelo campo atual que encontramos no xml
                // dentro do array $_POST. Se o campo for encontrado, iremos
                // validar o valor que nos foi enviado.
                
if( array_key_exists( (string)$campo['name'], $_POST ) ) {

                    // Otimo, encontramos o campo no array POST. Porem antes
                    // de validarmos o campo, precisamos verificar se ele
                    // deve ser validado na acao que esta acontecendo.
                    // Lembra-se da propriedade 'when' no xml? Eh aqui
                    // que ela entra, nos informando se o campo deve ou nao
                    // ser validado. As acoes devem ser separadas por uma ','
                    // no xml
                    
$whenToValidate explode(','$campo['when'] );
                    if( 
in_array$acao$whenToValidate ) ) {

                        // Finalmente chegamos! Chegou aqui, entao esta na hora
                        // de validar o campo de acordo com o que esta no xml.
                        // O conteudo especificado na propriedade 'validation'
                        // do xml, define um metodo estatico a ser chamado para
                        // validar o valor que foi enviado no metodo post
                        // nos permitindo assim, assumit que esse metodo recebe
                        // ao menos 1 parametro, que eh o valor a ser validado
                        // Veja a classe com os metodos de validacao, para
                        // entender exatamente o que acontece
                        
$codigo sprintf('$ret = %s( $_POST["%s"] );',
                                          (string)
$campo['validation'],
                                          (string)
$campo['name']
                                         );

                        // Suponto que estamos validando o campo 'nome', que
                        // da maneira como está descrito no xml do tutorial,
                        // teremos $codigo valendo algo como:
                        // $ret = validator::isFilled( $_POST["nome"] );
                        // Executa-se o código de validação agora. A variavel
                        // $ret ira conter o resultado da validacao.
                        
eval( $codigo );

                        // Caso $ret seja diferente de true, estou assumindo
                        // que o retorno é entao uma mensagem de erro
                        
if( $ret === true ) {
                            
$this->validacao[(string)$campo['name']] = true;
                        } else {
                            
$this->error true;
                            
$this->validacao[(string)$campo['name']] = $ret;
                        }
                    }
                }
            }
        }
    }
}

?>

Com esse código em mãos, precisamos também ter a classe que faz validação do conteúdo digitado nos campos. Como foi denifido no xml, a classe que estamos usando é a classe Validator. A que irei apresentar, faz validações hipóteticas, não sendo recomendado o uso delas, da forma que estão. Veja o código:

validator.class.php


<?php

class Validator {

    // Método que verifica se há algum valor em $valor
    
public static function isFilled$valor ) {
        if( empty( 
$valor ) )
            return 
'Campo nao pode ser vazio';

        return true;
    }

    // Metodo que iria validaro valor, para saber se este
    // eh um cpf valido
    
public static function isCpf$valor ) {
        if( 
$valor == '11111111111' )
            return 
'CPF invalido';

        return true;
    }

    // Metodo que verificaria se a data informada
    // eh valida
    
public static function isData$valor ) {
        
$data explode('/',$valor);
        if( 
sizeof$data ) != )
            return 
'Data invalida';

        return true;
    }

}

?>

Já está quase tudo pronto, agora basta adicionarmos o código em nosso index.php, que fará a validação dos campos. Lembra-se daquele nosso primeiro index.php não é mesmo? Ele deve ficar assim agora:

index.php


<?php

include_once('validator.class.php');
include_once(
'action.class.php');
$action = new Action( );
$action->run( );

if( $action->getError( ) === true ) {
    
$camposInvalidos $action->getValidacao( );
    foreach( 
$camposInvalidos as $campo=>$e ) {
        if( 
$e !== true )
            
printf('Erro: campo %s - %s <br>'$campo$e ); 
    }
}

?>

<form method="POST">
    <input type="text" name="nome" /><br />
    <input type="text" name="cpf" /><br />
    <input type="text" name="data" /><br />
    <!-- agora vem o botão de submit, que identificará a ação que ocorre -->
    <input type="submit" name="acao" value="Insert" />
</form>

Nestes exemplos, eu levei em conta todos os arquivos estão em um só diretório, como pode ser observado pelos include_once que faço no início do script.

Esclarecendo tudo então:

  • O arquivo xml é o responsável por descrever a validação
  • A propriedade validation contém o nome da classe e do método, como se fossem uma chamada estática Classe::metodo
  • A propriedade when define em quais acoes o campo deve ser validado, e essa ações são separadas por ‘,’
  • A propriedade name define o nome do cmapo que está sendo validado

Bom, é isso!
Como de costume, os arquivos para visualização do código seguem abaixo, pois o wordpress é tosco, e zoa todo o código, para copiar e colar.
Qualquer dúvida/comentário/sugestão/elogio/doações, não deixe de contatar-me : )

[]s

Index.php
Action.class.php
Validator.class.php
Validador.xml





espeak-php / SSML

22 03 2007

Mexendo na extensão hoje acabei por testar o uso de SSML . Interessante:


<?php
// ssml.php
$xml =<<<eoc
<speak version=”1.0″ xmlns=”http://www.w3.org/2001/10/synthesis&#8221;
    xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance&#8221;
    xsi:schemaLocation=”http://www.w3.org/TR/speech-synthesis/synthesis.xsd&#8221;
    xml:lang=”en-US”>

    <voice gender=”female” age=”22″>
        <p>Hello world! </p>
    </voice>
                                                  
    <voice gender=”male” age=”30″>
        <p>Hello world!</p>
    </voice>
    <voice xml:lang=”pt” gender=”male”>
        <p>Olá mundo!</p>
    </voice>
</speak>
eoc;

dl(‘espeak.so’);

espeak_initialize(ESPEAK_AUDIO_OUTPUT_PLAYBACK0);
espeak_SetVoiceByName(“en”);
espeak_synth($xmlstrlen($xml), 0ESPEAK_POS_CHARACTER0ESPEAK_SSML0);
espeak_synchronize();
espeak_terminate();

As vozes não são as mais bonitas do mundo, mas também não são as piores. Acho que nos próximos dias consigo implementar todas as funções disponibilizadas pela lib do espeak. Está no svn do projeto.





Notícias e links: 21/03

21 03 2007

CSS+Javascript power. Fancy menu
Não é PHP, mas vai dizer que nunca precisou de um menu pra alguma aplicação ? Este menu é bem estiloso.

What separates a professional PHP web developer from a scripter?

Quebec Slides
Slides de duas apresentações: Securing PHP Applications e Migrating to PHP 5.2.1
O primeiro contém dezenas de dicas de como aumentar a segurança de uma aplicação em PHP e a segunda fornece diversos motivos para se migrar para php 5.2. Vale o tempo investido.

Object Interaction and Mediator Classes in PHP 5
Abstracting Database Access Using Polymorphism with Objects in PHP 5
Mais artigos sobre design patterns do devshed. O interessante nestes artigos (a grande maioria ) é que realmente falam sobre o pattern e onde / como utilizar, o que faz com que eles sejam úteis não somente enquanto se desenvolve em PHP, mas em qualquer linguagem.

CodeIgniter vs. CakePHP
Comparativo entre CodeIgniter e CakePHP. Não da pra tirar muitas conclusões sobre qual é o melhor ( se é que algum é melhor que outro, no geral ), mas é possível conhecer algumas features de cada um deles.

XML for PHP developers, Part 3: Advanced techniques to read, manipulate, and write XML
Terceira parte do artigo sobre XML para desenvolvedores PHP. Não lembro se postei a segunda, então segue ( e a primeira também:
XML for PHP developers, Part 2: Advanced XML parsing techniques
XML for PHP developers, Part 1: The 15-minute PHP-with-XML starter

Command-line PHP? Yes, you can!
Breve introdução ao uso de PHP em linha de comando. É, muita gente utiliza PHP apenas como uma linguagem voltada à web, embora muitos já a considerem (eu estou entre estes muitos) uma linguagem de uso geral.
PHP em console + ncurses é bastante simples e interessante de se usar:

r2s

Tão eficiente quanto uma interface web : )





php-dev

21 03 2007

Na lista de discussão php-dev sempre há mensagens interessantes.

Nesta última semana vem sendo discutido um projeto para o GSoC , o dbobj. Trata-se de uma (não é apenas mais uma ) implementação nativa (isso é, uma extensão para PHP, e não escrito em PHP ) de ORM. Foi descrito com maiores detalhes em um email que pode ser visto no histórico da lista.

Poderia ser bastante interessante se “pegasse”, criaria uma certa padronização na forma de acesso a dados. Mas é bem provável que quem já utiliza algum framework para isso não o abandonaria. Enfim, não ha nada a perder com isso. O projeto phpaspect também “nasceu” no GSoC (outra “edição”). Deve dar bons frutos também.

Um outro assunto que vem sendo discutido ( e muito discutido ) é a implementação de funções anônimas em PHP. Um patch foi enviado e demonstrava o funcionamento desta implementação ( por sinal, o código foi esse:

$data = array(“zoo”, “orange”, “car”, “lemon”, “apple”);
usort($data, function($a, $b) { return strcmp($a, $b); });

)

Entre outras coisas, foi comentado também sobre uma possível implementação de closures em PHP. Nunca precisei, nem de funções anônimas, mas sei lá, vai que um dia eu precise : )

Então fica a dica, a lista pode ser assinada por qualquer um. Apenas se prepare para receber muitas mensagens diariamente.





Dica rápida: Verificar protótipos de funções PHP rapidamente

19 03 2007

Tenho plena certeza que não sou o único que sempre tem dúvidas com a ordem de determinadas funções em php, principalmente as funções de manipulação de array e de strings. A culpa não é minha, não há um padrão naquilo. E isso é uma das poucas coisas que me “irritam” enquanto estou desenvolvendo.

Quando tenho alguma dúvida ( várias vezes por dia, tenho uma “excelente” memória ) costumo consultar a documentação em php.net, seguido pelo nome da função:

http://php.net/array_search, http://php.net/substr, e por ai vai…

Até tenho documentação instalada localmente, mas é bastante chato ficar procurando. É mais prático olhar direto no site.

Mas hoje, tive a brilhante idéia de começar a utilizar o próprio php ( cli ) pra exibir o protótipo das funções, que me poupa algum tempo e achei bastante útil. Acho que pode ser útil para quem tem esse mesmo problema que eu. Veja a simplicidade:

$ php –rf substr
Function [ public function substr ] {

– Parameters [3] {
Parameter #0 [ $str ]
Parameter #1 [ $start ]
Parameter #2 [ $length ]
}
}

$ php –rf array_search
Function [ public function array_search ] {

– Parameters [3] {
Parameter #0 [ $needle ]
Parameter #1 [ $haystack ]
Parameter #2 [ $strict ]
}
}

$ php –rf array_key_exists
Function [ public function array_key_exists ] {

– Parameters [2] {
Parameter #0 [ $key ]
Parameter #1 [ $search ]
}
}

Muito bom!!! Espero encontrar mais alguma utilidade nisso : D





Notícias e links – 06/03

16 03 2007

Bastante ocupado ultimamente … :|

Using Zend Framework components in Code Igniter
Dica de como utilizar componentes do ZF no CI. Sei lá, vai que alguém precise

Zend Certification: Self Test
Pensando em se certifar como ZCE ? Que tal um teste antes ?
Oito questões, com algumas “pegadinhas”

Introducing Mediator Classes in PHP 5
Working with Strings and the Composite Pattern in PHP 5
Mais dois artigos da série de design patterns em PHP

Nine examples on how NOT to hire a PHP developer
Fica a dica para quem eventualmente tiver que contratar um programador ( não somente PHP )

Tutorial: Getting Started with the Zend Framework
Pequeno tutorial (19 páginas) com um introdução ao Zend Framework. Nunca usou um framework ? Que tal começar com a usar com ajuda deste tutorial.

Continuous integration with PHP
Breve introdução sobre integração contínua durante o desenvolvimento em PHP, com algumas dicas sobre PHPUnit e Phing.

Simulando Sobrecarga de Métodos no PHP
http://www.imasters.com.br/artigo/5350/php/simulando_sobrecarga_de_metodos_no_php/

Quercus
PHP in GlassFish, first steps
MediaWiki on GlassFish — via Quercus
Caucho Resin adds PHP
Nos últimos dias muito tem se falado sobre integração PHP / Java, ganho de performance e blablabla…

Would PHP benefit from JIT compilation?