Capítulo 6
Textos espaços e acentos
5 min de leitura 826 palavras 1 gravura
Neste capítulo você vai montar texto e distinguir espaços, bytes e caracteres Unicode.
Seu ponto de partida
Estude depois do capítulo 05. O exemplo deste capítulo é 06-textos-acentos, no pacote que acompanha o volume. Copie a pasta inicio para um diretório de prática e preserve o original. A raiz do exemplo é a referência concluída desta etapa. Sua cópia permite experimentar sem perder a referência.
Execute o PHP na raiz da sua cópia com php -S 127.0.0.1:8000 -t public. Abra http://127.0.0.1:8000/. Não abra PHP por duplo clique nem use o servidor de Python. Encerre com Ctrl+C antes de trocar de etapa.
Como praticar
Leia a explicação e digite ou confira o código indicado. Mude uma coisa. Antes de conferir, anote sua previsão. Salve, recarregue e compare. Se não acontecer o esperado, investigue o erro antes de avançar. Cada experiência parte dos valores da referência. Depois de conferir, desfaça somente a mudança desse experimento antes de começar a próxima lição. Você pode parar depois de uma lição e retomar mais tarde.
Junte peças e preserve a leitura
O ponto concatena, ou junta, duas partes de texto. Um espaço só aparece se estiver dentro de alguma parte. Uma frase montada com variáveis não elimina a necessidade de pontuação.
Os valores desta etapa são fictícios e escritos no arquivo. Antes de receber qualquer texto externo, aprenderemos a saída segura no HTML. Não use esta saída direta para publicar o que outra pessoa enviou.
Faça no seu exemplo
Em public/index.php, localize o bloco indicado. A referência completa acompanha esta etapa.
$nome = "Lia";
$frase = "Olá, " . $nome . ". Boa prática!";
Mude uma coisa e preveja
Retire somente o espaço após a vírgula na primeira parte.
Anote o que você acha que vai acontecer antes de salvar e recarregar.
Recarregue e confira
Olá,Lia fica grudado. Reponha o espaço.
Se não acontecer
Se colocou o espaço fora das aspas, ele não faz parte da string. Confira as peças antes de concatenar.
Trim remove espaços das pontas
Trim devolve uma string sem certos espaços e controles nas pontas. Não corrige ortografia nem remove todos os espaços internos. Guarde seu retorno em outra variável para comparar antes e depois.
Essa limpeza é útil para perceber que um campo com espaços pode ficar vazio. Ela não torna uma mensagem segura para HTML; limpeza e saída segura são tarefas diferentes.
Faça no seu exemplo
Em public/index.php, localize o bloco indicado. A referência completa acompanha esta etapa.
$entrada = " Lia ";
$limpa = trim($entrada);
Mude uma coisa e preveja
Troque somente a entrada por “Lia da Oficina” com espaços nas pontas.
Anote o que você acha que vai acontecer antes de salvar e recarregar.
Recarregue e confira
O espaço entre as palavras permanece; os espaços das pontas são removidos.
Se não acontecer
Se não mudou, confira se mostrou limpa. A variável entrada mantém o valor original.
Acentos podem ocupar vários bytes
UTF-8 codifica caracteres usando um ou mais bytes. Strlen conta bytes, e não letras visíveis. A referência usa mb_strlen quando disponível e uma alternativa Unicode para contar pontos de código.
Um ponto de código também não equivale sempre a um símbolo percebido: certos emojis e letras combinadas usam vários. Para o volume, os limites de formulário serão declarados em caracteres Unicode, sem prometer contar todos os símbolos como um. Salve o arquivo em UTF-8.
Faça no seu exemplo
Em public/index.php, localize o bloco indicado. A referência completa acompanha esta etapa.
$texto = "ação";
$bytes = strlen($texto);
Mude uma coisa e preveja
Troque somente ação por casa.
Anote o que você acha que vai acontecer antes de salvar e recarregar.
Recarregue e confira
Casa tem 4 bytes e 4 caracteres Unicode. Ação tinha 6 bytes e 4 caracteres nesta escrita.
Se não acontecer
Se aparecerem símbolos estranhos, confira a codificação UTF-8 do arquivo e a meta charset da página.

