Filtros e funções de string avançadas
Nesta aula, você aprenderá a dominar funções avançadas de string em PHP, incluindo formatação com sprintf, funções de formatação como number_format e str_pad, manipulação de strings multibyte com mb_*, e conceitos de encoding. O conteúdo é prático, com exemplos de código e exercícios para consolidar o aprendizado.
Bem-vindo à aula 53 do nosso curso de PHP. Até agora, você já conhece as funções básicas de strings, como strlen, substr, str_replace, entre outras. Nesta aula, vamos elevar o nível, explorando funções avançadas que permitem formatar strings de maneira sofisticada, trabalhar com caracteres multibyte (como acentos e emojis) e entender como o PHP lida com diferentes encodings. Esses conhecimentos são essenciais para desenvolver aplicações robustas, internacionalizadas e seguras.
Vamos começar com uma das funções mais poderosas para formatação de strings: sprintf. Em seguida, veremos outras funções de formatação, depois entraremos no mundo das funções mb_* (multibyte), e finalizaremos com uma discussão sobre encoding, onde entenderemos a diferença entre ASCII, UTF-8 e outros. Prepare-se para muita prática e exemplos que você pode testar imediatamente.
sprintf
A função sprintf é uma das ferramentas mais versáteis do PHP para criar strings formatadas. Ela recebe uma string de formato e uma lista de argumentos, e retorna a string formatada. O formato define onde e como cada argumento deve ser inserido, usando especificadores de conversão que começam com %.
Os especificadores mais comuns são: %s para string, %d para inteiro, %f para float, %x para hexadecimal, entre outros. Você também pode especificar largura, precisão, preenchimento e alinhamento. Por exemplo, %05d preenche um número inteiro com zeros à esquerda até completar 5 dígitos. Isso é muito útil para gerar códigos, números de pedido, etc.
// Exemplo básico de sprintf
$nome = 'Maria';
$idade = 30;
$mensagem = sprintf('Olá, %s! Você tem %d anos.', $nome, $idade);
echo $mensagem; // Olá, Maria! Você tem 30 anos.
// Preenchimento com zeros
$codigo = sprintf('%05d', 42);
echo $codigo; // 00042
// Float com precisão
$preco = 49.95;
$formatado = sprintf('R$ %.2f', $preco);
echo $formatado; // R$ 49.95
// Alinhamento à esquerda com largura
$alinhado = sprintf('%-10s|', 'nome');
echo $alinhado; // nome |
// Usando argumentos nomeados (PHP 8)
$resultado = sprintf('O %1$s correu %2$d km e depois %1$s descansou.', 'João', 5);
echo $resultado; // O João correu 5 km e depois João descansou.
Além de sprintf, existe a função printf, que imprime diretamente a string formatada, e sscanf, que faz o inverso: lê uma string e extrai valores conforme o formato especificado. Essas funções são amplamente usadas em relatórios, logs, geração de arquivos e até em consultas SQL (embora não seja recomendado para SQL por questões de segurança).
Funções de formatação
Além de sprintf, o PHP oferece outras funções úteis para formatar strings e números. Vamos destacar algumas:
number_format: formata um número com milhares separados e decimais.str_pad: preenche uma string com caracteres até atingir um tamanho específico.str_repeat: repete uma string várias vezes.str_word_count: conta o número de palavras em uma string.ucwords: coloca em maiúscula a primeira letra de cada palavra.strtoupperestrtolower: convertem para maiúsculas e minúsculas (cuidado com encoding).
// number_format
$numero = 1234567.891;
echo number_format($numero, 2, ',', '.'); // 1.234.567,89
// str_pad
$codigo = 'ABC';
echo str_pad($codigo, 10, '0', STR_PAD_LEFT); // 0000000ABC
// str_repeat
echo str_repeat('-=', 10); // -=-=-=-=-=-=-=-=-=-=
// str_word_count
$frase = 'O rato roeu a roupa do rei.';
echo str_word_count($frase); // 7
// ucwords
echo ucwords('joão da silva'); // João Da Silva
Essas funções são simples, mas muito poderosas quando combinadas. Por exemplo, você pode usar number_format para exibir valores monetários, str_pad para criar códigos de barras ou IDs com largura fixa, e str_repeat para gerar separadores visuais em logs.
mb_* (multibyte)
Strings em PHP são sequências de bytes. Quando trabalhamos com caracteres acentuados, como “ã”, “ç”, ou até emojis, cada caractere pode ocupar mais de um byte. As funções tradicionais como strlen e substr contam bytes, não caracteres, o que pode causar problemas. Para resolver isso, o PHP oferece a extensão mbstring, cujas funções começam com mb_ e operam com base em caracteres, respeitando o encoding.
É fundamental usar as funções mb_* quando sua aplicação lida com UTF-8 (ou outro encoding multibyte) para evitar corromper strings. Por exemplo, mb_strlen retorna o número de caracteres, enquanto strlen retorna o número de bytes. Da mesma forma, mb_substr extrai uma parte da string com base em caracteres, e mb_strpos encontra a posição de uma substring considerando caracteres.
// Diferença entre strlen e mb_strlen
$texto = 'coração';
echo strlen($texto); // 8 (bytes)
echo mb_strlen($texto); // 7 (caracteres)
// mb_substr
$sub = mb_substr('Olá mundo', 0, 3);
echo $sub; // Olá
// mb_strtoupper
$maiusculas = mb_strtoupper('coração');
echo $maiusculas; // CORAÇÃO (preserva o ç)
// mb_strpos
$pos = mb_strpos('Olá mundo', 'mundo');
echo $pos; // 4 (posição em caracteres)
Outras funções importantes incluem mb_strtolower, mb_convert_case, mb_detect_encoding e mb_check_encoding. Sempre que você for manipular strings que possam conter caracteres não-ASCII, prefira as funções mb_*. Isso é especialmente importante em formulários, processamento de texto e internacionalização.
Encoding
Encoding (ou codificação de caracteres) é o sistema que mapeia caracteres para bytes. O ASCII é o mais básico, usando 7 bits, mas não suporta caracteres acentuados. O ISO-8859-1 (Latin-1) adiciona acentos, mas ainda é limitado. O UTF-8 é o encoding mais usado atualmente na web, pois suporta todos os caracteres do Unicode, incluindo emojis, e é compatível com ASCII.
No PHP, é crucial garantir que suas strings estejam no encoding esperado, especialmente ao interagir com bancos de dados, APIs e arquivos. Funções como mb_convert_encoding permitem converter entre encodings, e mb_detect_encoding tenta detectar o encoding de uma string. Além disso, a função htmlspecialchars deve ser usada com o parâmetro de encoding correto para evitar vulnerabilidades XSS.
// Convertendo de ISO-8859-1 para UTF-8
$texto = 'cora\u00e7\u00e3o'; // Na prática, seria uma string em ISO-8859-1
$utf8 = mb_convert_encoding($texto, 'UTF-8', 'ISO-8859-1');
// Detectando encoding
$encoding = mb_detect_encoding($texto, ['UTF-8', 'ISO-8859-1'], true);
echo $encoding; // UTF-8 ou ISO-8859-1
// Verificando se é UTF-8 válido
if (mb_check_encoding($texto, 'UTF-8')) {
echo 'É UTF-8 válido';
}
// Usando htmlspecialchars com encoding
$seguro = htmlspecialchars($texto, ENT_QUOTES, 'UTF-8');
Uma boa prática é sempre definir o encoding no início do script com mb_internal_encoding('UTF-8') e usar a configuração default_charset no php.ini. Além disso, ao enviar headers HTTP, use header('Content-Type: text/html; charset=UTF-8'); para garantir que o navegador interprete corretamente.
Boas práticas e observações finais
Ao trabalhar com strings avançadas, lembre-se de:
- Use sempre
mb_*para funções que envolvem comprimento, posição ou extração, a menos que você tenha certeza de que a string é ASCII pura. - Prefira
sprintfpara montar mensagens dinâmicas, em vez de concatenar, pois é mais legível e evita erros de espaçamento. - Valide e normalize o encoding de entradas de usuários para evitar problemas de segurança e funcionalidade.
- Teste suas funções com caracteres acentuados e emojis para garantir que funcionam como esperado.
Com essas ferramentas, você pode criar aplicações mais robustas e preparadas para o mundo real. Vamos praticar com os exercícios abaixo.
Exercícios
Escreva uma função que use
sprintfpara formatar um número de telefone no formato(XX) XXXX-XXXX, recebendo como parâmetro um inteiro de 10 dígitos.✓ Resposta:function formatarTelefone($numero) { $numero = sprintf('%010d', $numero); // Garante 10 dígitos return sprintf('(%s) %s-%s', substr($numero, 0, 2), substr($numero, 2, 4), substr($numero, 6)); } echo formatarTelefone(11987654321); // (11) 9876-54321Use
number_formatpara exibir o número 1234567.891 com 2 casas decimais, ponto como separador de milhar e vírgula como separador decimal.✓ Resposta:echo number_format(1234567.891, 2, ',', '.'); // 1.234.567,89Crie uma função que receba uma string e retorne o número de caracteres (não bytes) usando
mb_strlen. Teste com a string "Olá, mundo!" e com um emoji.✓ Resposta:function contarCaracteres($str) { return mb_strlen($str, 'UTF-8'); } echo contarCaracteres('Olá, mundo!'); // 12 echo contarCaracteres('😀'); // 1Converta a string "Olá, mundo!" de UTF-8 para ISO-8859-1 usando
mb_convert_encodinge depois de volta para UTF-8. Explique o que acontece com os caracteres acentuados.✓ Resposta:$utf8 = 'Olá, mundo!'; $iso = mb_convert_encoding($utf8, 'ISO-8859-1', 'UTF-8'); // Agora $iso contém a string em ISO-8859-1, onde 'á' é representado por um byte 0xE1. $deVolta = mb_convert_encoding($iso, 'UTF-8', 'ISO-8859-1'); // $deVolta é igual a $utf8 original, pois a conversão é reversível.Escreva um código que verifique se uma string é UTF-8 válida usando
mb_check_encoding. Teste com uma string válida e uma inválida (por exemplo, uma string com bytes que não formam UTF-8).✓ Resposta:$valida = 'Olá, mundo!'; $invalida = "\xC3\x28"; // sequência inválida var_dump(mb_check_encoding($valida, 'UTF-8')); // bool(true) var_dump(mb_check_encoding($invalida, 'UTF-8')); // bool(false)