Escolar Documentos
Profissional Documentos
Cultura Documentos
7 coisas simples em PHP que alguns
ainda complicam
Por Rafael Jaques • Dicas • 15 de março de 2010 • 20 comentários
Post original por garotosopa:http://garotosopa.wordpress.com/2009/05/30/7coisassimplesemphpque
algunsaindacomplicam/
É comum ver scripts com dezenas de linhas de código pra fazer algo extremamente simples. Fica aqui meu
11 30 11
apelo desesperado com algumas dicas rápidas.
Share Share Share Share
1. Listar arquivos de um diretório
Se não houver um motivo muito claro pra usar opendir, readdir e closedir (não consigo pensar em nenhum),
a forma mais prática de listar o conteúdo de um diretório é com DirectoryIterator:
1 $iterator = new DirectoryIterator('/var/www');
2
3 foreach ( $iterator as $entry ) {
4 echo $entry‐>getFilename(), "
5 ";
6 }
Se for necessário listar os arquivos recursivamente, percorrendo todos os subdiretórios, é só usar o
RecursiveDirectoryIterator junto com o RecursiveIteratorIterator:
1 $iterator = new RecursiveDirectoryIterator('/var/www'
2 $recursiveIterator = new RecursiveIteratorIterator($iterator
3
4 foreach ( $recursiveIterator as $entry ) {
5 echo $entry‐>getFilename(), "
6 ";
7 }
Com um pouco de criatividade, é possível estender essas classes com qualquer lógica facilmente, como por
exemplo, para montar uma árvore com a estrutura dos diretórios.
data:text/html;charset=utf8,%3Cheader%20style%3D%22display%3A%20block%3B%20color%3A%20rgb(51%2C%2051%2C%2051)%3B%20fontfamil… 1/6
26/06/2015 7 coisas simples em PHP que alguns ainda complicam PHPit
2. Montar e desmontar query strings
Mesmo que menos comum (e menos útil), colocar uma query string numa URL é um trabalho trivial demais
pra ser feito com implode, concatenando tudo ou qualquer outro método engenhoso. Desde o lançamento do
PHP 5 é possível contar com a http_build_query:
1 $dados = array(
2 'hl' => 'pt‐BR',
3 'q' => 'Forgetting Sarah Marshall',
4 'testa‐escape' => 'acentuação',
5 );
6
7 echo http_build_query($dados);
8 // hl=pt‐BR&q=Forgetting+Sarah+Marshall&testa‐escape=acentua%C3%A7%C3%A3o
E o inverso também é possível com as funções parse_url e parse_str:
1 $url = parse_url('http://www.google.com/search?q=anneke
2
3 parse_str($url['query'], $query);
4
5 echo $query['q'];
6 // anneke van giersbergen
Só fique atento que, por motivos alheios ao bom senso, parse_str por padrão extrai as variáveis no escopo
onde foi chamada. É necessário passar um segundo argumento para ter um array gerado por referência,
como no exemplo acima com a variável $query.
3. Ler páginas remotas
Dentre todas as implementações, a mais desnecessária costuma ser fsockopen, fwrite, feof, fgets e fclose
para ler arquivos remotos por HTTP.
Uma função já resolve:
1 $contents = file_get_contents('http://php.net/file_get_contents
Isso é possível graças aos protocol wrappers que encapsulam a lógica de acesso aos respectivos protocolos,
tal como HTTP. Esta forma de acesso, no entanto, depende da configuração allow_url_fopen estar
habilitada no php.ini (que é o padrão).
data:text/html;charset=utf8,%3Cheader%20style%3D%22display%3A%20block%3B%20color%3A%20rgb(51%2C%2051%2C%2051)%3B%20fontfamil… 2/6
26/06/2015 7 coisas simples em PHP que alguns ainda complicam PHPit
Para ler os response headers da requisição, utilize fopen com stream_get_meta_data.
E se um dia você quiser impressionar a mulherada, veja a função stream_wrapper_register para criar o seu
próprio protocol wrapper.
4. Submeter dados por post para uma página
remota
A coisa fica mais complicada quando o desenvolvedor pensa em usar cURL pra submeter dados por POST
para outro servidor. A extensão até tem seu mérito, mas usála apenas pra este propósito é um grande
equívoco.
As funções que fazem uso dos protocol wrappers aceitam um objeto de stream context, criado pela função
stream_context_create, para configurar alguns aspectos do protocolo. As opções de contexto do protocolo
HTTP permitem definir, entre outras coisas, o método de acesso (GET, POST, etc) e o conteúdo a ser
postado:
1 $content = http_build_query(array(
2 'cidade' => 'Rio de Janeiro',
3 'tipo' => 'Apartamento',
4 ));
5
6 $context = stream_context_create(array(
7 'http' => array(
8 'method' => 'POST',
9 'content' => $content,
10 )
11 ));
12
13 $contents = file_get_contents('http://exemplo/teste.php
Quando não for necessário ler o retorno da requisição, basta chamar a url com fopen passando o contexto
como quarto argumento.
5. Fazer download de um arquivo remoto
Vale lembrar que a maioria das funções de stream e filesystem aceitam URLs completas e fazem uso da
abstração do protocolo. O que eu vejo muita gente esquecer é que isso inclui a função copy:
data:text/html;charset=utf8,%3Cheader%20style%3D%22display%3A%20block%3B%20color%3A%20rgb(51%2C%2051%2C%2051)%3B%20fontfamil… 3/6
26/06/2015 7 coisas simples em PHP que alguns ainda complicam PHPit
1 $url = "http://userserve‐ak.last.fm/serve/500/4349551/Terri
2
3 copy($url, '/tmp/' . urldecode(basename($url)));
O trecho acima vai baixar a imagem remota e salvar no arquivo local /tmp/Terri Clark.jpg. E caso não seja
óbvio, “local” se refere a quem está executando o script PHP, que no caso será o seu servidor caso seja um
script web, e não o cliente que está acessando pelo browser.
Se o objetivo for realmente repassar o conteúdo remoto para o cliente que estiver acessando pelo browser, o
script é igualmente simples:
1 $url = 'http://userserve‐ak.last.fm/serve/500/4349551/Terri
2
3 $handle = fopen($url, 'r');
4
5 $meta_data = stream_get_meta_data($handle);
6
7 // Repassa todos os headers do servidor remoto para o nosso cliente
8 foreach ( $meta_data['wrapper_data'] as $header ) {
9 header($header);
10 }
11
12 // Repassa o conteúdo para o nosso cliente
13 fpassthru($handle);
Considerando que estamos apenas testando a funcionalidade. Ter um script de proxy totalmente funcional é
bem mais complexo, e certamente já tem algo pronto por aí.
6. Fazer cálculo com data
Dentre todas as simplificações possíveis, a que mais costuma comover é a função strtotime. Pra quem já
está acostumado, parece que não faz mais do que sua obrigação. Mas pra quem ainda faz cálculos com data
multiplicando por 86400, chega a parecer mágico:
1 echo 'Amanhã: ', strftime('%A', strtotime('tomorrow'));
2 // Amanhã: domingo
3
4 echo 'Próxima segunda: ', strftime('%d de %B de %Y',
5 // Próxima segunda: 01 de junho de 2009
6
7 echo 'Vencimento: ', strftime('%d/%m/%Y', strtotime('+3 months'
8 // Vencimento: 30/08/2009
data:text/html;charset=utf8,%3Cheader%20style%3D%22display%3A%20block%3B%20color%3A%20rgb(51%2C%2051%2C%2051)%3B%20fontfamil… 4/6
26/06/2015 7 coisas simples em PHP que alguns ainda complicam PHPit
Mais exemplos você mesmo pode ver no manual do PHP ou na página de Date Input Formats do projeto
GNU. Para o nome dos meses e dias da semana ficarem em português, utilize setlocale(LC_TIME,
‘pt_BR’); antes de chamar a função strftime.
7. Escapar sql e html
Felizmente nunca mais vi nenhum script com aberrações antisqlinjection, mas há algum tempo era
possível encontrar pessoas removendo palavraschave de SQL de todas as strings que íam para o banco de
dados. Se o usuário digitasse palavras como select, delete ou drop, elas eram simplesmente removidas da
frase. Isso quando o programador não interrompia o script e acusava o usuário de estar tentando explorar
alguma falha de segurança. Eu juro, isso existia.
Ao trabalhar com PDO, a melhor opção (pra não dizer a única!) é utilizar prepare e execute pra separar a
query em si dos seus parâmetros:
1 $conexao = new PDO('mysql:dbname=banco;host=localhost'
2
3 $uf = 'RJ';
4 $idade = 18;
5
6 $sth = $conexao‐>prepare('SELECT nome FROM pessoa WHERE uf = ? AND idade
7
8 $sth‐>execute(array($uf, $idade));
9
10 while ( $row = $sth‐>fetch() ) {
11 echo $row['nome'];
12 }
Se estiver utilizando drivers nativos, veja as
funçõesmysql_real_escape_string ou mysqli_prepare emysqli_stmt_bind_param, dependendo da
extensão. Certamente outros bancos de dados têm a mesma funcionalidade.
A única preocupação é garantir que os parâmetros não se misturem com a query; não precisa inventar moda
e remover o que o usuário digitou.
Outra confusão comum é ao escapar HTML. O objetivo é evitar que o texto digitado por um usuário seja
interpretado pelo browser de todos os usuários do site.
data:text/html;charset=utf8,%3Cheader%20style%3D%22display%3A%20block%3B%20color%3A%20rgb(51%2C%2051%2C%2051)%3B%20fontfamil… 5/6
26/06/2015 7 coisas simples em PHP que alguns ainda complicam PHPit
Conceitualmente, esta é uma responsabilidade da camada de exibição. O template é que deve utilizar
htmlspecialchars antes de gerar a saída na tela, e não antes de salvar no banco. Isso garante que o conteúdo
que está no banco é fiel ao que foi digitado pelo usuário e pode ser reaproveitado em outras mídias além do
HTML.
O que pode e deve ser feito é filtrar conteúdo realmente indevido, como caracteres inválidos ou espaços
extras, dependendo da aplicação.
data:text/html;charset=utf8,%3Cheader%20style%3D%22display%3A%20block%3B%20color%3A%20rgb(51%2C%2051%2C%2051)%3B%20fontfamil… 6/6