PHP: Comparando arrays

Setembro 22, 2008

Você já tentou comparar dois arrays utilizando os operadores == ou === ?
Em alguns casos esta comparação pode ser útil.

O operador == retorna true caso os dois arrays sejam iguais, isto é deve conter o mesmo número de elementos com as mesmas chaves e valores. Sem importar a ordem de como eles foram atribuídos.

O operador === retorna true caso os dois arrays sejam iguais, isto é deve conter o mesmo número de elementos com as mesmas chaves e valores. Porém, desta vez a ordem de como eles foram atribuídos também devem ser iguais.

Por exemplo:

1 $paises1 = array("brasil", "japao", "italia");
2 $paises2 = array(0 => "brasil", 1 => "japao", 2 => "italia");
3
4 var_dump($paises1 == $paises2); // retorna true

Como podem ver, ele retorna true pois todas as verificações foram atendidas (mesmo número de elementos, chaves iguais e valores iguais).

Agora para uma comparação mais exigente:

1 $paises1 = array("brasil", "japao", "italia");
2 $paises2 = array(1 => "japao", 2 => "italia", 0 => "brasil");
3
4 var_dump($paises1 === $paises2); // retorna false

Já neste caso iria retornar false, mesmo o array sendo igual sua ordem não foi definida da mesma forma.

Sempre tive problemas com sessão na hora de gerar arquivos com a classe FPDF.
Era só colocar o session_start() no ínicio do arquivo que o Internet Explorer não abria mais o PDF, já no Firefox funcionava perfeitamente.
Achando a situação muito estranha, fui tentar achar a solução e como sempre os fóruns americanos me salvaram.

Basta colocar o seguinte comando antes da função session_start(), assim ficando:

1 session_cache_limiter(private);
2 session_start();

Pronto! Agora o Internet Explorer abrirá o PDF normalmente e entederá todas as variáveis de sessão ($_SESSION) normalmente.

[UPDATE]

Lembrando que isso forçará o cache do PDF, caso você não queira deixar o documento no cache é necessário fazer uma chamada diferente da anterior, por exemplo passando um parâmetro dinâmico e único (gerando um número aleatório ou chamando o timestamp são boas soluções).

Exemplo:

document.pdf?token=859859454 
document.pdf?token=238142340
document.pdf?token=132984294 

[/UPDATE]

PHP: O Tolerável

Junho 13, 2008

1<?
2 $var = Fruta;
3 echo “Eu gosto de comer {$var}; // retorna Eu gosto de comer Fruta 
4 ?>

Droga, Fruta era uma string e esqueci das aspas, agora vai dar erro de sintaxe.
Não tem problema! o PHP trata isso para você, primeiramente o interpretador tentará encontrar a constante Fruta, caso não encontre, ele converterá automaticamente para string.
Agora se existir tal constante, ele faz o esperado.
Segue exemplo abaixo: 

1 <?
2 define(“Fruta, “Laranja);
3 $var = Fruta;
4 echo “Eu gosto de comer {$var}; // retorna Eu gosto de comer Laranja
5 ?>

Isso também vale para arrays, quando você tenta acessar uma chave sem as devidas aspas você está acessando a constante.
Por exemplo:

1 $Array[teste] = Maça;

O PHP procura o valor da constante teste para setar como chave desse array, se não encontrar ocorre o mesmo procedimento, ele converte para string assim setando teste como chave do array.
Agora se você fizer:

1 define(teste, chegadeteste);
2 $Array[teste] = Maça;

Sua nova chave será chegadeteste.
Isso vale tanto para atribuição de valores como para recuperação.
Por isso tome cuidado, sempre que for utilizar uma string como chave de um array nunca se esqueça das aspas, pois se você não utilizar aspas e alguém definir uma constante com o mesmo nome, seu array pode se comportar de forma inesperada.

Sem contar que utilizando aspas corretamente você economiza processamento e evita que o PHP fique procurando por constantes para depois transformar em string.

[UPDATE]
Devido as muitas reclamações, segue a nota:
Nunca utilize essa técnica, estamos aqui somente para mostrar como funciona o interpretador do PHP. Essa é uma má prática de programação, além de poder gerar um E_NOTICE.
[/UPDATE]

