Archive for julho, 2010

26 de julho de 2010

PHPUnit no CodeIgniter com CIUnit

por adlerparnas

Fala Pessoal!

Meu nome é Adler Parnas e hoje vou falar da instalação do PHPUnit no CodeIgniter utilizando a biblioteca CIUnit. Não tenho o objetivo de explicar o funcionamento nem a utilização do CodeIgniter nem o PHPUnit.

O PHPUnit é um Framework para automatização de testes unitários,  muito utilizado para Desenvolvimento Baseado em Testes. O CIUnit é uma série de códigos em PHP para a integrar o PHPUnit ao CodeIgniter para que você possa realizar testes de seus Models, Controllers e Helpers de uma maneira bem mais fácil.

A instalação do PHPUnit pode ser feita através do PEAR. Para quem não possui o PEAR intalado basta seguir o tutorial no site oficial da PEAR, pra quem usar WAMP + Windows 7 pode ler esta explicação que escrevi.

O CIUnit pode ser baixado no site do oficial do projeto que possui um tutorial muito fácil de ser acompanhado. Apesar de seguir os passos como é dito no site oficial, tive problemas ao executar os teste. Fuçando nos códigos do CIUnit e nas mensagens de erros geradas, descobri que o mapeamento do CIUnit para a pasta de bibliotecas do CodeIgniter está errado.

No arquivo: system\application\libraries\fooStack\fooBase\index.php:


// existe a seguinte atribuição
$application_folder = "../../application";

// o correto seria
$application_folder = "/application";

Um outro arquivo com problemas é o \system\application\tests\CIUnit.php que possui um código comentado que deve ser descomentado:

########################################
# descomente estas linha abaixpo         #
########################################

// $CI->load->library('fooStack/Spyc');
// CIUnit::$spyc = &$CI->spyc;
$CI->load->library('fooStack/Fixture');
CIUnit::$fixture = &$CI->fixture;

É isso ai pessoal! Espero que esta dica seja útil a vocês e caso tenha dito algo errado me corrijam.

26 de julho de 2010

Instalando PEAR no WAMP sobre o windows 7

por adlerparnas

Fala Pessoal!

Meu nome é Adler Parnas e hoje vou falar do da instalação do PEAR no WAMP sobre o Windows 7. Não tenho como objetivo explicar o que é o PEAR nem a instalação do WAMP.

No WAMP 2.0 existe o arquivo C:\wamp\bin\php\php5.3.0\go-pear.bat que é um script para a instalação do PEAR. Entrei no console, fui para a pasta especificada e  executei o arquivo go-pear.bat e encontrei o seguinte erro:


