Escapování

Článek vyšel v rámci PHP okénka na serveru Root.cz.

V PHP jsou tři základní escapovací funkce, které se používají v různých situacích: addslashes, htmlspecialchars a urlencode.

Funkce addslashes se používá většinou při ukládání dat do databáze. Funkce doplní zpětné lomítko před apostrof, uvozovky a zpětné lomítko, takže text obsahující tyto znaky obalený apostrofy nebo uvozovkami může být bez obav použit v SQL dotazu. Při ukládání proměnných zvenku tuto funkci používejte pouze v případě, že není zapnutá direktiva magic_quotes_gpc, jinak dojde k dvojitému escapování. Některé databáze (např. MySQL) si vystačí s touto funkcí i při ukládání binárních dat, jiné pro escapování těchto dat potřebují použít vlastní funkci – např. SQLite používá funkci sqlite_escape_string.

Funkce htmlspecialchars se používá při vypisování textu, ve kterém nechceme interpretovat HTML značky – řídící znaky <>"& se převedou na odpovídající HTML entity – tedy např. < na &lt;. Použití této funkce by mělo být samozřejmostí při vypisování neošetřeného textu a při používání proměnných v hodnotách atributů HTML značek, např. value.

<?php
// špatně - proměnná může obsahovat speciální HTML znaky
echo "<input name='search' value='$_GET[search]' />\n";

// špatně - proměnná může obsahovat apostrof
echo "<input name='search' value='" . htmlspecialchars($_GET["search"]) . "' />\n";

// správně - případné uvozovky jsou spolu s ostatními speciálními znaky defaultně escapovány
echo "<input name=\"search\" value=\"" . htmlspecialchars($_GET["search"]) . "\" />\n";

// správně - escapován bude i apostrof
echo "<input name='search' value='" . htmlspecialchars($_GET["search"], ENT_QUOTES) . "' />\n";
?>

Funkci htmlspecialchars je zvykem používat na výstupu, i když by ji z výkonnostních důvodů bylo někdy lepší použít např. už při ukládání dat do databáze. Nedělá se to ze dvou důvodů – jednak by kvůli větší délce escapovaného textu mohl být řetězec zkrácen přesto, že uživatel maximální délku nepřekročil, a jednak by někdo do databáze mohl nestandardním způsobem vložit neošetřená data, která by při výpisu způsobila paseku. Zkrácení řetězce může mít závažné důsledky, pokud k němu dojde uprostřed HTML entity – v extrémním případě to může vést až k nezobrazení celé stránky.

Funkce urlencode se používá při ošetřování řetězce předávaného v URL. Funkce nahradí všechny nealfanumerické znaky kromě -_. jejich URL reprezentací – tedy znakem % následovaným dvojicí hexadecimálních číslic (mezera se převede na +). Pokud tedy chceme vytvořit přehled nejčastěji hledaných výrazů, měli bychom to udělat nějak takhle:

<?php
$result = mysql_query("SELECT search, pocet FROM searches ORDER BY pocet DESC LIMIT 10");
while ($row = mysql_fetch_assoc($result)) {
    echo "<li><a href='?search=" . urlencode($row["search"]) . "'>" . htmlspecialchars($row["search"]) . "</a> ($row[pocet])</li>\n";
}
mysql_free_result($result);
?>

Kromě těchto základní escapovacích funkcí v PHP samozřejmě existují další, např. quotemeta nebo preg_quote. Vždycky jde o to zamyslet se nad tím, jestli v daném kontextu náhodou nejsou některé znaky speciální a pokud ano, tak je správně ošetřit. Podle mého názoru je správné escapování jedna z vlastností, které odlišují kvalitní webové aplikace od těch ostatních.

Jakub Vrána, Výuka, 27.4.2005, on-line

Diskuse

DFly:

a take rawUrlEncode()
27.4.2005 23:30:08

Kuba:

Jen malá poznámka ke zvýrazňovači php kódu - nevím proč není kód vypisován neproporcionálním fontem. Rozlišit znakové sekvence "' a '" je takhle dost netriviální (já to dělám tak, že označuju znak po znaku myší :o)
23.11.2005 12:20:41

ikona Jakub Vrána:

Proporcionální písmo se mi lépe čte a vejde se ho na stejné místo víc. Lepší rozlišování "' od '" to nepřeváží.
23.11.2005 13:20:09

Kuba:

No, já nevím, ale u všech kódů je to tak nějak zvykem...
23.11.2005 14:30:49

wyvern:

tak proc tu neudelat nejaky vtipni tlacitko, kterym si budu moct prepnout mezi proporcialni a neproporcialnim..? klidne by na to stacil nejakej jednoduchej javascript...
15.5.2006 14:00:17

Jakub:

Tiez to tak robim:)
8.5.2006 16:32:11

assimilate:

K uvedeným příkladů, a varianta

<?php echo '<input name="search"
value="'
,htmlspecialchars( $_GET['search'] ),'" />'; ?>

Správně? Špatně?
7.6.2006 10:08:07

Martin Sirovy:

Take to pisu takto + pouzivam pokud je to v parametru ENT_QUOTES, tak by me take zajimalo jestli je to ok. Dalsi vec jestli pokud pouzivam apostrofy je nutne psat & jako entitu &amp; nebo staci jen &. Doufam, ze se dockame odpovedi. BTW musim pochavalit autora, nacerpal jsem z tohoto webu hodne uzitecnych tipu .]
4.3.2007 13:11:30

ikona Jakub Vrána:

ENT_QUOTES je nutné používat uvnitř hodnoty atributů uzavřené do apostrofů. & je nutné psát jako &amp; vždy.
5.3.2007 11:09:11

Martin Sirovy:

Ok, děkuji za odpověď. Tento to kod je tedy v poradku: <?php echo '<input name="search"
value="'
,htmlspecialchars( $_GET['search'] ),'" />'; ?>
6.3.2007 17:50:44

kozotoč:

<?php echo'<input name="search"
value="'
.htmlspecialchars($_GET['search']).'" />'?>

je i o pár ns rychlejší, protože se nemusí řešit případné escapování a desubstituce proměnných mezi dvojitými uvozovkami. pozor, stringy odděluje tečka (afaik).
24.5.2007 02:24:09

Megaloman:

Tečka je operátor, který stringy neodděluje, ale spojuje, u konstruktu echo lze tečky nahradit čárkami, což je teprve operátor, který odděluje stringy.

Ovšem v tomto případě na tom nezáleží, protože výsledný výstup bude tak jako tak stejný...
5.8.2008 05:52:55

ikona Jakub Vrána:

Je to vžitý omyl. Konstantní řetězec je stejně rychlý v apostrofech jako v uvozovkách.
5.8.2008 06:00:34

kozotoč:

Mýlíš se. V příkladu je sice použit konstantní řetězec, ale obsahuje \ a tokeny za ním musí PHP na rozdíl od apostrofového řetězce parsovat. Výrok, že s použitím apostrofů je syntaktická analýza ''o pár nanosekund rychlejší'' je tedy pravdivý. Nehledě na optickou „ošklivost” takového řetězce a potenciální si přidělávání problémů, že to někde zapomenu escapovat a budu muset složitě pátrat kde.
25.8.2008 22:30:48

ikona Jakub Vrána:

Apostrofový řetězec přeci také může obsahovat zpětné lomítko. Nejlepší asi bude to změřit:
<?php
for ($i=0; $i < 1e6; $i++) "abc\"def"; // 0.630249977112
for ($i=0; $i < 1e6; $i++) 'abc"def'; // 0.63881611824
?>
Jedná se o samostatné spuštění jednotlivých variant a medián ze tří pokusů.
26.8.2008 02:52:20

ikona v6ak:

Myslím si sice, že pro výkonovou optimalizaci je málo podstatné, zda používám apostrofy nebo uvozovky, myslím, že používáš špatnou metodu testování (bavím se o php4 a vyšším, ne o php3). Kód se parsuje na začátku asi do nějakého vykonávacího stromu (zde bych použil Composite, ale nevím, jak to je v php). Přitom se IMHO parsují i řetězce a při vykonávání pak není poznat rozdíl mezi řetězci s jinou syntaxí. Pokud chceš porovnávat dobu parsování, pak je potřeba použít jiný prostředek, třeba eval, tady by bylo jeho použití IMHO namístě (i když T9 mi nabízí f*ck :-D ). Momentálně nemůžu otestovat, nemám po ruce php, jen javascript, C  a Brainfuck.