Como todo mundo sabe as variáveis não são globais, isto é, não funcionam em um escopo diferente do qual foi definida.

O PROBLEMA

1 $programa = “Chaves”;
2 $horario =19:15″;
3 $exibicao = “segunda à sexta”;
4 $canal = “SBT”;
5
6 function exibirPrograma() {
7 echo “O programa {$programa} é exibido de {$exibicao} às {$horario} no canal {$canal}”;
8 }

Isto não iria interpretar nenhuma variável, afinal as variáveis foram setadas fora do escopo da função. A solução seria utilizar a palavra chave global ou a supervariável $GLOBALS ou até mesmo passar as variáveis por parâmetro (nossa, essa última é gambiarra total).

A SOLUÇÃO

1 function exibirPrograma() {
2 global $programa, $exibicao, $horario, $canal;
3 echo “O programa {$programa} é exibido de {$exibicao} às {$horario} no canal {$canal}”;
4 }

OU

1 function exibirPrograma() {
2 echo “O programa {$GLOBALS['programa']} é exibido de {$GLOBALS['exibicao'} às {$GLOBALS['horario']} no canal {$GLOBALS['canal']}”;
3 }

Bem, isso todo mundo já sabe, agora imagine que você tenha que “globalizar” 100 variáveis, vai ser muito chato utilizar o termo global ou a variável $GLOBALS 100 vezes, correto?

A MÁGICA

1 function exibirPrograma() {
2 extract(array_slice($GLOBALS,7));
3 echo “O programa {$programa} é exibido de {$exibicao} às {$horario} no canal {$canal}”;
4 }

Isso importaria para a função todas as variáveis que foram setadas no escopo local da página, assim evitando que você altere todo seu código. A função extract() faz exatamente isso, define variáveis através de chaves de um array. Na função array_slice() é removido os 7 primeiros elementos de $GLOBALS que não há necessidade de importá-los, pois já são supervariáveis globais (_POST, _GET, _SERVER, etc)

Há um tempo atrás precisei fazer um site que armazenava e recuperava dados em japonês e português tudo na mesma base de dados. A solução para isso foi utilizar codificação UTF-8, esquecendo o famoso ISO-8859-1 (Latin).
Utilizando UTF-8 corretamente você se livrará de todos os problemas de acentuação que poderão ser causados em sua página e se livrar de vez de funções como utf8_encode() e derivadas.
Apesar de consumir alguns bytes a mais em certos caracteres, você terá a vantagem de trabalhar com qualquer tipo de idioma.

O segredo está em deixar TUDO na codificação UTF-8.

  • Arquivos .php devem ser salvos por sua IDE nesta codificação. (Qualquer editor possui esta opção, como por exemplo o Zend Studio ou Eclipse)
  • Meta tag dos cabeçalhos HTML <meta http-equiv=”Content-Type” content=”text/html; charset=UTF-8″/>
  • Cabeçalhos em seus arquivos PHP
    header(“Content-Type: text/html; charset=UTF-8″, true);
  • Banco de dados, tabelas e campos com collation utf8_general_ci
  • Sempre após a conexão com o banco alterar codificação.
    Após conectar (mysql_connect) e antes de efetuar qualquer operação deve-se utilizar a função mysql_set_charset(“utf8″, $conexao);    

    Caso seu PHP seja inferior a 5.2.3, é possível utilizar dois SQL ao invés da função acima.
    mysql_query(“SET NAMES ‘UTF8′”, $conexao);
    mysql_query(“SET CHARACTER SET ‘UTF8′”, $conexao); 

    [UPDATE]

    As instruções SQL acima podem ser utilizadas com qualquer função ou classe (PDO, ADODB, etc)

    [/UPDATE]

Após feito essas alterações, você deve limpar suas tabelas e inserir novamente os dados para que a partir de agora sejam gravados e lidos na codificação correta. Outra opção é converter seus registros utilizando as funções CAST() ou CONVERT() do seu banco de dados.
Lembrando que os exemplos acima foram feitos utilizando MySQL, mas qualquer banco possui instruções semelhantes.