Hoje tive um problema inesperado, a aplicação estava funcionando corretamente com FireFox 2 e para minha surpresa deu pau no FireFox 3, levei um bom tempo até descobrir que o novo FireFox implementou o método getElementsByClassName() cujo eu também já havia “implementado”, logo começaram os conflitos entre os dois métodos.
Então fica a dica para que conheçam as novas implementações do FireFox e certifiquem-se que sua aplicação não terá um comportamento inesperado com essa nova atualização.

Segue estes dois links interessantes para vocês ficarem por dentro:

http://developer.mozilla.org/pt/docs/Firefox_3_para_desenvolvedores
http://developer.mozilla.org/pt/docs/Mudan%C3%A7as_no_Gecko_1.9_que_afetam_websites

Ouço muitas pessoas dizendo que a função parseInt() é bugada, em alguns casos de conversão de números como 07 ou 08 ela não retorna o valor esperado.
Só que muita gente não sabe sobre um segundo parâmetro que a função pode receber.

sintaxe: parseInt(string, base);

Este segundo parâmetro é simplesmente a base que você converterá o número, ela pode ser decimal, octal ou hexadecimal.
Quando não especificamos este parâmetro, é assumido por padrão a base decimal (10). Exceto quando você inicia a string com 0 ou 0x que automaticamente é assumido a base octal (8 ) ou hexadecimal (16).
Esta é a causa do retorno inesperado, pois quando você converte o número 08 sem especificar a base, é assumido a base octal e nesta base este número não existe (somente de 0 a 7), assim retornando o valor inesperado 0.

A forma correta, forçando a conversão na base decimal:

1 parseInt(08, 10); // retorna 8

Então por segurança, especifique sempre a base para qual deseja converter, ainda mais quando for um valor dinâmico.

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)

Muitas pessoas tentam rodar triggers pelo phpMyAdmin e recebem um erro de sintaxe.
Tudo levar a crer que o phpMyAdmin não suporta triggers, mas não é bem assim.
O que ocorre é que o delimitador (separador de comandos) padrão do phpMyAdmin ou até mesmo do console do MySQL é o ponto e vírgula “;”
A sintaxe da trigger também possui ponto e vírgula “;” então quando você executa uma trigger, o phpMyAdmin acredita que você está enviando diversas instruções SQL, assim seu bloco de comando é interrompido no meio do caminho acusando erro de sintaxe.

Para resolver isto é simples, basta alterar o delimitador em tempo de execução.
Por exemplo:

DELIMITER $$ — Seta novo delimitador

DROP TRIGGER IF EXISTS teste $$ — Essa é uma instrução SQL
CREATE TRIGGER teste BEFORE DELETE ON tabela
FOR EACH ROW
BEGIN
COMANDO1;
COMANDO2;
COMANDO3;
END$$ — Essa é outra instrução SQL

DELIMITER ; — Volto ao delimitador padrão

Outra opção ainda mais fácil, é utilizar a aba “SQL” do phpMyAdmin e alterar o campo “Delimitador”.
Lembrando que o MySQL introduziu trigger a partir da versão 5.0, caso sua versão seja inferior não funcionará.

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.