Práce s řetězci

PHP obsahuje velké množství funkcí pro práci s řetězci. Využívají se zejména pro kontrolu zadaných dat ve formulářích. Určitě to znáte, je potřeba omezit délku uživatelského jména, některé znaky zakázat nebo převést a podobně.

Délka řetězce

Na počátku byla funkce strlen(), která vracela počet znaků v řetězci...

<?php

  $Jmeno 
'Tereza';
  echo 
strlen($Jmeno); // Vypíše: 6

?>

Tato funkce pracuje spolehlivě, dokud se používají jednobytová kódování, jakými jsou například Windows-1250 nebo ISO-8859-2. Zdánlivý problém přineslo UTF-8, které pro speciální znaky (například písmenka s diakritikou) používá více bytů. A tak se začaly vyvíjet funkce, které s tím počítají. Modifikovaná funkce vycházející ze strlen(), kterou bychom měli používat, se jmenuje mb_strlen() (předpony mb_ u modifikovaných funkcí znamenají "multibyte"). Do nepovinného druhého parametru se dá napsat kódování, ve kterém předáváme funkci řetězec. Pokud však používáme UTF-8 výhradně, můžeme ho nastavit jako vnitřní kódování pro vícebytové funkce. K tomu slouží funkce mb_internal_encoding(). Stačí ji jednou umístit na začátek skriptu a nemusíte si lámat hlavu s tím, kde všude nastavovat kódování.

<?php

  $Jmeno 
'Tomáš';

  echo 
strlen($Jmeno); // 7 (špatně)
  
echo mb_strlen($Jmeno); // 7 (nejspíše špatně)

  
echo mb_strlen($Jmeno'UTF-8'); // 5 (správně)

  
mb_internal_encoding('UTF-8');
  echo 
mb_strlen($Jmeno); // 5 (ideálně)

?>

V praxi vypadá kontrola přijatého pole formuláře asi takto:

<html>
<body>
  <form action="index.php" method="post">
  Jméno: <input type="text" name="nick" maxlength="20" value="">
  <input type="submit" value="Odeslat">
  </form>
<?php

  mb_internal_encoding
('UTF-8');

  if (isset(
$_REQUEST['nick'])) {
    if (
mb_strlen($_REQUEST['nick']) > 20) {
      echo 
'Přezdívka je příliš dlouhá!';
    }
    else if (
mb_strlen($_REQUEST['nick']) < 3) {
      echo 
'Přezdívka je příliš krátká!';
    }
    else {
      echo 
'Takhle je to správně!';
    }
  }

?>
</body>
</html>

Někdo by se mohl zeptat, proč zbytečně kontrolovat maximální délku, když je u tagu input nastaven atribut maxlength na hodnotu 20. Všechny kontroly na straně serveru jsou ale nesmírně důležité. I když se vám může zdát, že stačí vědět, zda uživatel něco zadal, jste na omylu. Kdokoliv si u sebe může upravit HTML kód stránky, změnit atribut maxlength třeba na 1000 znaků. Stejně tak je špatné spoléhat například na JavaScript, který kontroluje formulářová pole. JavaScript je jistě dobrá věc, slušného uživatele včas upozorní, že na některé pole zapomněl nebo ho vyplnil špatně, ale člověk se zlými úmysly by si ho mohl vypnout a v klidu by mohl propašovat do vaší databáze, co by se mu zachtělo. A kontrolou délky to teprve začíná, důležitý je také formát a povolené znaky...

Ořezání netisknutelných znaků

PHP obsahuje funkce, které odstraní určitě znaky ze začátku, konce, nebo z obou stran řetězce. Zejména mezery, které uživatel nechtěně zadá do formulářového pole, ale také tabulátory (\t), řádkovací znaky (\n a \r) a znak NULL (\0). Z obou stran odstraňuje tyto znaky funkce trim(), pouze zleva ltrim() a pouze zprava rtrim().

<?php

  $Text 
'   Tady máme několik slov.   ';
  echo 
trim($Text); // Vypíše: "Tady máme několik slov."

?>

Výběr části řetězce

Funkce mb_substr() vrací část řetězce (první parametr) určenou druhým, a případně třetím argumentem. Pokud je druhý argument kladný, odpočítá se určitý počet znaků od začátku řetězce, přičemž první znak má číslo 0. Třetí (nepovinný) parametr určuje, na kolikátém znaku řetězec ukončit. Čtvrtý parametr může stejně jako u funkce mb_strlen() určovat kódování předaného řetězce (například "UTF-8").

