PHP Manual
/
Stylistika a konvence

Apostrofy a uvozovky

22. 08. 2019

Obsah článku

Pro ohraničení řetězců je možné použít buď uvozovky nebo apostrofy. Já osobně preferuji pouze **apostrofy**, pokud nejde o speciální znak zalomení řádku nebo tabulátor.

Důvodů je celá řada, pojďme si je konstruktivně projít.

Hlavní důvod, proč uvozovky nepoužívat, je bezpečnost a nevhodná práce s datovými typy.

Použití HTML tagů uvnitř řetězce

Pokud potřebujeme vrátit v řetězci HTML kód a string obalujeme v uvozovkách, tak musíme dost nepříjemně escapovat:

return "<a href=\"{$link}\">{$text}</a>";

Nebo to samé čitelněji se zachováním uvozovek bez escapování:

return '<a href="' . $link . '">' . $text . '</a>';

Delší vizuální vzdálenost řetězce od proměnné

Není nic horšího, než nalepené proměnné uvnitř stringu přímo na sobě, kdy není možné rychle vizuálně poznat, co je proměnná a co string:

$url = "{$baseImageUrl}/{$dirName}/{$basename}.{$ext}";

Tento zápis nemá žádný negativní vliv na funkčnost, jen jsou jednotlivé proměnné a pevné znaky z řetězce nalepeny příliš na sobě, což zhoršuje čitelnost.

Zkusme to znovu a více čitelněji:

$url = $baseImageUrl . '/' . $dirName . '/' . $basename . '.' . $ext;

Hlavní výhodu vnímám hlavně v čistotě kolem proměnných, kdy v názvu nepřekáží žádné zbytečné znaky.

Navíc se to bude i lépe zalamovat a ve stringu nevzniknou znaky zalomení ;)

$url = $baseImageUrl
. '/' . $dirName
. '/' . $basename . '.' . $ext;

Uvnitř uvozovek není možné volat funkci

Ale proměnnou ano, proto se "něco" připojuje ven za řetězec (zejména funkce), ale proměnné se píší zas dovnitř. A někdy programátor i proměnnou připojí za řetězec. Zkrátka zmatek nad zmatek.

Proč nemůžeme věci dělat jednotně?

Nevhodné přetypování jiného datového typu na string

Mějme následující volání funkce:

echo getFullName("{$user->name}");
function getFullName(string $name): string
{
// ... implementace ...
}

Do uvozovek je možné vkládat proměnné, což způsobí jejich přetypování na string. Pokud je ovšem proměnná v řětezci sama a je jiného datového typu, než string, může dojít k poškození informace o původním datovém typu. Kdyby například konstrukce $user->name vracela false nebo null, tak bychom nedokázali poznat, že jde o chybu.

Aplikace by měla vždy rozpoznat chybový stav a správným způsobem selhat, než aby ji ignorovala. Správné hlášení chyb vede k lepšímu debuggování v budoucnu.

Občas se lze setkat i s přetypováním zejména z toho důvodu, že funkce vyžaduje určitý datový typ:

trim("{$returnText}");

V tom případě se spíše přikláním k zápisu:

trim ((string) $returnText);

který nepůsobí tolik "magicky" a je i pro méně zdatné uživatele zřejmé, co se proměnnou stalo.

Zahození hodnoty null z databáze

Dejme tomu, že načítáme název hotelu z databáze:

return "{$row->hotel->name}";

Co když ale název neexistuje a je null? Použitím uvozovek jsme vytvořili potenciálně těžko odhalitelnou chybu, protože dojde k přetypování na prázdný string. My bychom ale rádi vrátili skutečný null. Je totiž rozdíl, když záznam neexistuje, nebo existuje, ale je prázdný.

Správně by se tedy nemělo uvádět nic:

return $row->hotel->name;

Vyžaduje funkce vrácení konkrétního datového typu a je v tomto striktní? Pokud nemůžeme vyhovět zadání, měli bychom vyhodit výjimku.

function getHotelName(int $hotelId): string
{
// implementace
if ($row->hotel->name === null) {
throw new \Exception('Hotel name does not exists.');
}
return $row->hotel->name;
}

Nekonzistence kódování znaků a datových typů

Nezřídka se setkávám s konstrukcí ve smyslu:

echo "{$returnCode}" . self::CRLF;

Kterou je lepší zapsat spíše jako:

echo $returnCode . "\n";

Použití uvozovek kolem proměnné je v tomto případě zbytečné a akorát ztěžují čitelnost, protože jde o další zbytečné znaky navíc. Zároveň zalomování řádků typu CRLF není moderní a je lepší používat jen \n, které je nativní pro kódování UTF-8.

Správně bychom ještě mohli validovat datový typ pro kód. Například, že je číslo a případně vrátit náhradu. To jde ternárním operátorem:

echo (is_int($returnCode) ? $returnCode : '?') . "\n";

Poznámka: Použití funkce is_int() značí nekvalitní návrh aplikace, protože by se nikdy nemělo stát, že neznáme datový typ proměnné.

Obalení výstupního řetězce do apostrofů

Často je potřeba v textu výjimky obalit výstupní řetězec z proměnné do uvozovek nebo apostrofů. Zbytečně tím ovšem vzniká "vyplácání" obojího typu ohraničení řetězců, navíc pokud řetězec začíná i končí stejným znakem, tak není možné v případě více řetězců rychle jednoznačně určit, kde řetězec začal a kde skončil, pokud se uvnitř vyskytne apostrof:

throw new \Exception(__METHOD__ . ": Unsupported data type '{$fileType}'");

Já osobně toto řeším ohraničením do jiného typu znaku (osvědčily se mi hranaté závorky), aby byl elegantně vidět začátek a konec řetězce:

throw new \Exception(__METHOD__ . ': Unsupported data type [' . $fileType . ']');

Nebo:

throw new \Exception("Status '{$status}' is invalid");

Lze vyměnit za:

throw new \Exception('Status [' . $status . '] is invalid');

Parsování po řádcích

Uvozovky jsou vhodné například pro parsování podle nového řádku:

foreach(explode("\n", $text) as $line) {
// implementace
}

Pro tento účel byly speciálně stvořeny.

Nicméně pokud potřebujete zpracovat složitější dokument (například zdrojový kód programovacího jazyka nebo HTML stránku), tak doporučuji používat Tokenizér společně s regulárními výrazy.

Nekombinujte dva způsoby ohraničení

Pokud už z nějakého důvodu uvozovky stejně použijete, tak je aspoň zachovejte v rámci jednotnosti všude.

Toto je odstrašující případ:

throw new \Exception("Image on URL does not exist. ResponseSize: " . strlen($result) . ')');

Kde začátek řetězce ohraničují uvozovky a na konci zase apostrofy.

K tomuto defektu dochází zejména při použití automaticky formátujících nástrojů (například Code Sniffer), které se snaží konvence sjednocovat, ale ne vždy se to podaří.

Jan Barášek   Více o autorovi

Autor článku pracuje jako seniorní vývojář a software architekt v Praze. Navrhuje a spravuje velké webové aplikace, které znáte a používáte. Od roku 2009 nabral bohaté zkušenosti, které tímto webem předává dál.

Rád vám pomůžu:

Související články

1.
4.

Potřebujete poradit s PHP?

Nabízím trénink vývojářů, konzultace, školení a analýzu návrhových vzorů. Osobně v Praze nebo online.

Napište mi, pokud si nevíte rady.

Lektor: Jan Barášek

Status:
All systems normal.
2024