Bem-vindo à aula 53 do curso de PHP! Hoje vamos explorar funções avançadas de string que vão muito além do básico. Você aprenderá a formatar strings de forma precisa com sprintf, a manipular números e textos com funções de formatação, a lidar com caracteres multibyte (como acentos e emojis) usando a extensão mbstring, e a entender os conceitos de encoding por trás dessas operações. Essas habilidades são essenciais para desenvolver aplicações robustas e internacionalizadas.

Dominar essas funções não é apenas uma questão de conhecer a sintaxe, mas de entender quando e por que usá-las. Por exemplo, ao trabalhar com dados de usuários em diferentes idiomas, você precisará de funções multibyte para evitar erros de codificação. Ao gerar relatórios ou logs, a formatação com sprintf pode tornar seu código mais legível e seguro. Vamos mergulhar em cada tópico com exemplos práticos e dicas de boas práticas.

sprintf

A função sprintf é uma das mais poderosas para formatação de strings. Ela permite criar uma string formatada a partir de um modelo, substituindo placeholders por valores. A sintaxe básica é sprintf($formato, $arg1, $arg2, ...). Os placeholders começam com % e são seguidos por especificadores de tipo, como %s para string, %d para inteiro, %f para float, entre outros.

Além do tipo, você pode especificar a largura mínima, precisão, preenchimento e alinhamento. Por exemplo, %05d preenche com zeros à esquerda até completar 5 dígitos. %-10s alinha à esquerda em um campo de 10 caracteres. Isso é extremamente útil para gerar relatórios alinhados, códigos de barras, ou simplesmente para evitar concatenação manual propensa a erros.

$nome = 'João';
$idade = 30;
$saldo = 1234.567;

// Formatação básica
echo sprintf('Olá, %s! Você tem %d anos.', $nome, $idade);
// Saída: Olá, João! Você tem 30 anos.

// Preenchimento com zeros
echo sprintf('Código: %05d', 42); // Código: 00042

// Precisão de float
echo sprintf('Saldo: R$ %.2f', $saldo); // Saldo: R$ 1234.57

// Alinhamento à esquerda
$produtos = ['Maçã' => 2.5, 'Banana' => 1.2];
foreach ($produtos as $produto => $preco) {
    echo sprintf('%-10s %6.2f', $produto, $preco) . PHP_EOL;
}
// Saída:
// Maçã          2.50
// Banana        1.20

Outra vantagem do sprintf é que ele permite reutilizar o mesmo argumento várias vezes, usando a sintaxe %1$s para referenciar o primeiro argumento. Isso é útil quando você precisa repetir um valor na string sem passá-lo novamente.

$cidade = 'São Paulo';
echo sprintf('Eu moro em %1$s e %1$s é uma cidade grande.', $cidade);
// Saída: Eu moro em São Paulo e São Paulo é uma cidade grande.

Funções de formatação

Além de sprintf, o PHP oferece outras funções de formatação que facilitam a vida. Vamos ver algumas das mais úteis: number_format para formatar números com separadores de milhar e decimais, str_pad para preencher strings até um tamanho específico, e str_repeat para repetir uma string várias vezes.

Essas funções são especialmente úteis em aplicações financeiras, relatórios e interfaces de usuário, onde a apresentação dos dados é crucial. Por exemplo, number_format permite exibir preços com duas casas decimais e ponto como separador de milhar, conforme o padrão brasileiro.

$valor = 1234567.891;

// Formatação padrão (ponto para decimais, vírgula para milhar)
echo number_format($valor, 2, ',', '.'); // 1.234.567,89

// Sem separador de milhar
echo number_format($valor, 2, ',', ''); // 1234567,89

// str_pad: preenche com caracteres até o tamanho
$codigo = '123';
echo str_pad($codigo, 8, '0', STR_PAD_LEFT); // 00000123

// str_repeat: repete uma string
echo str_repeat('-=', 10); // -= -= -= -= -= -= -= -= -= -=

Outra função interessante é strtr para traduzir caracteres, e wordwrap para quebrar linhas em um texto. Vamos ver um exemplo de wordwrap:

$texto = "PHP é uma linguagem de script poderosa, amplamente utilizada para desenvolvimento web.";
echo wordwrap($texto, 30, "\n");
// Quebra em linhas de até 30 caracteres

mb_* (multibyte)

As funções multibyte (mb_*) são essenciais quando trabalhamos com textos que contêm caracteres fora do conjunto ASCII, como acentos, caracteres de idiomas como japonês, chinês, ou emojis. A extensão mbstring deve estar habilitada no PHP (geralmente está na maioria das instalações).

O problema com funções tradicionais como strlen e substr é que elas contam bytes, não caracteres. Em UTF-8, um caractere pode ocupar de 1 a 4 bytes. Por exemplo, 'é' ocupa 2 bytes. Usar strlen em uma string com acentos retornará o número de bytes, não o número de caracteres visíveis. As funções mb_* resolvem isso considerando o encoding.

$texto = 'Olá, mundo! 😀';

// strlen conta bytes (cada acento e emoji pode ter múltiplos bytes)
echo strlen($texto); // 18 (dependendo do encoding)