<?php

  mb_internal_encoding
('UTF-8');

  echo 
mb_substr('pomeranč'2); // Vypíše: "meranč"
  
echo mb_substr('pomeranč'25); // Vypíše: "meran"
  
echo mb_substr('pomeranč'03); // Vypíše: "pom"

?>

Pokud je druhý parametr záporný, začíná se od konce řetězce. Pokud je třetí parametr kladný, odpočítá se příslušný počet znaků doprava.

<?php

  mb_internal_encoding
('UTF-8');

  echo 
mb_substr('pomeranč', -1); // Vypíše: "č"
  
echo mb_substr('pomeranč', -3); // Vypíše: "anč"
  
echo mb_substr('pomeranč', -53); // Vypíše: "era"


?>

Pokud bude třetí parametr záporný, bude ořezán daný počet znaků z konce řetězce.

<?php

  mb_internal_encoding
('UTF-8');

  echo 
mb_substr('pomeranč'0, -4); // Vypíše: "pome"
  
echo mb_substr('pomeranč', -7, -2); // Vypíše: "omera"
  
echo mb_substr('pomeranč'4, -2); // Vypíše: "ra"

?>

V praxi tato funkce najde využití například u knihy návštěv či fóra. Takto omezíme příspěvek na 1000 znaků:

<?php

  mb_internal_encoding
('UTF-8');

  if (isset(
$_REQUEST['zprava'])) {
    if (
trim($_REQUEST['zprava']) === '') {
      echo 
'Musíte zadat text příspěvku!';
    }
    else {
      
$_REQUEST['zprava'] = mb_substr($_REQUEST['zprava'], 01000);
      
/* ... Další práce a uložení do databáze ... */
    
}
  }
  else {
    exit; 
// Ukončení skriptu, uživatel se sem nedostal ze stránky s formulářem.
  
}

?>

Ošetření HTML a speciálních znaků

