Indução de tipos com PHP - Utilizando a Spl_Types para tipagem forte

Esse artigo é continuação de como tornar seus scripts fortemente tipados com php. A primeira e segunda parte você pode ler aqui: Indução de tipos com PHP – O Básico, Indução de tipos com PHP – Instalando o Spl_Types


Como já vimos nos últimos dois artigos, o PHP por padrão tem é relaxado em relação aos seus tipos, o que tem suas vantagens e desvantagens. Como nosso objetivo é tornar nosso script fortemente tipado, iremos utilizar a extenso Spl_Types para fazer esse trabalho. A extensão possui cinco classes para trabalhar com os tipos, são eles:

  • SplString – Induz o tipo string.
  • SplInt – Induz o tipo inteiro.
  • SplBool – Induz o tipo booleano.
  • SplFloat – Induz o tipo ponto flutuante.
  • SplEnum – Induz o tipo enumerável.

Vamos construir nosso script principal e fazer alguns testes para certificar que a extensão funciona como esperado. Vamos por partes, e no final teremos uma classe completona!

Primeiro vamos nomear nossa classe e criar nosso método construtor e inicializar todas as variáveis que utilizaremos na classe.

class Basket {

  private $id_cart;
  private $items = array();
  private $lock_cart;

  public function __construct()
  {
    $this->id_cart = uniqid();
    $this->lock_cart = new SplBool;
    $this->items = new ArrayObject;
  }
}

Como esse artigo é meramente didático, não entrarei em assuntos como por que isei a uniqid() para gerar um id para meu carrinho de compras. Você sabe! É só didática.

Com propriedade lock_cart já começamos com nossa mágica de tipagem forte. Iniciaremos com a explicação do SplBool.

Como você já deve imaginar, a classe SplBool é usada para forçar que essa variável ao tipo booleano, então se tentarmos passar qualquer outro valor para essa variável teremos alguma exceção, que veremos daqui há pouco, quando terminarmos nossa classe. Uma outra propriedade que setamos em nosso construtor foi items, que foi preenchida com uma instância da classe ArrayObject. A classe é poderosa, mais uma Spl, feita inteiramente para se trabalhar com arrays. Para saber mais, dê uma lida na documentação da classe. É incrível o que se pode fazer com ela em associação das outras Spls, como a ArrayIterator. Agora vamos adicionar um método para adicionar items ao nosso carritnho de compras.

class Basket {

  private $id_cart;
  private $items = array();
  private $lock_cart;

  public function __construct()
  {
    $this->id_cart = uniqid();
    $this->lock_cart = new SplBool;
    $this->items = new ArrayObject;
  }

  public function editItemPrice(SplInt $index, SplFloat $price) 
  {
    $this->items
     ->offsetGet( (int) $index)
     ->offsetset('price', $price);
  }
}

Nesse vamos apresentar mais duas classes de indução de tipo, são elas SplFloat e SplString. A SplFloat cuida de pontos flutuantes que usaremos para especificar o preço de nosso produto e usaremos também a SplString, para espefificar o nome do nosso produto.

Aqui fazemos duas verificações! A primeira que estamos fazendo sem saber é a verificação de Instância da classe, se é da SplFloat e SplString. E a segunda que estamos fazendo conscientemente é a que estamos vamos explicar aqui, a tipagem forte! Veja que o parâmetro price deve ser da instância SplFloat e sendo assim ser um float, e também nosso parâmetro name, que deve ser instância SplString e assim sendo obrigatoriamente uma string. Os conceitos podem estar meio confusos aqui, mas quando começarmos a usar a classe você entenderá com mais claridade. Fique tranquilo!

Agora que temos como adicionar novos itens ao nosso carrinho. Vamos adicionar a possibilidade de editar e remover itens.

class Basket {

  private $id_cart;
  private $items = array();
  private $lock_cart;

  public function __construct()
  {
    $this->id_cart = uniqid();
    $this->lock_cart = new SplBool;
    $this->items = new ArrayObject;
  }

