Blog and Site, BETA!
Random header image... Refresh for more!

Como obter a declaração de um array a partir de um array em PHP

Você, alguma vez na vida, precisou escrever uma definição de um array que você tinha em memória no próprio código? Como assim, Zé? Sei lá, por exemplo, na hora de escrever testes no cakephp você muitas vezes precisa definir um array que será utilizado como parâmetro de comparação com os dados obtidas em runtime, right?

Ok, só que aí você tem aqueles arrays enormes que representam os dados obtidos do banco. Você vai ficar digitando todos aqueles campos do array no braço? NOT.

Uma solução ingênua para o problema é utilizar um var_dump() ou print_r() para obter uma representação próxima do array e, então, ir ajeitando o texto para que este se torne uma definição, de fato, de um array.

Mas Zé, será que não tem um jeito mais espertinho de se fazer isso? Tem. Graças ao PorKaria, e seu talento nato para POGs, aprendi uma técnica ninja, conhecida apenas por programadores PHP seniors: “use a json_encode() e depois a json_decode(), oras bolas”.

Suponha que você tenha um array enorme do qual você precisa obter a definição para colocar no seu código. O array está armazenado na variável $meusDados e foi obtida através de um find no banco de dados. Um exemplo no CakePHP:

$meusDados = $this -> Dados -> findByName('Zé');

Suponha que o cake vai retornar um array enorme, já que a minha tabela de dados possui 75 campos. Mas você quer testar, você quer gerar fixtures, você vai ficar “ajeitando” o output de um var_dump() da vida pra poder inserir a definição de uma tabela no código? Não!

É tudo muito simples. Tudo que você precisa, na verdade, é da definição em JSON, e não necessariamente da definição em PHP. O primeiro passo, então, é obter a representação em JSON do array:

var_dump(json_encode($meusDados));

Pronto, copie a representação em JSON escrita na tela, faça as alterações necessárias e então use a json_decode() para definir o array no seu código:

$x = json_decode('representação em JSON do array original', true);

E voilá, $x vai conter o seu array para que você o utilize/manipule como bem desejar.

That’s all folks. :)

January 16, 2010   No Comments

Linguagens de Programação by Cesar Brod

“Java é quase livre
Se não fosse, nem pensar!
Python ensina a identar
Do jeito Deus sempre quis
De Ada, Prolog e Lisp
Eu escapei por um tris
Nutro paixões infantis
Por C, Cobol, outras tantas
Mas nunca deixo de ouvir
O que minha alma me diz
Meu amor mais profundo é o PHP
A melhor linguagem do mundo”

Cesar Brod (via @PorKaria)

Identifiquei-me principalmente com o “nutro paixões infantis”, aiehiaheiaue :P

October 30, 2009   No Comments

Lidando com código PHP legado

Alguns slides interessantes sobre código PHP legado (ruim) e como amenizar um pouco as coisas:

August 17, 2009   No Comments

Dicas de otimização de PHP do Google estavam furadas

Recentemente eu postei sobre a página do google com dicas de otimização para a web, enfatizando o tutorial sobre PHP. Por incrível que pareça, as dicas não eram tão boas assim! Veja:

PHP performance tips from Google

A maioria das dicas dadas no tutorial do google realmente funcionam, mas apenas para versões antigas (3.. 4), as versões mais modernas possuem otimizações para os casos ilustrados. Fail do Google, hein? Se até eles podem, por que não eu? :D

Uma discussão sobre o fail também pode ser encontrada na própria lista do projeto.

Fonte: http://www.phpdeveloper.org/news/12771

June 29, 2009   No Comments

Crie namespaces melhores em PHP

Um artigo recente de Nathan A. Good no IBM Developer Works dá algumas dicas sobre nomenclatura de namespaces, agora que eles estão pra chegar ao mundo PHP. Pra quem já programa em outra linguagem que possua namespaces  é tudo bastante natural. Pra quem só trabalhou com PHP até hoje, acho que vale a pena dar uma lida.

Fundamentos

Por que usar namespaces? Os dois objetivos principais são evitar colisões e ajudar na organização do código. Duas classes de mesmo nome podem possuir comportamentos completamente diferentes. As representações de um automóvel para uma fabricante de carros e para uma empresa de seguros são diferentes. Sem namespaces, era comum adicionar o contexto ao nome da classe: Ford_Automovel e ItauSeguros_Automovel, por exemplo (tosco, mas dá pra pegar a idéia, né?).

E agora, como é?

Para acessar uma classe Foo contida no namespace IBM, por exemplo, deve-se fazer:

<?php
$foo = new \IBM\Foo();
?>

Como pode ser percebido, o identificador de namespaces é a backslash “\“.

Notas: namespaces não correspondem a pastas no sistema de arquivos, como Java, e também podem conter funções e constantes, além de classes.