IMHO však budou apostrofy nepatrně rychlejší, nemusí očekávat $. Ale to záleží na algoritmu.
26.8.2008 05:30:00

ikona Jakub Vrána:

Výrok, že syntaktická analýza je o pár ns rychlejší, je pravdivý, původní komentář ale ne - celkový běh je rychlejší s uvozovkami.

Pokud se totiž bavíme o výkonnosti, je doba parsování zanedbatelná, protože při použití akcelerátoru se parsuje jen jednou, zato vykonává se opakovaně.
26.8.2008 05:44:11

ikona David Grudl:

Když se oba řetězce přeloží na stejný opcode, tak nemůže být v běhu rozdíl. BTW akcelerátory se používají naprosto sporadicky.
26.8.2008 06:39:43

ikona Jakub Vrána:

Jaká je příčina rozdílu, netuším - prostě jsem to změřil. Máš pravdu, že se to přeloží na stejný opcode.

Akcelerátory se u projektů, kterým přestává stačit jeden server, používají zcela běžně. Na sdíleném webhostingu samozřejmě méně.
26.8.2008 07:03:29

ikona David Grudl:

Ještě k větě "při použití akcelerátoru se parsuje jen jednou, zato vykonává se opakovaně" - asi trošku slovíčkařím, ale pokud se nepletu, přítomnost akcelerátoru na serveru (např. Zend Optimizeru nebo ionCube loaderu) neznamená použití opcode cache. Třeba Zend Optimizer se dá najít na řadě sdílených webhostingů, akceleruje vykonávání skriptů, ale jako opcode cache začne fungovat až po zakoupení encoderu ($960 je stále dost ;)

ps. Jednou jsem změnil jedno písmenko v názvu nepoužívané proměnné třídy a výkon se zhoršil o 5 %. Je to magie!
26.8.2008 08:39:05

ikona Jakub Vrána:

Otázka je, čemu říkáme akcelerátor. Já tak říkám třeba eAcceleratoru, u kterého je ukládání zkompilovaného kódu pro další použití hlavním úkolem.

A ano, pouhá přítomnost akcelerátoru na serveru ukládání kompilace nezajistí. Např. v situaci, kdy je na serveru APC a není zapnuté apc.enabled :-).
26.8.2008 08:47:21

ikona v6ak:

No pokud kde o běh, tak jsem to pochopil jako že to je cca nastejno. A taky nechápu, proč by se to mělo lišit, když ve stromu to bude nejspíš vypadat naprosto identicky. Pokud máš nějaký důvod, sem s ním!
OT: Ta moje T9 je tak deformovaná, že když jsem psal 'sem', napsala 'PDO' :-D
26.8.2008 06:45:19

kozotoč:

Páni, ty máš rychlou mašinu. Udělal jsem taky test - z toho, co máš jako příklad v článku.
<?php
$_GET
['search']="a\"b'c\\d\ne";
$t1=microtime(true);
for(
$i=0;$i<1e6;$i++)$a="<input name=\"search\" value=\"" . htmlspecialchars($_GET["search"]) . "\" />";
$t2=microtime(true);
for(
$i=0;$i<1e6;$i++)$a='<input name="search" value="' . htmlspecialchars($_GET["search"]) . '" />';
$t3=microtime(true);
die((
$t2-$t1).' s vs '.($t3-$t2));
?>

Vyhodilo mi to:

2.0504870414734 vs 1.9555149078369
26.8.2008 23:04:51

kozotoč:

zkoušel jsem to několikrát (i na začátku jsem inicializoval $a, ($a='';) aby se neřeklo, že se v prvním cyklu musela poprvé vytvořit) a konstantně je případ s apostrofy více než o 1/10 sekundy (tj o více než 100 nanosekund na jeden výskyt) rychlejší.

ještě odpověď na "Apostrofový řetězec přeci také může obsahovat zpětné lomítko": ano, ale zde syntaktický analyzátor PHPka nemusí odskočit na tu část jeho kódu, která by zjišťovala, co vlastně že za ním může být.