  public function editItemPrice(SplInt $index, SplFloat $price) 
  {
    $this->items
     ->offsetGet( (int) $index)
     ->offsetset('price', $price);
  }

  public function editItemPrice(SplInt $index, SplFloat $price) 
  {
    $this->items
      ->offsetGet( (int) $index)
      ->offsetset('price', $price);
  }

  public function editItemName(SplInt $index, SplString $name)
  {
    $this->items
      ->offsetGet( (int) $index)
      ->offsetset('name', $name);
  }

  public function delItem(SplInt $index)
  {
    $this->items
      ->offsetUnset( (int) $index);
  }
}

Nos dois métodos utilizamos os já conhecidos SplFloat e SplString, e introduzimos mais uma classe a SplInt. Como você já deve ter presumido até agora, ela força o tipo Inteiro em alguma variável. Mais uma vez fazemos uma checagem dupla. Checamos primeiro se pertence a uma instância da SplInt e ainda se é um inteiro.

Agora vamos implementar a possibilidade de dar um lock em nosso carrinho para podermos fechar nossa compra!

class Basket {

  private $id_cart;
  private $items = array();
  private $lock_cart;

  public function __construct()
  {
    $this->id_cart = uniqid();
    $this->lock_cart = new SplBool;
    $this->items = new ArrayObject;
  }

  public function editItemPrice(SplInt $index, SplFloat $price) 
  {
    $this->items
     ->offsetGet( (int) $index)
     ->offsetset('price', $price);
  }

  public function editItemPrice(SplInt $index, SplFloat $price) 
  {
    $this->items
      ->offsetGet( (int) $index)
      ->offsetset('price', $price);
  }

  public function editItemName(SplInt $index, SplString $name)
  {
    $this->items
      ->offsetGet( (int) $index)
      ->offsetset('name', $name);
  }

  public function delItem(SplInt $index)
  {
    $this->items
      ->offsetUnset( (int) $index);
  }

  public function lockCart(SplBool $bool)
  {
     $this->lock_cart = $bool;
  }
}

Vamos agora implementar nosso último tipo de indução de tipo com a SplEnum. Para isso, além de criar o método que irá setar o tipo de nosso carrinho de compras, precisamos criar também a classe que iremos setar os nossos tipos de carrinho.

class Basket {

  private $id_cart;
  private $items = array();
  private $lock_cart;

  public function __construct()
  {
    $this->id_cart = uniqid();
    $this->lock_cart = new SplBool;
    $this->items = new ArrayObject;
  }

  public function editItemPrice(SplInt $index, SplFloat $price) 
  {
    $this->items
     ->offsetGet( (int) $index)
     ->offsetset('price', $price);
  }

  public function editItemPrice(SplInt $index, SplFloat $price) 
  {
    $this->items
      ->offsetGet( (int) $index)
      ->offsetset('price', $price);
  }

  public function editItemName(SplInt $index, SplString $name)
  {
    $this->items
      ->offsetGet( (int) $index)
      ->offsetset('name', $name);
  }

  public function delItem(SplInt $index)
  {
    $this->items
      ->offsetUnset( (int) $index);
  }

  public function lockCart(SplBool $bool)
  {
     $this->lock_cart = $bool;
  }

  public function setCartType(SplInt $type)
  {
    $this->cart_type = new CartType(CartType::ESPECIAL);
  }
}

class CartType extends SplEnum {
    const __default = self::NODEFINED;

    const NODEFINED = 0;
    const NORMAL = 1;
    const ESPECIAL = 2;
}

Pronto, agora temos um exemplo prático para testarmos todos os nossos conceitos até agora! Usamos a SplBool para setarmos se o nosso carrinho está ou não ‘lockado’(estrangeirismo feio). Vamos testar!

Vamos começar criando uma instância de nosso carrinho e adicionando dois itens.

$basket = new Basket();
$basket->addItem(new SplFloat(9.99), new SplString('Bola'));
$basket->addItem(new SplFloat(14.99), new SplString('Carrinho'));

Nosso objeto está assim até então:

Basket Object
(
    [id_cart:Basket:private] => 4f3aa8521d98a
    [items:Basket:private] => ArrayObject Object
        (
            [storage:ArrayObject:private] => Array
                (
                    [0] => ArrayObject Object
                        (
                            [storage:ArrayObject:private] => Array
                                (
                                    [price] => SplFloat Object
                                        (
                                            [__default] => 9.99
                                        )

                                    [name] => SplString Object
                                        (
                                            [__default] => Bola
                                        )

                                )

                        )

                    [1] => ArrayObject Object
                        (
                            [storage:ArrayObject:private] => Array
                                (
                                    [price] => SplFloat Object
                                        (
                                            [__default] => 14.99
                                        )

                                    [name] => SplString Object
                                        (
                                            [__default] => Carrinho
                                        )

                                )

                        )

                )

        )

    [lock_cart:Basket:private] => SplBool Object
        (
            [__default] => 
        )

)

Vamos fazer nosso primeiro teste para saber se tudo está funcionando como deveria funcionar mesmo! As checagens de instâncias e tipos, ou seja, vamos induzir um erro aqui…

$basket->addItem(new SplFloat(50.44), new SplString(15));
$basket->addItem(new SplFloat('17.99'), new SplString('moto'));
$basket->addItem(new SplString('Barco'), new SplFloat(17.99));
$basket->setCartType(new CartType(CartType::OUTRO));

Aqui induzimos quatro erros completamente diferentes.

O primeiro erro, onde nós deveríamos ter passado uma string para a SplString, passamos um inteiro.

/*Fatal error: Uncaught exception 'UnexpectedValueException' with message 'Value not a string'*/

No segundo erro, passamos uma string para a SplFloat, enquanto deveriamos ter passado um float.

/*Fatal error: Uncaught exception 'UnexpectedValueException' with message 'Value not a float'*/

No terceiro, invertemos tudo, passamos os valores corretos, mas em ordens erradas. Passamos primeiro uma string e depois um float, enquanto o que se espera é o contrário, um float e depois uma string.

/*Catchable fatal error: Argument 1 passed to Basket::addItem() must be an instance of SplFloat, instance of SplString given'*/

Já no quarto, induzimos uma constante que não existe na classe CartType.

/*Value not a const in enum CartType*/

Apenas para ver que tudo está funcionando como o esperado, o código abaixo edita nossos itens, deleta e ‘locka’ nosso carrinho.

$basket->editItemPrice(new SplInt(1), new SplFloat(12.45));
$basket->editItemName(new SplInt(1), new SplString('Helicoptero'));
$basket->delItem(new SplInt(1));
$basket->lockCart(new SplBool(true));

Nosso objeto final vai se parecer com isso:

Basket Object
(
    [id_cart:Basket:private] => 4f3ab574309a2
    [items:Basket:private] => ArrayObject Object
        (
            [storage:ArrayObject:private] => Array
                (
                    [0] => ArrayObject Object
                        (    
                            [storage:ArrayObject:private] => Array
                                (
                                    [price] => SplFloat Object
                                        (
                                            [__default] => 9.99
                                        )

                                    [name] => SplString Object
                                        (
                                            [__default] => Bola
                                        )

                                )

                        )

                )

        )

    [lock_cart:Basket:private] => SplBool Object
        (
            [__default] => 1
        )

)

Indução de tipos com PHP - Instalando o Spl_Types

Esse artigo é continuação de como tornar seus scripts fortemente tipados com php. A primeira parte você pode ler aqui: Indução de tipos com PHP


Nesta segunda parte do artigo vamos demonstrar para aqueles haters que já discutimos, como tornar o PHP melhor do que já é.

Já tem algum tempo que temos como tornar nossos scripts fortemente tipados com php, porém, isso não vem como padrão. Para tal necessitaremos de uma extensão, a SPL_Types. Na documentação da extensão temos a sua descrição que não poderia ser melhor, ela ajuda a tornar seus scripts a serem fortemente tipados.