phar "C:\wamp\bin\php\php5.3.0\PEAR\go-pear.phar" does not have a signaturePHP Warning:  require_once(phar://go-pear.phar/index.php): failed to open stream: phar error: invalid url or non-existent phar "phar://go-pear.phar/index.php" in C:\wamp\bin\php\php5.3.0\PEAR\go-pear.phar on line 1236

Warning: require_once(phar://go-pear.phar/index.php): failed to open stream: phar error: invalid url or non-existent phar "phar://go-pear.phar/index.php" in C:\wamp\bin\php\php5.3.0\PEAR\go-pear.phar on line 1236
Pressione qualquer tecla para continuar. . .

C:\wamp\bin\php\php5.3.0>

No meu caso, a pasta de binários do PHP não estava na variável de ambiente PATH do meu usuário, então quando o script era executado ele não reconhecia o comando php.exe.
A solução que tomei foi editar o arquivo go-pear.bat adicionar um comando que levasse o script a pasta de binários do php:

@ECHO OFF
# esta linha foi adicionada
cd C:\wamp\bin\php\php5.3.0
set PHP_BIN=php.exe
%PHP_BIN% -d output_buffering=0 PEAR\go-pear.phar
pause

Quando executei o script pela segunda vez, encontrei o mesmo erro, o que me levou a desconfiar das permissões do meu usuário para executar o script. Então abri o console como administrador e executei o arquivo novamente e tchan!, o mesmo erro aconteceu! Resolvi então copiar e executar o comando que estava no script e ainda sim o mesmo erro ocorria!

Perguntando ao pai dos burros, ele me informou um link para o blog phphints onde existe este comando milagroso:

> cd C:\wamp\bin\php\php5.3.0
> php -d phar.require_hash=0 PEAR/go-pear.phar

Após informar o local onde o PEAR seria instalado, bastou colocar o diretório dos binários do PEAR na variável de ambiente PATH do meu usuário e tudo funcionando.

É isso ai pessoal! Espero que esta dica seja útil a todos os programadores PHP Windows e caso tenha dito algo errado me corrijam!

22 de julho de 2010

Insert e Update na mesma query

por adlerparnas

Fala pessoal!

Meu nome é Adler Parnas, e estou aqui para falar de uma técnica de tratamento de exceção no MySQL.

Quantas vezes escrevemos códigos nas nossas classes Model para tratar de uma inserção ou atualização. Normalmente faço algo dessa forma:


class Meu_Model{

    public function save($item){

        if($item['id']){
            // update
        } else {
            // insert
        }
    }
}

Um grande recurso que descobri através de meu chefe Dino, é o tratamento de exceções para chaves duplicadas no MySQL.

INSERT INTO minha_tabela VALUES (meu_valor1, meu_valor2, meu_valor3)
       ON DUPLICATE KEY campo2=meu_valor2, campo3=meu_valor3

O que o MySQL faz, e acredito que outros SGDB‘s também fazem, é tentar o INSERT e caso ocorra uma exceção por chave duplicada ele faz um UPDATE dos campos listados na cláusula ON DUPLICATE KEY.

Reconheço que e este recurso não pode ser utilizado em todos os casos, mas é uma mão na roda para uma boa parte deles :D.

É isso ao pessoal! Espero que esta dica seja útil pra vocês como foi pra mim, e caso tenha dito algo errado, por favor me corrijam.

Fonte: http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html

14 de julho de 2010

Nunca mais você vai usar as variáveis $_GET e $_POST

por adlerparnas

Olá! Pessoal!

Meu nome é Adler Parnas e hoje vou falar de um técnica para acessar, validar e filtrar dados das variáveis $_POST e $_GET no PHP.

Caminhando na minha jornada rumo a Certificação PHP, me deparei com um artigo na PHP Architect, que exemplificava a utilização das funções filter_input e filter_input_array. Tais funções foram inseridas no PHP a partir da versão 5.2 e são uma ótima forma para tratar dados das variáveis $_GET e $_POST deixando seu código mais legível e seguro.

Como é falado no artigo original, é incrível a quantidade de sites/sistemas em PHP com falhas de segurança por  não tratar a entrada de dados pelo usuário. Existe também o tempo gasto para escrever códigos de tratamento dos dados de entrada.

Veja como seu código fica mais limpo e claro utilizando a função filter_input para tratar um parâmetro via GET:


<?php

$user_name = filter_input(INPUT_GET, 'user_name', FILTER_SANATIZE_STRING);

?>

Na página de documentação do PHP, também existe um exemplo utilizando a função filter_input_array, onde é criado um array com as opções de validação do POST esperado pelo programa.

<?php
error_reporting(E_ALL | E_STRICT);

/* data actually came from POST
$_POST = array(
   'product_id'    => 'libgd<script>',
   'component'   => '10',
   'versions'       => '2.0.33',
   'testscalar'    => array('2', '23', '10', '12'),
   'testarray'     => '2',
);
*/
/**
 * Arry com as opções de validação
 */
$args = array(
   'product_id'     => FILTER_SANITIZE_ENCODED,
    'component'   => array(
                                    'filter'    => FILTER_VALIDATE_INT,
                                    'flags'     => FILTER_REQUIRE_ARRAY,
                                    'options'   => array('min_range' => 1, 'max_range' => 10)
    ),
    'versions'     => FILTER_SANITIZE_ENCODED,
    'doesnotexist' => FILTER_VALIDATE_INT,
    'testscalar'   => array(
                                    'filter' => FILTER_VALIDATE_INT,
                                    'flags'  => FILTER_REQUIRE_SCALAR,
    ),
    'testarray'    => array(
                                    'filter' => FILTER_VALIDATE_INT,
                                    'flags'  => FILTER_REQUIRE_ARRAY,
    )
);

$myinputs = filter_input_array(INPUT_POST, $args);

var_dump($myinputs);
?>

O resultado deste tratamento seria:

array
   'product_id'     => string 'libgd%3Cscript%3E' (length=17)
   'component'    => boolean false
   'versions'        => string '2.0.33' (length=6)
   'doesnotexist'  => null
   'testscalar'     => boolean false
   'testarray'      => boolean false

Existem vários tipos de filtros que podem ser utilizados, sendo eles divididos em “dois grupos”, SANATIZE e VALIDATE. Os filtros dos tipo SANATIZE limpam os dados da variável, já os filtros do tipo VALIDATE, retornam FALSE caso o dados não passe pelo filtro.

As funções filter_input e filter_input_array não tratam todos os tipos de dados e nem vão deixar seu programa 100% seguro, mas já é uma boa parte da segurança realizada de forma elegante.

É isso ai galera! Espero que essa dica seja útil a todos vocês e caso tenha dito algo errado, favor me corrijam.

Fontes:

13 de julho de 2010

Javascript Orientado a Objetos

por adlerparnas

Olá! Pessoal!

Meu nome é Adler Parnas, e hoje vou falar de uma técnica que utilizo para escrever o Javascript dos meus projetos. Imagino que todos já conheçam a biblioteca Javascript jQuery e entendam Programação Orientada a Objetos, pelo  menos um pouco.

Já vimos inúmeras demonstrações que a utilização de cache, quando se utiliza jQuery, é muito eficiente por diminuir a chamada da função seletora $(). Sim, fazer cache daquele campo no HTML onde você atualiza os twittes no seu blog é perfeito, afinal de contas, a cada 10, 20, 30 segundos você  altera o texto que está lá!

Agora me responda uma coisa! Do quê adianta eu fazer cache de elementos, se em tal página eles nem existem ou não são tão utilizados assim? Uma forma de tratar isso seria criar um arquivo Javascript apenas para essa página, ou até mesmo colocar o Javascript direto no HTML (haarrrr), podendo gerar muitas linhas de códigos repetidos. Uma forma que gosto de tratar isso é criando objetos para cada “página” do meu site/sistema, assim realizo cache e executo somente o que é necessário.

Vamos dizer que temos uma página de cadastro, onde o Javascript é necessário apenas para validação dos campos e talvez algumas requisições AJAX.  Da forma que eu utilizo seria algo parecido com isso:

var cadastro = {
    _$txt_email:null,
    _$txt_password:null,
    initialize:
       function(){
          /*
           * aqui vem o código que será executado no onload da página
           */
       } // fim da funcao initialize
} // fim do objeto cadastro

Para fazer com que cada função initialize seja executada no objeto correto, utilizo uma classe na tag body, que me ajuda no CSS e informa para o Javascript qual página está sendo renderizada.


<!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" xml:lang="en">
<head>
    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
    <title>Pàgina de Cadastro</title>
</head>
<body class="cadastro">
  <form action="">
     <fieldset>
         <label for="txt_name">Nome <em>*</em></label>
         <input type="text" name="txt_name" id="txt_name" />
     </fieldset>
     <fieldset>
         <label for="txt_email">Email <em>*</em></label>
         <input type="text" name="txt_email" id="txt_email" />
     </fieldset>
     <fieldset>
         <label for="txt_password">Senha <em>*</em></label>
         <input type="text" name="txt_password" id="txt_password" />
     </fieldset>
     <fieldset>
         <label for="txt_password_2">Confirmar senha <em>*</em></label>
         <input type="text" name="txt_password_2" id="txt_password_2" />
     </fieldset>
     <fieldset><input type="submit" value="Enviar" /></fieldset>
  </form>
  <!-- Javascript include -->
  <script type="text/javascript" src="script.js"></script>
  <!-- end Javascript include -->
</body>
</html>

Para que o objeto certo seja executado escrevo meu código Javascript dessa forma:

/**
 * Variável para fazer cache do elemento body
 */
var $_body;

var home = {
   initialize:
      function(){
          /*
           * Código executado no on-load da página
           */
      }
}

var cadastro = {
   _$txt_email:null,
   _$txt_password:null,
   initialize:
      function(){
          /*
          * Código executado no on-load da página
          */

          // realizando cache dos elementos importantes para essa página
          this._$txt_email = $("#txt_email");
          this._$txt_password = $("#txt_password");

          this._$txt_email.change(cadastro.valida_email);
      },
   valida_email:
      function (event){
         // validação de email
      },
}

var login = {
   initialize:
      function(){
           /*
            * Código executado no on-load da página
            */
            $('#txt_email').change(cadastro.valida_email);
      }
}

$(
   function(){
      try{
         // realizando cache do elemento body
         $_body = $('body');
         // recuperando o classe do elemento body e chamando o
         // método initialize do objeto responsável
         eval($_body.attr('class')+".initialize()");
      } catch(){
         // coloquei detro do tray-catch pq se o objeto não existir
         // o javascript não gerará um erro (padrão silenciator hehhe).
      }
   }
);

Não sei dizer ao certo, se essa é ou não a melhor forma de escrever o código Javascript, sei que dessa forma facilita muito a reutilização de código, na manutenção e na performance, pois não fico executando comandos de outras páginas.

É isso ai pessoal! Espero que esta dica seja útil para todos e caso tenha tido algo errado, favor me corrijam! Até o próximo post!