A captura mostra um trecho da referência concluída. Abra e percorra o exemplo para conferir o restante. Experimentos temporários podem produzir outra aparência; restaure os valores indicados antes de comparar.
Atividades para fazer antes das respostas
Use uma nova cópia do exemplo. Tente aplicar o que aprendeu antes de consultar os comentários.
-
Monte uma saudação com dois nomes fictícios.
-
Compare trim de ” ” com trim de “a b”.
-
Explique por que strlen não serve ao limite de letras acentuadas.
Respostas comentadas
Compare sua explicação e o que realmente aconteceu. Outra solução pode funcionar se cumprir o objetivo e preservar o acesso ao conteúdo.
-
Junte os nomes com um espaço escrito entre aspas.
-
A primeira vira string vazia; a segunda mantém o espaço interno.
-
Em UTF-8, um caractere pode ocupar mais de um byte.
Quando seguir
Você junta texto, reconhece limpeza e confere acentos. Se ainda precisa de ajuda, repita a experiência pequena antes de avançar.
O arquivo completo
Referência do exemplo 06-textos-acentos, reproduzida aqui para que você possa conferir sem sair da página.
public/index.php
<?php
declare(strict_types=1);
$nome = "Lia";
$frase = "Olá, " . $nome . ". Boa prática!";
$entrada = " Lia ";
$limpa = trim($entrada);
$texto = "ação";
$bytes = strlen($texto);
$caracteres = function_exists("mb_strlen") ? mb_strlen($texto, "UTF-8") : preg_match_all("/./us", $texto);
?>
<!doctype html>
<html lang="pt-BR">
<head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1">
<title>Livro de visitas de prática</title><link rel="stylesheet" href="estilos.css"></head>
<body><a class="pular" href="#conteudo">Pular para o conteúdo</a>
<header><p>Prática de PHP em pequenos passos</p><h1>Livro de visitas</h1>
<p>Conteúdo fictício. Somente neste computador.</p></header>
<main id="conteudo" tabindex="-1">
<h2>Texto em pequenos passos</h2><p><?= $frase ?></p><p>Original entre colchetes: [<?= $entrada ?>]</p><p>Limpo entre colchetes: [<?= $limpa ?>]</p><p>Texto: <?= $texto ?></p><p>Bytes: <?= $bytes ?>. Caracteres Unicode: <?= $caracteres ?>.</p>
</main><footer><p>Servidor de estudo em 127.0.0.1. Encerre com Ctrl+C.</p></footer></body></html>
public/estilos.css
* { box-sizing: border-box; }
body { margin: 0; background: #f4f7fb; color: #203246;
font: 1.05rem/1.65 Arial, sans-serif; }
header, main, footer { max-width: 48rem; margin-inline: auto; padding: 1.5rem; }
header { padding-top: 2.5rem; }
h1 { font-size: clamp(1.8rem, 5vw, 2.7rem); line-height: 1.2; }
main { background: #fff; border-radius: .8rem; }
article { border-top: 1px solid #cad4df; padding-block: 1rem; }
a { color: #124e77; text-underline-offset: .2em; }
nav { display: flex; flex-wrap: wrap; gap: 1rem; }
label { display: block; font-weight: bold; }
input:not([type=hidden]), textarea { width: 100%; max-width: 34rem;
border: 2px solid #718095; border-radius: .35rem; padding: .7rem;
font: inherit; color: inherit; background: #fff; }
button { font: inherit; background: #124e77; color: white;
border: 0; border-radius: .35rem; padding: .75rem 1.2rem; cursor: pointer; }
button:hover { background: #103b59; }
.mensagem { white-space: pre-wrap; overflow-wrap: anywhere; }
.erros { color: #8b142c; }
.ok { color: #175c30; font-weight: bold; }
:focus-visible { outline: 3px solid #b04d00; outline-offset: 3px; }
.pular { position: absolute; left: -10000px; }
.pular:focus { position: static; display: block; padding: 1rem; background: white; }
@media (max-width: 35rem) { header,main,footer { padding: 1rem; } }