Chápu, že se toto může zpracovávat různě (jinak do syntaktického stromu, jinak při Just-In-Time compilaci), ale i tak platí, že uvozovková notace s escapovanýma uvozovkama je celkově o pár ns pomalejší, opticky ošklivější a náchylnější k bugům vzniklým zapomenutím zpětného lomítka.
26.8.2008 23:21:24

ikona Jakub Vrána:

Syntaktický analyzátor funguje nějak takhle:
<?php
$state
= "INIT";
for (
$i=0; $i < strlen($s); $i++) {
    $state = $states[$state][$s{$i}];
}
?>
Složitost je tedy lineární vzhledem k délce kódu. To je taky jediný důvod, proč je apostrofová varianta v tomto případě rychlejší – má méně znaků.

"Odskok na jinou část kódu", o kterém mluvíš, je zadarmo, protože prozkoumání tabulky pro zpětné lomítko zabere stejně času jako prozkoumání tabulky pro apostrof.
27.8.2008 04:53:17

kozotoč:

Jakube, prosim tě: přestaň už mlžit a uznej taky jednou svou chybu, že používání textových literálů s apostrofovou notací je celkově (z pohledu rychlosti, optického vzhledu v kódu, náchylnosti k vytovření syntaktické chyby) výhodnější než používání literálů uvozovkových. Vážím si tvé práce, ale tadytímhle „maloJardováním” ztrácíš kredit.
29.8.2008 12:33:28

ikona Jakub Vrána:

Nemlžím a proti apostrofům nic nemám. Nemám ovšem nic ani proti uvozovkám, takže jestli po mě chceš slyšet odsouzení uvozovek, tak se ho nedočkáš. Žádné chyby si nejsem vědom. Chyby vidím v tomto vlákně dvě:

http://php.vrana.cz/escapovani.php#d-4733 (špatný závěr)
http://php.vrana.cz/escapovani.php#d-6982 (špatná metodika)

Autorem těchto příspěvků ovšem nejsem já.
30.8.2008 05:23:22

kozotoč:

mno, ale reagovat bych přecijenom mohl.

http://php.vrana.cz/escapovani.php#d-6970 (špatná metodika)
23.8.2009 01:58:50

Karel:

Hele, už toho fakt nech a jdi programovat v apostrofech ;-)
Konstantní řetězce (tedy ty, kde není žádná proměnná), které jsou ve dvojitých uvozovkách, se nijak nedesubstituují a jejich zpracování není nijak handicapované oproti apostrofovým. (v tom ses mýlil)

Pokud jsou v jedné notaci řetězce oproti té druhé zpětná lomítka navíc (tj. zbytečně), pak zabere jistý (ale naprosto zanedbatelný) čas zabere jejich první zpracování ve fázi 'parse' (což Jakub připustil) a ve fázi 'execute' se použije stejný bytecode (stejně "rychle"), nezávisle na tom, v jakých uvozovkách řetězec byl. (což je pokud to dobře chápu Jakubova první reakce na tebe v této diskuzi)
23.8.2009 02:22:18

ikona David Grudl:

Čas věnovaný této diskusi byl větší, než kolik by se ušetřilo předěláním všech uvozovek ve všech PHP aplikacích :-)
27.8.2008 09:27:12

ikona Jakub Vrána:

Nemůžeš přeci porovnávat dobu běhu kódu na začátku skriptu a na jeho konci… Zkoušel jsi varianty prohodit (tedy nejdřív vyzkoušet apostrofy, potom uvozovky)?

Když chceš porovnat dva kusy kódu, musíš to dělat za stejných podmínek – tedy vytvořit dva skripty obsahující pouze testovaný kód a potom je za stejných podmínek spustit.

Já jsem to udělal a výsledky jsou tyto:
<?php
for($i=0;$i<1e6;$i++)$a="<input name=\"search\" value=\"" . htmlspecialchars($_GET["search"]) . "\" />"; // 1.4262650013
for($i=0;$i<1e6;$i++)$a='<input name="search" value="' . htmlspecialchars($_GET["search"]) . '" />'; // 1.4782140255
?>
Jedná se o samostatné spuštění jednotlivých variant a medián ze tří pokusů.
27.8.2008 04:39:54

kozotoč:

Vyhodnocení uvozovkového literálu, který za zpětným lomítkem může mimo několika znaků (jako \t \n) mít (krom jiného) jedno, nebo dvě, nebo tři oktalová číslice nebo x a dvě hexadecimální číslice, není to samé jako apostrofový literál, kde se kontroluje jen apostrof pro ukončení.

Btw. udělal jsem přesně ten samý test, stejnou metodou, jakou popisuješ, a pro uvozovkový literál mi to vyhazuje 3.8289790153503 a pro apostrofový 3.7983191013336 sekund.

Přiznej už prosimtě, konečně, že ses zmýlil - není to žádná ostuda.
29.8.2008 12:48:28

ikona Jakub Vrána:

Už jsem to vysvětloval v příspěvku http://php.vrana.cz/escapovani.php#d-6985. Syntaktickému analyzátoru je úplně jedno, kolik znaků má v daném kontextu nějaký význam. Prostě načte znak a změní stav podle tohoto načteného znaku. Čas změny stavu je konstantní a tedy nezávislý na počtu významových znaků.

Výsledky se mohou lišit, to připouštím. Mě se ale shodují na třech různých počítačích, dvou různých operačních systémech (Windows XP, Linux) a dvou verzích PHP (5.2.6, 5.1.6). A zaráží mě, že tobě vyšly úplně jiné časy než v testu http://php.vrana.cz/escapovani.php#d-6982.

A jak už jsem psal, chyby v tomto vlákně vidím dvě, ani jednu ode mě.
30.8.2008 05:42:00

kozotoč:

Můj výrok v prvním ze dvou příspěvků, které označuješ jako chybné, ("...o pár nanosekund rychlejší...") je pravdivý, protože v tomto případě zpracovávají čtyři uzovovky přes \ navíc (přestože by nemusely).
To, čím argumentuju já, má 3 body, druhý z nich je optický vzhled dané notace a třetí je náchylnost k syntaktickým chybám a zdržení a řešení toho "kde jsem zapomněl zpětné lomítko nebo kde mi přebývá uvozovka". V 2/3 a 3/3 je na tom uvozovková notace hůř a tedy celkově (to, co mám na mysli) je na tom uvozovková notace hůř než apostrofová.
(Po žádném odzusování (ani tvém osobním názoru na obě notace) jsem netoužil.)
p.s. ad druhá chyba v threadu.. někam se "ztratil" tvůj post, který ji kritizuje (???)
9.9.2008 19:24:47

ikona Jakub Vrána:

Jak prokázaly tři měření na různých počítačích, operačních systémech a verzích PHP, tak výrok pravdivý není.

Největší tvůj omyl spočívá v názoru, že uvozovkový literál se nutně musí zpracovat pomaleji, protože může přejít do více stavů než apostrofový. Dokud nepochopíš, že na počtu možných stavů nezáleží a záleží jen na délce vstupu, tak je jasné, že se se mnou budeš hádat.

To, že samotná syntaktická analýza je rychlejší (ale výhradně kvůli kratšímu vstupu), jsem nikde nerozporoval a naopak jsem tento fakt podpořil v příspěvku http://php.vrana.cz/escapovani.php#d-6973.

O tom, že apostrofy jsou v tomto případě pěknější a méně náchylné k chybám, jsem se taky nikde nepřel.

Post se nikam neztratil, je na http://php.vrana.cz/escapovani.php#d-6984.
10.9.2008 04:24:08

kozotoč:

//muj test dle http://php.vrana.cz/escapovani.php#d-6982 (prvni polovina pro kazdou variantu zvlast, 1. fetch nemeren, zprumerovane)
2.1177170276642 " 2.0763738155365 ' // localhost, WinXP
1.02556681633 " 1.10180020332 ' // flyweb.cz, linux
1.06299996376 " 1.04999709129 ' // flyweb.cz jiny server, linux
1.87020397186 " 1.90944814682 ' // pipni.cz, 2x Xeon 3.20 GHz HT, predpokladam linux (tady bylo zajimave, ze tam byly velke vykyvy - i treba 0.5 s)
8.11.2008 05:52:38

ikona David Grudl:

Jak na tom může být obecně uvozovková notace hůř k náchylnosti k chybám a optické čitelnosti? Co když potřebuješ do řetežce zapisovat apostrofy? Co když potřebuješ zapsat znak tabulátoru nebo oddělovače řádků?
10.9.2008 05:42:35