Jedna z nejdůležitějších funkcí před uložením dat do databáze je htmlspecialchars(). Tato funkce převede některé znaky, které mají v HTML speciální význam (<, >, & a ") na HTML entity, takže se pouze zobrazí, ale nestanou se součástí kódu HTML. To je velmi důležité, kdokoliv by pak přidáním příspěvku ve vaší aplikaci mohl narušit strukturu HTML vaší aplikace.

<?php

  $Zprava 
'<b>text příspěvku</html>';
  
$Zprava htmlspecialchars($Zprava); // Výsledek: "&lt;b&gt;text příspěvku&lt;/html&gt;"

?>

Tato funkce převádí jen ty překlady, které jsou v každodenním programování pro web nejužitečnější. Pokud požadujete překlad všech znakových entit HTML, použijte funkci htmlentities(). Dobré je také vědět, že existuje dekódovací funkce html_entity_decode(), i když ji nejspíše nikdy nevyužijete.

Jsou situace, kdy se hodí z řetězce veškeré HTML (a také PHP) tagy úplně odstranit. K tomu PHP obsahuje funkci strip_tags().

<?php

  $Zprava 
'<b>tučný text a <img src="pic.png" alt="my picture"> obrázek</b>';
  
$Zprava strip_tags($Zprava); // Výsledek: "tučný text a  obrázek"

?>

Pokud se data ukládají do databáze, je potřeba znaky, které by mohly být problémové, opatřit zpětnými lomítky. Jedná se o apostrofy a uvozovky. K tomu slouží funkce addslashes():

<?php

  $Text 
'jmeno = "O\'Neal"';
  
$Text addslashes($Text); // Výsledek: "jmeno = \"O\'Neal\""

?>

Opatření řetězce lomítky před uložením do databáze je nezbytné, avšak využití této je funkce sporné, neboť PHP obsahuje konfigurační direktivu magic_quotes_gpc, která automaticky opatřuje lomítky všechna data přijatá přes HTTP metody GET, POST a cookies. Tato direktiva bývá někdy zapnutá, a v tom případě je použití addslashes() nežádoucí, způsobila by dvojité escapování. Funkce get_magic_quotes_gpc() se může hodit pro ověření nastavení direktivy magic_quotes_gpc.

Osobně však tuto direktivu pokud možno vypínám a používám funkci addslahes(), kde je potřeba. Stejně tak bude používána nadále v této učebnici, takže na to buď dejte pozor, nebo si nastavte v php.ini:

magic_quotes_gpc = Off

Funkce pro odstranění zpětných lomítek se jmenuje stripslashes(). Ta může být použita například tehdy, když je PHP direktiva magic_quotes_gpc nastavena na On (což je výchozí nastavení) a vy tato data nevkládáte na místa (jako je databáze), která toto escapování potřebují. To je například tehdy, když data zadaná do HTML formuláře pouze vypisujete.

<?php

  $Text 
'jmeno = \"O\'Neal\"';
  
$Text stripslashes($Text); // Výsledek: "jmeno = "O'Neal""

?>

Nahrazování

Funkce str_replace() nám umožňuje část řetězce nahradit jiným. První parametr je část řetězce, který má být nahrazen parametrem druhým, třetí parametr pak řetězec, na kterém to bude provedeno. První i druhý parametr mohou být řetězce nebo pole.

<?php

  $Text 
'infranet';
  echo 
str_replace('infra''inter'$Text); // Vypíše: "internet"

  
$Text 'Ovoce a zelenina jsou zdravé potraviny.';
  
$Old = array('Ovoce''zelenina');
  
$New = array('Hamburger''Coca-Cola');

  
$Text str_replace($Old$New$Text);
  echo 
$Text// Vypíše: Hamburger a Coca-Cola jsou zdravé potraviny.

?>

Funkce str_ireplace() je podobná, jen s tím rozdílem, že hledaný řetězec nahradí bez ohledu na velikost písmen.

Občas se také mohou hodit funkce, které převedou malá písmena na velká a opačně. Těmi jsou mb_strtoupper() a mb_strtolower().

<?php

  mb_internal_encoding
('UTF-8');

  
$Text 'nějaký text';

  
$Text mb_strtoupper($Text); // "NĚJAKÝ TEXT"
  
$Text mb_strtolower($Text); // "nějaký text"

?>

Při prvních pokusech (například při tvorbě návštěvní knihy) se vám také bude hodit funkce nl2br(), která převádí odřádkování na XHTML tag <br />. Pokud vyžadujete klasický HTML tag, můžete použít str_replace():

<?php

  $_REQUEST
['zprava'] = str_replace("\r\n""\n"$_REQUEST['zprava']);
  
$_REQUEST['zprava'] = str_replace("\r""\n"$_REQUEST['zprava']);
  
$_REQUEST['zprava'] = str_replace("\n"'<br>'$_REQUEST['zprava']);

?>

Rozdělení řetězce do pole a zpět

Funkce explode() umožňuje rozdělit řetězec jiným řetězcem a vytvořit tak pole. První parametr je dělitel a druhý dělený řetězec. Pole dostane indexy vzestupně od nuly. Třetí nepovinný parametr udává, na kolik maximálně částí může být řetězec rozdělen (zbytek řetězce bude jako poslední prvek pole).

<?php

  $Text 
'To máme dnes ale krásný den.';

  
$Text explode(' '$Text);
  echo 
$Text[4]; // Vypíše: "krásný"

?>

Funkce implode() dělá opak, pole složí v řetězec. První parametr je řetězec, který se vloží mezi jednotlivé prvky a druhý skládané pole.

<?php

  $Text 
= array('To''máme''dnes''ale''krásný''den.');

  
$Text implode(' '$Text);
  echo 
$Text// Vypíše: "To máme dnes ale krásný den."

?>

Tyto funkce by vám měly stačit k tvorbě běžných aplikací, jakými jsou knihy návštěv nebo fóra. Pokud byste se chtěli seznámit se všemi funkcemi pro práci s řetězci, nahlédněte do dokumentace PHP.

Řetězec jako pole znaků

Než se dostaneme k složitým regulárním výrazům, je dobré vědět, že každý řetězec může být brán jako pole, resp. každý znak jako jeden prvek. První znak je přístupný přes index 0 a další se inkrementálně zvyšují.

<?php

  $Text 
'Have a nice day.';

  echo 
$Text[12]; // Vypíše: "d"

  
$Text[6] = 'n';
  
$Text[7] = ' ';

  echo 
$Text// Vypíše: "Have an ice day."

?>

 

« Obsah učebnice