// mb_strlen conta caracteres
echo mb_strlen($texto, 'UTF-8'); // 13

// substr vs mb_substr
$sub = substr($texto, 0, 3); // 'Ol' (corta no meio do caractere?)
$mb_sub = mb_substr($texto, 0, 3, 'UTF-8'); // 'Olá'

// mb_strtoupper e mb_strtolower
echo mb_strtoupper('café'); // CAFÉ

// mb_strpos
echo mb_strpos('coração', 'a'); // 2 (posição correta em caracteres)

Além dessas, há funções como mb_str_split para dividir em caracteres, mb_convert_case para converter maiúsculas/minúsculas com suporte a títulos, e mb_detect_encoding para detectar o encoding de uma string. Sempre que você for manipular strings que possam conter caracteres não-ASCII, prefira as funções mb_*.

Encoding

Encoding (ou codificação de caracteres) é o sistema que mapeia caracteres para bytes. O encoding mais comum na web hoje é o UTF-8, que suporta todos os caracteres do Unicode. No PHP, é crucial garantir que suas strings estejam no encoding correto, especialmente ao interagir com bancos de dados, arquivos e APIs.

A função mb_convert_encoding converte uma string de um encoding para outro. Por exemplo, converter de ISO-8859-1 (latin1) para UTF-8. Isso é comum ao ler arquivos antigos ou dados de bancos de dados legados.

$textoLatin = 'Coração';
$textoUtf8 = mb_convert_encoding($textoLatin, 'UTF-8', 'ISO-8859-1');
echo $textoUtf8; // Coração em UTF-8

// Verificar se é UTF-8 válido
if (mb_check_encoding($textoUtf8, 'UTF-8')) {
    echo 'Encoding válido';
}

// Detectar encoding
$encoding = mb_detect_encoding($textoUtf8, ['UTF-8', 'ISO-8859-1'], true);
echo $encoding; // UTF-8

Outras funções úteis: htmlentities e htmlspecialchars convertem caracteres especiais em entidades HTML, o que é essencial para evitar XSS ao exibir dados do usuário. Lembre-se de sempre especificar o encoding ao usar essas funções, por exemplo, htmlspecialchars($str, ENT_QUOTES, 'UTF-8').

Boas práticas e observações finais

Ao trabalhar com strings em PHP, adote estas práticas:

  • Use aspas simples para strings simples e aspas duplas quando precisar de interpolação, mas evite interpolação complexa; prefira sprintf.
  • Para strings multibyte, sempre use funções mb_* e especifique o encoding 'UTF-8' explicitamente.
  • Certifique-se de que seu arquivo PHP está salvo em UTF-8 sem BOM e que as conexões com banco de dados usem UTF-8.
  • Valide e sanitize toda entrada de usuário, usando htmlspecialchars ao exibir.
  • Teste suas funções com strings contendo acentos e emojis para garantir compatibilidade.

Referências

Exercícios

  1. Crie uma função que receba um nome e um valor, e retorne uma string formatada usando sprintf no formato: "Cliente: [nome] - Total: R$ [valor]" com o valor tendo duas casas decimais e vírgula como separador decimal.

    ✓ Resposta:
    function formatarCliente($nome, $valor) {
        $valorFormatado = number_format($valor, 2, ',', '.');
        return sprintf("Cliente: %s - Total: R$ %s", $nome, $valorFormatado);
    }
    echo formatarCliente('Maria', 1234.5); // Cliente: Maria - Total: R$ 1.234,50
  2. Dada a string "Programação em PHP", use mb_strlen para contar os caracteres e mb_substr para extrair os primeiros 5 caracteres. Imprima ambos.

    ✓ Resposta:
    $str = 'Programação em PHP';
    echo mb_strlen($str, 'UTF-8'); // 16
    echo mb_substr($str, 0, 5, 'UTF-8'); // Progr
  3. Converta a string "Olá, mundo!" para maiúsculas usando uma função multibyte e depois substitua todas as vogais por 'X' usando uma função de substituição que respeite o encoding.

    ✓ Resposta:
    $str = mb_strtoupper('Olá, mundo!', 'UTF-8');
    // Substituir vogais por X
    $str = mb_ereg_replace('[aeiouáéíóúâêîôûãõ]', 'X', $str);
    echo $str; // XLÁ, MUNDX!
  4. Escreva um script que detecte o encoding de uma string "café" e, se não for UTF-8, converta para UTF-8. Use mb_detect_encoding e mb_convert_encoding.

    ✓ Resposta:
    $str = 'café';
    $enc = mb_detect_encoding($str, ['UTF-8', 'ISO-8859-1'], true);
    if ($enc !== 'UTF-8') {
        $str = mb_convert_encoding($str, 'UTF-8', $enc);
    }
    echo $str; // café em UTF-8
  5. Usando sprintf, crie uma string que exiba um número inteiro com 5 dígitos, preenchido com zeros à esquerda, e um float com 2 casas decimais, separados por um hífen. Exemplo: 00042-3.14

    ✓ Resposta:
    $int = 42;
    $float = 3.14159;
    echo sprintf('%05d-%.2f', $int, $float); // 00042-3.14