E para definir a classe acima no seu respectivo namespace?

<?php
namespace IBM;

class Foo {
...
}
?>

E como eu escolho os nomes para os meus namespaces? Em Java a convenção é utilizar o seu domínio (ou da sua empresa) ao contrário: br.eti.josericardo, por exemplo. Eu, pessoalmente, acho legal essa convenção e não vejo problema em segui-la também no PHP.

Mas como não foi estabelecida nenhuma convenção oficial neste sentido. As sugestões do Nathan são:

  1. No nível mais alto usar o nome do projeto (eg. Greeter) ou algo sobre o domínio (contexto mesmo): IBM\Greeter e IBM\MyApp\Account, respectivamente.
  2. Nos níveis mais baixos usar o nome do projeto ou da aplicação. Ele diz que tenta manter a quantidade de subnamespaces entre 5 e 9, pra facilitar a memorização.
  3. Em relação ao reuso, tomar cuidado para não criar namespaces muito especializados. Para coisas que serão reaproveitadas em outros projetos, KISS: use namespaces como Lib, Common e coisas do gênero.
  4. Utilize UpperCase camel para os namespaces: MyProduct, FooBar, etc.

Para declarar subnamespaces, faça:

namespace IBM\Greeter;

namespace IBM\MyApp\Account;

e assim por diante.

Hey! PHP tem alias também!

Pelo pouco visto acima, já deve ter gente pensando “putz, vou ter que digitar esse mundaréu de coisas só pra acessar um método ou uma classe?”.
A resposta é não! Como? Importe o namespace (use) e, opcionalmente, defina um alias para o namespace ou classe (não funciona para funções ou constantes), exemplos:

use MyCompany\Common\Validation; // acessa-se como Validation
use MyCompany\Common\Validation as Validators; // acessa-se como Validators
use MyCompany\Common\NomeDeClasseBastanteLongo as NomeCurto;

É importante notar que a definição de “imports” (use) e de aliases casam com nomes que não sejam qualificados, ou seja, que não tenham o namespace definido junto com o nome. No exemplo acima, se usarmos NomeCurto, estaremos acessando MyCompany\Common\NomeDeClasseBastanteLongo, mas se usarmos \MyCompany\Lib\NomeCurto, “NomeCurto” não será substituído por NomeDeClasseBastanteLongo e, muito menos, por MyCompany\Common\NomeDeClasseBastanteLongo. Understood?

Por fim, é possível também definir mais que um namespace em um mesmo arquivo. A recomendação é que isto não seja feito, mas, caso você queira muito, faça (note as chaves):

namespace MyProject {
    const CONNECT_OK = 1;
    class Connection { /* ... */ }
    function connect() { /* ... */  }
}

namespace AnotherProject {
    const CONNECT_OK = 1;
    class Connection { /* ... */ }
    function connect() { /* ... */  }
}

namespace { // código global
    session_start();
    $a = MyProject\connect();
}

Acabei saindo do escopo do post, mas eu comecei a tirar umas dúvidas enquanto lia o artigo do Nathan e achei que seria legal compartilhar com a diminuta “audiência” deste blog :)
Fontes:

http://www.ibm.com/developerworks/opensource/library/os-php-namespaces

http://br.php.net/manual/en/language.namespaces.php

June 26, 2009   2 Comments

Saiu o Eclipse PDT 2.1

Seis meses após o lançamento da última versão estável e acompanhando o lançamento do Eclipse Galileo, acaba de sair a nova versão do PDT, a 2.1.

E quais são as novidades? Acho que o principal é o suporte às novas funcionalidades do PHP 5.3, como namespaces e closures. Bom trabalho Eclipse Project :)

Ha! O PDT também tem uma wiki com mais detalhes.

June 26, 2009   No Comments

“Let’s make the web faster” (Google)

É, ao que tudo indica o Page Speed era apenas a ponta do iceberg. O Google acaba de lançar mais uma página relacionada ao aumento de desempenho na web: Let’s make the web faster. A página trás uma série de tutoriais sobre como tornar as páginas mais rápidas. Vários temas são abordados, inclusive PHP, veja o vídeo:

Isso tudo faz parte de uma nova iniciativa do Google de compartilhamento e geração de novas informações para que a web, sua plataforma de desenvolvimento, se torne cada vez mais eficiente. Bem, acho que ninguém tem nada a perder, correto?

As dicas para PHP:

  1. Não copie variáveis sem ter um motivo
  2. Utilize aspas simples para delimitar strings
  3. Utilize echo e, ao invés de concatenar as strings e variáveis, passe-as como argumentos:
    echo 'Escrevendo duas variáveis: ', $var1, ' e ', $var2;
  4. Utilize switch/case ao invés de if/else.

June 24, 2009   1 Comment

Os 10 princípios dos mestres do PHP?