ikona Jakub Vrána:

Já myslím, že to nebylo myšleno obecně, ale jen pro tento konkrétní případ.
10.9.2008 05:45:27

kozotoč:

ano, pokud potřebuju vypsat tabulátor, nový řádek, tak samozřejmě použiju uvozovky.

myslel jsem ale případ v tomto článku, např. u použité části řetězce

"<input name=\"search\" value=\""

není opravdu důvod používat uvozovkovou notaci - asi se shodneme na tom, že

'<input name="search" value="'

je lepší. Zejména tam, kde uvozovka v uvozovkami uvozeném řetězci začíná nebo končí, nebo tam, kde se v něm vyskytují vedle sebe mnoho " a \, tam mohou (subjektivně, vjemově) nastávat "zmatky".
8.11.2008 07:09:17

ikona Jakub Vrána:

S tím se dá souhlasit. Důvod použití uvozovek v tomto příkladě je ten, že na konci se používá \n, takže na konci je vhodnější mít uvozovky – z důvodu konzistence jsou i na začátku.
10.11.2008 03:19:45

kozotoč:

p.s. v tomhle vláknu vidím chyby ode mně a pak od jedno člověka, který je neumí přiznat. a to mně mrzí :-(
9.9.2008 23:07:06

ikona Jakub Vrána:

Ale já opravdu nevidím žádnou chybu, které bych se dopustil. Můžeš mi ji prosím ukázat?
10.9.2008 04:26:27

kozotoč:

Je to v prvních našich vzájemných komentářích na začátku tohoto threadu. Spočívá ve vzájemném nepochopení obecného versus konkrétního použití apostrofů/uvozovek, resp. sémantická chyba v odpovídání na něco jiného než vytyčená otázka/komentář/problém. Já chybu přiznal, ty jako lektor tohoto jazyka a člověk, který mu „perfektně rozumí” nemusíš, protože bys ztratil tvář. (Ta fráze v uvozovkách jsou tvoje slova z http://php.vrana.cz/php-cli.php . Pro mě perfektně = dokonale (počeštění z angličtiny), bez nejmenší chybičky, což implikuje i znalost všech jeho syntaktických elementů, metod, rozšíření, funkcí (viz. např. zde http://php.vrana.cz/kodovani-hlavicek-e-mailu.php#d-3684) apod. Já osobně bych si v životě nedovolil něco takového vypustit z huby, ale ty budeš něco víc.)
8.11.2008 06:12:43

ikona Jakub Vrána:

Samozřejmě také dělám chyby a nemám problém je přiznat. V této diskusi ale opravdu žádné své nevidím. Odkaž mi prosím na příspěvek, kde jsem se chyby dopustil. Obecné „vzájemných komentářích na začátku tohoto threadu“ mě vede k příspěvku http://php.vrana.cz/escapovani.php#d-4733, kde vidím pravdivý výrok „je i o pár ns rychlejší“ zdůvodněný nepravdivým tvrzením „nemusí se řešit případné escapování a desubstituce proměnných“. V další diskusi se zabývám tímto nepravdivým výrokem.
10.11.2008 03:18:01

pojízdná kočka:

Inu, Jakube, on má kozotoč pravdu v tom, že buď nějakému jazyku rozumíš dokonale (a pak si můžeš dovolit to napsat), nebo [v něm] děláš chyby (a nemáš problém je přiznat). Nic moc mezi tím.

(p.s. tvůj komentář je o 2 dny starší než ty ve stejné úrovni pod ním, přesto je před nima. čím to?)
25.2.2009 12:18:53

ikona Jakub Vrána:

Ještě ty tady... I když člověk něčemu perfektně rozumí, tak v tom může udělat chybu. A já ji nemám problém přiznat. Jistě bys našel něco, na čem bys mě nachytal, ale v této diskusi to opravdu nevidím.

Příspěvky jsou zdánlivě nesprávně seřazeny proto, že spodní dva mají hloubku 10 a 11 a můj má hloubku 11. Takže jsou seřazeny správně, ale aby se nerozpadl design, tak je maximální zobrazovaná hloubka 10. Tento příspěvek má hloubku 13 a to by prosím už opravdu stačilo.
25.2.2009 15:26:04

pojízdná kočka:

Já bych přecejen něco chybného od tebe viděla:
kozotoč ti na začátku tohoto threadu vytknul v 3. řádku (počítáno bez komentářů) 2 zpětná lomítka, která jsou tam zbytečně (oproti apostrofové notaci). Později v diskuzi, když jsi to chtěl demonstrovat na příkladu, jsi tam použil jen jednu uvozovku. Byť se jedná o jeden jediný znak, toto je podle mě špatná metodika (možná záměrně?) a manipulace.
18.8.2009 01:54:52

ikona Jakub Vrána:

Zpětná lomítka jsem použil proto, aby byl kód konzistentní - aby v půlce řádku nebyly apostrofy a v půlce uvozovky. Nepovažuji to ale za nic důležitého, jindy bych to možná napsal jinak.

Na příkladu jsem chtěl ukázat, že zpětné lomítko se vyhodnotí už při kompilaci a při spuštění se provádí stejný bajtkód. Nezáleží na tom, kolik tam těch zpětných lomítek je.
18.8.2009 08:17:26

pojízdná kočka:

Myslím, že nemáš tak docela pravdu - víc lomítek => víc času pro PHP kompilátor, který stráví na jejich převádění. Já vím, že v tomto případě jde o nanosekundy, ale nota bene to je přesně to, čím argumentoval kozotoč na začátku tohoto threadu.
23.8.2009 01:38:29

pojízdná kočka:

"buď nějakému jazyku rozumíš dokonale (…) nebo [v něm] děláš chyby"

Jakub Vrána: "I když člověk něčemu perfektně rozumí, tak v tom může udělat chybu."

Jakube, netvrdil jsi, že mu rozumíš, ale že mu rozumíš dokonale.
Tady jsi použil manipulace patří mezi logické klamy. Tento logický klam, kterého ses dopustil, se nazývá podsunutý argument. (https://cs.wikipedia.org/wiki/Argumenta%C4%….28straw_man.29 )
14.4.2016 22:11:25

ikona Jakub Vrána:

Z jednoduchého min(30, 3*$hloubka) jsem výpočet změnil na 10 * log(3 + $hloubka) - 10, což by mělo strukturu diskuse zachovat a přitom design nezdeformovat.
9.3.2009 06:30:00

kozotoč:

oprava: v tom, že jde o nanosekundy, by se dalo souhlasit, v tom, že se desubstituce zabírá u dvojitých uvozovek extra čas, pravdu neměl.
23.8.2009 01:42:17

Karel:

Tohle se mi přestává líbit. Jakubovy stránky jsou výborný zdroj pro začínající i pokročilé PHPčkaře; neměli bychom zacházet k osobním útokům a dělat z toho flamewars mimo dané téma.
8.11.2008 06:52:24

kozotoč:

O.K. – mír. Pochopil jsem a uznávám 1/3 toho, co jsem vytknul: že použití uvozovek bez zbytečných vnořených uvozovek je přinejmenším stejně rychlé jako apostrofové řešení.
8.11.2008 06:56:26

kriplozoik:

speciální případ je, když necháme uživatele zadat něco, co pak vyhledáváme v databázi přes LIKE (procento, podtržítko) nebo REGEXP (hafo dalších znaků, viz též funkce quotemeta).
9.3.2008 03:54:03

ikona v6ak:

Jak jsme už psali, kód je v php4+ nejdříve celý parsován a pak celý vykonáván, takže takovéto měření nemá smysl, teoreticky by mělo vyjít oboje stejně. Jediná možnost by byla použít eval nebo podobný trik, kterým bychom změřili dobu parsování. Ale možná bychom museli zvýšit počet průběhů, abychom odstranili vedlejší vlivy. Nejlépe spustit php v reálném čase. Na to je ideální minimální Linux nezatížený GUI a zbytečnými službami. PHP bych spouštěl z příkazového řádku, ne z apache.
Pak by asi byl vidět rozdíl mezi uvozovkama a apostrofama.
29.8.2008 13:57:02

ikona Jakub Vrána:

Tento druh měření má smysl při použití akcelerátoru - tehdy se kód parsuje (a kompiluje) jen jednou a zpracovává se opakovaně. Souhlasím, že by měření mělo podle mých znalostí teoreticky vyjít stejně, ale nevychází - na různých platformách, operačních systémech i verzích PHP. Příčinu neznám.

Všechny testy samozřejmě spouštím z příkazového řádku.
30.8.2008 05:46:00

ikona v6ak:

V php3 se kód postupně parsuje a vykonává. V php4+ bez akcelerátoru se nejdřív celý zparsuje a pak celý vykoná. Je to parsování na jedno použití. (Použití neznamená průběh.) Akcelerátor by uschoval výsledek parsování pro další použití. Nevím, jak akcelerátory pracují s evalem, spíš na to kašlou.
Já jsem chtěl měřit právě dobu parsování, protože právě tam by měl být rozdíl, takže akcelerátor, pokud by si poradil s evalem, by tu byl na škodu.
30.8.2008 07:49:42

cpbbt:

Tak to jsem blázen. Poslední dvě možnosti pracují naprosto identicky. Moc tomu nerozumím.
26.9.2008 15:44:18

Michal:

URL escapuji pomoci urlencode(). Ale kdy použít rawurlencode(). Rozdíl je v escapovaní mezery ale fakt nevím kdy by se mohla funkce rawurlencode hodit?
4.12.2011 14:02:01

Ogara:

Tak to vypada, ze fce magic_quotes_gpc uz je mrtva, ma nejakou nahradu nebo neni zadna potreba? :)
5.2.2014 20:44:36

v6ak:

Čistě terminologicky, magic_quotes_gpc není funkce, ale konfigurační direktiva.

Dnes to vypadá, že magic_quotes_gpc je snad již naštěstí mrtvá. Kdysi jsem se nad tím dost rozčiloval, je to nesystémové řešení. Programátor pak musel rozlišovat, odkud ta hodnota vlastně přišla (zkuste si pak v aplikaci udělat trošku abstrakce...) a celé to vedlo spíše ke zmatku.

Když bychom měli z nějakého důvodu používat staré API, tak addslashes nebo o něco lépe mysql_real_escape_string. Pokud ale půjde o novou aplikaci, použil bych spíše PDO, Nette Database, Nette Database Table, Dibi (nicméně vývoj byl přesunut směřem k Nette Database), nebo další takové knihovny, které nabízejí pohodlnější řešení.
6.2.2014 08:39:28

ikona Jakub Vrána:

magic_quotes_gpc=1 se dá nahradit pomocí filter.default=magic_quotes, ale nedoporučoval bych to. Jde o to, že data se ošetřují v nevhodný okamžik ještě před tím, než se rozhodne o tom, zda se vůbec budou posílat do databáze. Navíc je lepší zvolit lepší abstrakci (např. vázání proměnných) a data ručně vůbec neošetřovat.

Pro zpětnou kompatibilitu lze použít opak skriptu na http://php.vrana.cz/vypnuti-magic_quotes_gpc.php.
8.2.2014 04:00:28

pitr03:

Zdravím... Narazil jsem na problém, jak pomocí FPutS() uložit text v azbuce do TXT souboru, tak aby se dal znovu přečíst. Asi to s problematikou escapování úplně nesouvisí, ale uvítal bych radu. Díky...
30.3.2014 08:47:22

ikona Jakub Vrána:

Důležité je použít správné kódování. Pokud se skripty posílají s hlavičkou Content-Type: text/html; charset=utf-8 a kódování UTF-8 se používá i na všech ostatních místech, tak všechno obvykle funguje správně.
1.4.2014 06:54:08

Romana:

Pokud funkce addslashes pridava zpetne lomitko, nemela by se jmenovat addbackshashes. Dekuji za zpracovni pripominky. Szalayova romana.szalayova@seznam.cz
4.8.2015 11:31:26
avatar © 2005-2024 Jakub Vrána. Publikované texty můžete přetiskovat pouze se svolením autora. Ukázky kódu smíte používat s uvedením autora a URL tohoto webu bez dalších omezení Creative Commons. Můžeme si tykat. Skripty předpokládají nastavení: magic_quotes_gpc=Off, magic_quotes_runtime=Off, error_reporting=E_ALL & ~E_NOTICE a očekávají předchozí zavolání mysql_set_charset. Skripty by měly být funkční v PHP >= 4.3 a PHP >= 5.0.