Como já vimos na primeira parte desse artigo, o php nos oferece duas opções por padrão de indução de tipos, são eles arrays e instâncias. Com essa extensão ganhamos todas as outras que queríamos Strings, Inteiros, Booleanos, Pontos Flutuantes e Enumeráveis. Antes de continuarmos é preciso saber uma coisa. Até o momento que escrevia esse artigo a extensão estava marcada como experimental no repositório PECL, então não se assuste se acontecer algum bug, apesar de ter testado a extensão ad nauseam, nunca se sabe.

Como ela é uma extensão PECL, precisaremos fazer a instalação em nossa máquina. Primeiramente tentei recorrer ao pacote pecl para instalar, mas tive um problema, e depois de ver que há sim diferença entre o que é liberado por quem cuida da extensão e a versão estável disponível na página do pacote, resolvi fazer tudo passo a passo. O erro que consegui fazendo do jeito fácil foi o abaixo:

!#shell
$  pecl install SPL_Types
...
/tmp/pear/temp/SPL_Types/spl_type.c:405:1: error: duplicate 'static'
/tmp/pear/temp/SPL_Types/spl_type.c:415:1: error: duplicate 'static'
make: ** [spl_type.lo] Erro 1
ERROR: `make' faile

Então fui para a versão difícil da instalação do pacote. Os próximos passos consistem em fazer o que o comando acima fez, só que de outra fonte. Primeiramente vamos buscar os arquivos do pacote em seu repositório oficial. Aqui, todas as ações que faço costumo fazer dentro do diretório /tmp, mas fique tranquilo para fazer onde quiser. Nosso próximo passo exige um pacote específico o subversion, use o comando abaixo para instalar.

sudo apt-get install subversion

Agora que já temos o subversion instalado, vamos buscar os arquivos do pacote.

$ cd /tmp
$ svn co https://svn.php.net/repository/pecl/spl_types/trunk/ spltypes
$ cd spltypes

Com os arquivos necessários dentro do diretório spltypes, o nosso próximo passo é transformá-lo em uma versão compilável e instalável. A ferramenta phpize faz isso para nós, ele está dentro do pacote php5-dev no ubuntu, vamos instalar com o comando abaixo.

sudo apt-get install php5-dev

Após instalar o pacote, o nosso próximo passo é utilizar o phpize na pasta spltypes, como abaixo:

$ phpize
...
Configuring for:
PHP Api Version:         20090626
Zend Module Api No:      20090626
Zend Extension Api No:   220090626

Agora com nossa extensão para ser instalada, vamos configurar, compilar e instalar com os comando abaixos:

$ ./configure
...(aguardar)
$ make
...(aguardar)
$ make install
...(aguardar)

Após isso, nosso último passo é habilitar a extensão. Para tal, vamos criar um arquivo de configuração para a extensão com o comando abaixo

$ sudo echo 'extension=spl_types.so' > /etc/php5/conf.d/spltypes.ini

Reinicie seu apache e veja em seu phpinfo() se a nova extensão foi carregada. Para fazer isso de uma forma rápida pelo terminal, utilize o comando abaixo:

$ php -m | grep -i spl
...
SPL
SPL_Types

No próximo parte e final desse artigo, vou falar como usar essa extensão a seu favor! See Ya!

Indução de tipos com PHP - O básico

Existe todo um preconceito em relação ao PHP ser relaxado com seus tipos. A questão é que esses haters se apegaram tanto a essa questão que já foi resolvida há algum tempo e não consegue largar. É como dizem: se você começa a afirmar uma coisa com certa frequência, você acaba acreditando sem retorno por aquele conceito e não há nada que o fará mudar de ideia. Mas não posso julgá-los, ainda em PHP existem pessoas usando getters e setters, enquanto há algum tempo temos ferramentas de sobrecarga e você acaba com a arquitetura de encapsulamento de seus valores. Ooops, isso também acontece em outras linguagens. My bad. Enfim, esquecendo a questão filosófica envolvida nesse assunto, vamos explicar como induzir tipos a seus objetos!

Mas o que é indução de tipo e por que isso é importante!?

Bem, essa é uma pergunta interessante é que precisaremos percorrer um certo caminho até chegar a sua resposta, mas resumindo, indução de tipo é quando você tem que ter certeza que o valor que está passando por determinado ponto do código é proveniente de algum tipo de dado (string, array, boolean,…) ou algum tipo de objeto(MinhaClasse, Usuario, PessoaFisica, PessoaJuridica, …).

No PHP, por padrão você pode fazer esse teste com apenas alguns tipos de dados. Você pode testá-lo se é um array ou alguma instância. Vamos a prática:

namespace test;

  final class Test
  {
    public static function testMethod(array $list = [])
    {
      return implode(' ', $list);
    }
  }

  $obj = Test::testMethod([
    'varios', 
    'itens', 
    'passados', 
    'como', 
    'array'
  ]);

  echo $obj;

  /* output:
  varios itens passados como array
  */

Eu sei. Já usei esse exemplo anteriormente para explicar as novas implementações da versão reduzida de declaração de arrays, mas o exemplo é completamente reusável se levarmos em consideração que logo a versão 5.4 do php estará lançada(isso se você não está lendo este artigo muito tempo depois que o php5.4 fora lançado).

No código acima, temos a indução de tipo sendo feito na declaração do método. Aquele array logo depois do parantese de abertura de nossos parâmetros indica que a variável list, obrigatoriamente deve ser um array, caso contrário, você verá algum apito do php avisando que fez alguma coisa errada como essa abaixo:

$obj = Test::testMethod('Isso é uma string');
/* output:
  Catchable fatal error: Argument 1 passed to 
  test\Test::testMethod()     must be an array, string given,
*/

Ilustrando o que nós já sabíamos, ele quer um array e você está dando uma string. Vamos agora para um exemplo com objetos, para ficar mais divertido.

class Pessoa {

  public static function contratar(PessoaFisica $obj) {
    return $obj ->nome . ' contratado!';
  }
}

class PessoaFisica extends Pessoa {

  protected $nome;

  public function __construct($nome) {
    $this->nome = $nome;
  }

}

$pessoafisica = new PessoaFisica('Fábio Luciano');
$pessoa = new Pessoa();

print $pessoa->contratar($pessoafisica);

O código acima funciona perfeitamente como esperado. Queremos contratar um novo funcionário e quem faz isso é somente a classe Pessoa. E só se pode fazer contratações de pessoas físicas. Ditamos essa regra colocando em nosso código, que somente deve ser passado como parâmetro de nosso método contratar objetos da classe PessoaFisica.

E se alguém achou que poderia contratar uma empresa e pudesse usar os mesmos métodos(entenda-se por meios), que uma pessoa física?

class PessoaJuridica extends Pessoa {

  protected $nome;

  public function __construct($nome) {
    $this ->nome = $nome;
  }

}

$pessoajuridica = new PessoaJuridica('Coisa Inc.');
$pessoa = new Pessoa();


print $pessoa->contratar($pessoajuridica);
/* 
Catchable fatal error: Argument 1 passed to Pessoa::contratar() 
must be an instance of PessoaFisica, instance of PessoaJuridica given
*/

Bem, acho que você já deve ter entendido qual o ganho que tem quando se se usa esse tipo de artifício em seu código: Confiança. No fim é tudo sobre isso. Você ganha confiabilidade que seu código só será usado se for de um determinado tipo ou de uma determinada instância.

Ok. Entendi! Mas e os outros tipos!?

Até o momento que estava escrevendo esse artigo o php havia implementado essa característica para apenas os dois tipos comentados. Porém, existe uma forma muito bacana se usar a indução de tipo para mais alguns. São eles: Inteiros, Enums, Ponto Flutuante, Booleanos e strings.

Nesse momento nós quebramos aquele conceito dos haters, então vamos como calma. Vamos dividir esse artigo em dois para tomarmos um ar.

Tunning - Diminuindo o número de requisições com base64 encoding

Lendo esse artigo hoje, me lembrei que há algum tempo, mentalmente, comecei a escrever algo sobre quando usar e  não usar a técnica que usa a  imagem codificada em base64 para diminuir o número de requisições ao servidor.

Antes de continuarmos, precisamos compreender por alto o que é o base64. Em termos gerais, base64 é uma forma de codificação para qualquer tipo de dado. Neste caso, nós podemos simplificar dizendo que a codificação base64 é a representação textual de uma imagem.

Antes de mais nada, é bom lembrar que isso é uma técnica de tunning, e como em grande maioria delas, só é válida em alguns casos específicos. Por exemplo, essa técnica tem maiores ganhos somente quando existe uma quantidade considerável de imagens a serem carregadas em uma página.
Para continuarmos é necessário compreender um pouco sobre como é o passo do carregamento de uma página que contem vários itens a ser carregados.
Considere o código abaixo para os próximos exemplos e explicações.

O código é simples, mas consiste em doze requisições: Um arquivo de estilo, outro de javascript e mais dez requisições para cada imagem que será anexes-coada ao documento. Fiz com dez para não criar um arquivo monstruoso e não perder tempo.
A primeira coisa que será carregada do documento acima será o arquivo javascript, mas o browser não pára para analizá-lo para depois depois ir para o próximo item, que seria o arquivo de estilo. Ao ler o documento, o browser vai fazer cada requisição de cada vez, o que pode ser perigoso, caso algum item do seu cabeçalho dê algum problema, o carregamento da sua página pode ser comprometido.

Sabendo disso, que tal deixar a cargo do browser apenas duas requisições, e as outras dez serem feitas internamente pelo sistema operacional?

Na prática, o que iremos fazer com essa técnica é pegar o conteúdo da imagem, criptografar em base64 e incluí-la no código fonte.

A ferramenta de codificação e tradução base64 está implementada em diversas linguagens(python e ruby), e aqui neste exemplo vou utilizar em PHP.

O primeiro passo que irei fazer é codificar uma classe que me retorne a url codificada em base64 e que seja compatível com o que o browser espera. O formato é

data:[<mime type>][;charset=<charset>][;base64],<encoded data>

A partir disso, temos o código abaixo:

$uri = new DataUri('./imgs/gluttony.jpg');
print $uri->generate();
O código acima, quando executado de forma correta, vai gerar as data uri no formato esperado. Veja o exemplo de uma uri gerada. Se você copiar e colar o código abaixo na sua barra de endereço, verá o resultado aqui.

Agora vamos criar o código que vai exibir todas as imagens de um determinado diretório e aplicar nossa técnica.

Prontinho. O código não está bonito, mas está bom para demonstrar sua aplicação.

Dica: essa técnica não pode ser aplicada em qualquer lugar. Como pode-se ver, nós diminuímos drasticamente a quantidade de requisições ao servidor, mas também aumentamos exponencialmente o tamanho do lógico html. Essa técnica não terá a menor valência se as imagens estiverem em outro servidor.
Só aplique essa técnica se a quantidade de requisições for um gargalo para sua aplicação, senão, continue fazendo como sempre fez.

Novidades do PHP 5.4 - Declaração de arrays

Uma das novidades que estão vindo com a nova versão do PHP, a versão 5.4, é a versão reduzida de declaração de arrays.

O propósito para essa adição é exclusivamente estético e visa a melhora da manutenção e leitura de códigos onde existe a necessidade de por exemplo a passagem de arrays como parâmetros de alguma função. Mais sobre a proposta pode ser lida aqui

Se você deu uma olhada no documento, a proposta inicial era disponibilizar duas formas de fazer referências de índice e valor. A primeira forma, se você já trabalhou com php alguma vez já foi visto, que é a forma "indice => valor". A outra seria o padrão "indice : valor", mas felizmente ficamos somente com a primeira. Esse padrão é utilizado por diversas outras linguagens para referências entre índice e valor, se você já usou json você provavelmente já viu.

No exemplo acima, você pode ver uma declaração simples de um array usando a forma contraída, se fossemos utilizar a forma extendida, era só trocar os [] por array();

No exemplo acima, vemos a declaração de um array com a definição de valores com índices pré-definidos. Usei a função implode no array para demostrar que essa forma contraída é apenas um alias para a forma padrão que já utilizamos e é perfeitamente possível utilizar as funções que você sempre usou para manipular arrays

No exemplo acima, demonstramos a qual propósito esse alias foi implementado. Vemos claramente a questão da legibilidade e fácil leitura do código.

Outra coisa que eu diria que é no mínimo interessante e que vai poupar algumas linhas de códigos em alguns projetos é dereferencing que é ilustrado no código abaixo

O maior ganho dessa implementação é que se existe uma função ou método que tenha como saída um array, você não precisará armazenar em um conteúdo para depois usá-lo. Sabendo o índice do array, você só o usará. Mais informações você pode encontrar na documentação dessa implementação.

Instalando o PHP5.4 no ubuntu por código fonte

Recentemente, para testar as novidades que virão na próxima versão do PHP(5.4), fiz a instalação do RC(Release Candidate) disponível. Primeiramente antes de continuar acredito ser necessário afirmar que como ainda está em RC, é recomendável não fazer a instalação do pacote e que qualquer coisa estranha que acontecer é por sua conta em risco. Nem preciso dizer que não é recomendável para ambientes de produção, não é?

Existe uma euforia por trás dessa versão, mas por que? Parte disso é que esta versão é a mais próxima da versão 6 que está por vir.

Deixemos de papo e vamos para a compilação do pacote.

Como não vamos precisar destes arquivos posteriormente, vamos fazer tudo isso dentro do diretório /tmp, para que após a inicialização esses arquivos sejam removidos. Então vamos mudar para o diretório /tmp com o comando:

cd /tmp

Para prosseguirmos, algumas bibliotecas serão necessárias para configurar, compilar e instalar o pacote. Com o comando abaixo instalamos todas elas:

sudo apt-get -y install make g++ flex bison build-essential zlib1g-dev binutils cmake libmcrypt-dev \
 libmhash-dev libxslt1-dev libtidy-dev libbz2-dev libxml2-dev libssl-dev libmysqlclient16 libmysqlclient16-dev

Agora sim vamos começar a instalação do PHP. Primeiramente vamos baixar o código fonte da versão do php que estamos querendo instalar. Nesse momento estamos na versão RC6 do código, então, vamos baixá-la.

wget http://downloads.php.net/stas/php-5.4.0RC6.tar.gz

Após completar a cópia, vamos descompactá-lo e mudar para o diretório do pacote para começarmos a configuração do pacote.

tar zxf php-5.4.0RC6.tar.gz && cd php-5.4.0RC6

Os passos seguintes são feitos em cadeia, se você não conseguir passar de um passo NÃO FAÇA o próximo por que não irá funcionar.

Antes de prosseguirmos, é necessário dizer que este artigo abrange a instalação básica deste pacote, e não iremos fazer nenhuma configuração adicional para posterior compilação. Para saber mais informações sobre as opções que o pacote possui para compilação, digite o comando a seguir no terminal, a fim de encontrar qual das diversas opções lhe agrada.

./configure --help

Como faremos a configuração padrão do pacote, digite o comando abaixo:

sudo ./configure

Após configurar e nenhum erro ser apresentado, vamos compilar nosso pacote com o comando abaixo. Esse passo costuma demorar um bocado.

sudo make

Se tudo correr bem durante a compilação estamos prontos para fazer a instalação com o comando abaixo:

sudo make install

Correndo tudo bem, vamos mover o arquivo de configuração padrão para sua localização correta

sudo mv php.ini-development  /usr/local/lib/php/php.ini

Para testar se tudo correu bem, vamos ver a versão do php que temos instalada na máquina com o comando abaixo:

php -v

Aqui, a saída para este comando resulto em:

PHP 5.4.0RC6 (cli) (built: Jan 30 2012 02:13:34)  Copyright (c) 1997-2012 The PHP Group Zend Engine v2.4.0, Copyright (c) 1998-2012 Zend Technologies

Para finalizar vamos testar um dos novos recursos que esta versão traz: O servidor web embutido.

Para isso, vamos criar um arquivo com a função phpinfo() em seu conteúdo com o comando a seguir:

echo '<?php phpinfo();' > index.php

Agora vamos ao recurso, rodamos o comando abaixo, com a opção -S seguida da especificação de host e porta que nosso servidor rodará, aqui foi escolhida 666, mas pode ser qualquer porta que esteja liberada.

php -S localhost:666

Agora acessamos o endereço localhost:666 em nosso browser e temos a imagem a seguir:

20

Instalando o PHP5.4 no ubuntu por repositório

Recentemente, para testar as novidades que virão na próxima versão do PHP(5.4), fiz a instalação do RC(Release Candidate) disponível. Primeiramente antes de continuar acredito ser necessário afirmar que como ainda está em RC, é recomendável não fazer a instalação do pacote e que qualquer coisa estranha que acontecer é por sua conta em risco. Nem preciso dizer que não é recomendável para ambientes de produção, não é?

Existe uma euforia por trás dessa versão, mas por que? Parte disso é que esta versão é a mais próxima da versão 6 que está por vir.

Deixemos de papo e vamos para a instalação e configuração do pacote.

Primeiramente precisamos adicionar a chave pública do repositório. Para tal, execute o código abaixo em linha de comando.

 curl http://apt.damz.org/key.gpg | sudo apt-key add - 

Se o bash apitar dizendo que você não tem o curl, você pode perfeitamente fazer isso com o wget, como no comando abaixo:

 wget -qO- http://apt.damz.org/key.gpg | sudo apt-key add - 

Agora iremos adicionar o repositório em sí. Você vai notar na linha abaixo, que a versão que está disponível é para a natty, mas isso não será um problema desde que não mudemos a linha abaixo. Iremos baixar a versão para a natty no oneiric(ao menos aqui está assim).

sudo echo 'deb http://apt.damz.org/ubuntu natty php54' > /etc/apt/sources.list.d/php54.list

Vamos atualizar a lista de pacotes disponível com o update do apt-get.

sudo apt-get update

Se você já tem o php instalado em sua estação, será necessário apenas um dist-upgrade ou upgrade pelo terminal, e seus pacotes serão atualizados.

sudo apt-get dist-upgrade

É esperado que três pacotes sofram alguma mudança com esta atualização. São eles:

  • libapache2-mod-php5
  • php5-cli
  • php5-common

Caso você esteja fazendo uma instalação, e não uma atualização, o comando abaixo vai adicionar os pacotes necessários para ter a instalação da versão em sua estação.

sudo apt-get install libapache2-mod-php5 php5

Após a instalação, você pode verificar se tudo está certo verificando em linha de comando qual a versão instalada com o comando abaixo:

php -v

A saída que tive aqui foi essa:

É importante que você analise os warnings gerados, por que no meu caso, as bibliotecas do mysql e o adaptador PDO para este banco de dados não estão mais disponíveis e portanto não funcionarão.

Um conselho: faça seus testes em um ambiente controlado como uma máquina virtual(VirtualBox). Caso contrário, você deverá enfrentar alguma dificuldade se tentar rodar algum outro projeto que está rodando em uma versão anterior.

Abaixo você pode ver meu phpinfo():

13

Traduzindo as man pages para português

Apesar de preferir as manpages servidas em inglês, há pessoas que as prefiram para o idioma tupiniquim(nada contra!). Seguindo os passos abaixo, você deixará algumas das páginas para português.

Primeiro de tudo, vamos trazer os pacotes contendo as traduçòes das manpages.

Se você está em uma distribuição derivada do debian((lxk)?ubuntu,linux mint) , execute a seguinte instrução:

 sudo apt-get install manpages-pt manpages-pt-dev 

Se você esá em uma distribuição derivada do redhat(fedora,centos), execute a seguinte instrução:

 su -c 'yum install man-pages-pt ' 

Isso ainda pode não resolver o seu problema. Nas distribuições derivadas do debian, ainda pode ser necessário fazer uma alteração nas suas variáveis LANG para isso edite seu arquivo /etc/default/locale, para ficar assim:

LANG="pt_BR.UTF-8"
LANGUAGE="pt_BR:en"

Ao final, seu terminal terá o mesmo efeito que o abaixo ao executar 'man chmod' :

__005