Em um post do ano passado, Glen Stansberry deu uma garimpada na web e separou 10 dicas de desenvolvedores PHP famosos. A esta lista ele chamou de “Os 10 princípios dos mestres do PHP”. Acho que vale a pena dar uma olhada.

Os princípios:

  1. Use o PHP apenas quando necessário: o PHP foi criado para resolver problemas de desenvolvimento para a Web. Para vários tipos de tarefas, há ferramentas mais apropriadas, saiba quais são.
  2. Utilize várias tabelas no Mysql para obter uma boa escalabilidade.
  3. Nunca, jamais, confie nos seus usuários. Seja paranóico em relação aos dados submetidos pelos usuários.
  4. Invista em caching de código PHP.
  5. Aumente sua produtividade utilizando uma IDE, templates e snippets.
  6. Aprenda a utilizar as funções de filtragem (filter_*) do PHP.
  7. Use um framework: pode salvar bastante tempo.
  8. Não use um framework: o preço da comodidade se chama OVERHEAD.
  9. Use processamento em lotes + cron. O que fazer quando uma tarefa demora mais que 1 ou 2 segundos para ser completada?
  10. Ative a emissão de erros imediatamente, no nível máximo: error_reporting(E_ALL).

Eu não sei se estes podem ser considerados realmente os 10 grandes princípios do desenvolvimento PHP. Mas que são boas dicas para sempre se ter em mente, ha, isso são.

June 21, 2009   No Comments

Um jeito fácil de realizar requisições assíncronas com PHP

Uma situação que às vezes alguém pode se deparar, no meu caso foi nessa semana, é a necessidade de se realizar uma requisição assíncrona em uma determinada interação com um web service, por exemplo. Ou então fazer uma requisição do tipo fire-and-forget , one-way ou out-only (fazer a requisição e não se importar com o retorno dela). Apesar de a maioria estar acostumado com o modelo de interação Request-Response do HTTP, situações como essas não são raras.

As perguntas que eu quero responder são: é possível fazer isso usando PHP? Se sim, como?

O problema é o seguinte. Durante a execução do seu script você precisa contactar outra página. Entretanto, você, por algum motivo, não quer esperar pelo resultado desta invocação, se é que há resultado. Uma mensagem de notificação, por exemplo, não aguarda coisa alguma como resposta. Como fazer isso? Se você estivesse disposto a esperar pelo resultado da requisição não se importando com o tempo que isso pudesse levar, então é relativamente simples implementar usando cURL ou a pecl_http (olhei por cima a documentação e não encontrei nada relativo a invocações assíncronas). Mas e quando não se está disposto ou não é possível (faz parte do protocolo de interação com a aplicação)?

Uma possível solução seria criar um novo processo e delegar estas tarefas ao mesmo [1], não sei se funciona, aparentemente sim, mas não testei porque achei trabalhoso demais e eu sou um cara preguiçoso.

Procurando um pouco mais, encontrei um outro artigo que caracteriza bem o problema (caso você não tenha entendido direito até agora o que eu estou tentando fazer) e expõe algumas soluções para o problema: [2]. No final, ele até apresenta uma solução interessante, utilizando raw sockets. O problema dessa solução é que você precisa construir o request HTTP no braço e tudo mais.

Enfim, no artigo [2] ele menciona a possibilidade de resolver o problema utilizando a própria cURL. Como fazer? Realize o request como você está acostumado a fazer usando a cURL, mas defina o timeout para um tempo curto, no artigo ele diz que o mínimo que se pode esperar é 1s. Qual é o problema desta abordagem? Imagine que várias requisições sejam feitas à uma página que implementa essa solução. Cada requisição, invariavalmente terá que esperar no mínimo (o timeout, lembra?) 1s para que a resposta da página seja gerada.

Como chegar, então, a algo próximo do desempenho da solução utilizando sockets, que possui um tempo de retorno (disparo) quase imediato? Simples, a partir da versão 7.16.2 da cURL (PHP 5.2.3) é possível definir o timeout em milisegundos! Para isto basta utilizar a boa e velha curl_setopt e definir o parâmetro CURLOPT_TIMEOUT_MS, ao invés do antigo e surrado CURLOPT_TIMEOUT, que trabalhava na escala de segundos. Curl, isn’t it? (eu não resisti).

Com estas ferramentas simples e bastante conhecidas é possível então utilizarmos a cURL para realizar requisições do tipo fire-and-forget.

E nos casos em que queremos tratar a resposta mas não queremos esperar por ela, até mesmo permitindo que o nosso script PHP (que dispara a requisição) retorne algo para o cliente? Simples também, basta criarmos uma outra página que fará a requisição propriamente dita. Para fazer a requisição para esta segunda página a gente utiliza o fire-and-forget e deixamos que esta trate a(s) resposta(s).

Bem, era isso que eu tinha pra falar. Se alguém tiver alguma dúvida ou souber de alguma solução melhor para o problema ou até mesmo de algum problema em relação a esta abordagem NOTIFIQUE-ME! DEIXE O SEU COMENTÁRIO! :D É importante para todos.

[1] http://w-shadow.com/blog/2007/10/16/how-to-run-a-php-script-in-the-background

[2] http://petewarden.typepad.com/searchbrowser/2008/06/how-to-post-an.html

May 27, 2009   4 Comments

Wordpress multi-idiomas com Gengo

É inevitável, para se alcançar a grande audiência da Internet é necessário que o conteúdo publicado esteja em inglês, ponto. Isto é o mínimo, mas em um mercado globalizado não é difícil se deparar com a necessidade de suportar três ou mais idiomas. Como recentemente passei a utilizar o Wordpress como ferramenta de trabalho, fui atrás de algumas indicações e o Gengo, como plugin para gerenciamento de idiomas, foi muito bem recomendado.

O processo de instalação do plugin é padrão: Plugins -> Add New, fazer o upload do zip e então ativar o plugin através da tela de plugins. Feito isto, um novo item “Languages” será adicionado ao menu da esquerda da página de administração do Wordpress.

Figura 1. Adicionando o português como idioma padrão do site.

Figura 1. Adicionando o português como idioma padrão do site.

Ao clicar no item Languages, uma tela parecida com a da Fig. 1 deve então aparecer para você selecionar o idioma primário do seu site. No meu caso, bastou selecionar Português/Brasil e pronto, o Gengo já estava configurado para utilizar o português como idioma padrão.

Entretanto, para que a tradução ocorra (exceto para o inglês, é lógico), é também necessário que o arquivo de tradução, no meu caso o pt_BR.mo, relativo ao idioma seja adicionado à pasta wp-content/languages. A fonte primária de arquivos de traduções é a “Wordpress na sua língua”. Para o português, especificamente, você pode ir direto à página do Wordpress Brasil. Bem, olhando rapidamente no site, eu não encontrei os arquivos de tradução para download em separado, então, aparentemente, você vai ter que fazer o download do pacote inteiro do wordpress em português que tem no site.

Feito o download do pacote do wordpress em português, basta copiar a pasta wp-content/languages para a sua instalação atual do wordpress (estou assumindo que a instalação oficial, em inglês, é a que está sendo utilizada como base). Agora sim, você tem o wordpress “traduzido” para o português funcionando. “Traduzido” (entre aspas) porque você provavelmente vai ter que traduzir algumas coisas no seu template também, né? Como fazer o seu template se tornar language-aware é tema para outro post :D

Após  a adição do português, a tela da Fig. 2 deve ser exibida.

Figura 2. Adicionando o inglês.

Figura 2. Português adicionado com sucesso.

Em seguida eu adicionei o inglês também. Feito isto, as duas versões do meu site passam a ser acessadas pelas seguintes URLs:

http://www.josericardo.eti.br/pt

http://www.josericardo.eti.br/en

Figura 3. Post traduzido.

Figura 3. Post traduzido.

Daí em diante, basta começar a traduzir os posts e páginas para que o conteúdo do site em inglês também seja preenchido. A Fig. 3 mostra a capa do meu blog após a tradução do primeiro post do mesmo. Para traduzir um post, por exemplo (é possível também traduzir páginas), basta criar um novo post assim como era feito anteriormente. A diferença é que agora haverá mais uma opção na tela de edição de posts relativa ao Gengo (ver Fig. 4).

Figura 4. Selecionando o item original para realizar a tradução.

Figura 4. Selecionando o item original para realizar a tradução.

Então, basta ir selecionando os itens, indicar que o post atual é uma tradução e selecionar o post orinal na lista de páginas que vai aparecer (para encontrar posts mais antigos clique no botão “Next 10″). O legal é que o post original vai aparecer embaixo para que você possa traduzir de maneira mais fácil.

Figura 5. Warning durante o setup do Gengo.

Figura 5. Warning durante o setup do Gengo.

Apesar de estar utilizando a versão beta (2.8) do Wordpress, a instalação (conforme relatado) funcionou quase sem problemas, apenas um warning apareceu na página principal  (ver Fig. 5). Isto se deve ao fato de eu não ter traduzido as categorias do site também. Mas foi só adicionar uma verificação antes do foreach no arquivo classes.php e pronto.

Bem, o básico do Gengo é isso. Simples e eficiente. É bom lembrar que a questão do template ainda fica em aberto. Em breve eu posto algo sobre isso, mas se você está com pressa, basta dar uma olhada nas FAQ do Gengo, várias perguntar relevantes (como era de se esperar) são respondidas por elas.

May 25, 2009   2 Comments