Odkazování na sebe sama

Školení, která pořádám

V PHP je k dispozici několik obratů, jak se soubor může odkazovat sám na sebe. Kromě „konstanty“ __FILE__, která vždy obsahuje absolutní cestu k aktuálně zpracovávanému souboru (hodí se např. tehdy, když chceme vložit soubor ve vložené knihovně: include dirname(__FILE__) . "/soubor.inc.php"), je definováno ještě několik $_SERVER proměnných. Následující platí pro Apache, u jiných serverů by to mělo být obdobně.

podmínkypožadavek / 'REQUEST_URI''PHP_SELF''SCRIPT_NAME'
DirectoryIndex index.php/?a/index.php/index.php
AcceptPathInfo/item.php/clanek-1?a/item.php/clanek-1/item.php
ErrorDocument/clanek-1?a/item.php/item.php
RewriteEngine/clanek-1?a/item.php/item.php
PHP-clitest/item.php / nenastavenotest/item.php od PHP 4.3.0test/item.php

Pro vytvoření absolutního URL na související soubor (např. pro hlavičku Location nebo pro poslání e-mailem), se často používá funkce dirname. Ta má však tu nevýhodu, že pro kořenový adresář vrací / a v jiném případě řetězec lomítkem neukončuje. Lepší je proto použít např. tento zápis:

<?php
header("Location: http://$_SERVER[SERVER_NAME]" . substr($_SERVER["PHP_SELF"], 0, strrpos($_SERVER["PHP_SELF"], "/")) . "/");
?>

Skripty pak bez problémů fungují jak v kořenovém adresáři webového serveru, tak v podadresáři.

Za zmínku stojí také proměnná 'SERVER_NAME'. Pokud mě paměť neklame, byla v prastarých verzích PHP nastavena na hodnotu gethostbyname($_SERVER["SERVER_ADDR"]), takže se při použití VirtualHost nedala použít a bylo nutné se spoléhat na 'HTTP_HOST'. Tato proměnná ale zase není k dispozici při použití HTTP/1.0. Nyní by proměnná 'SERVER_NAME' měla obsahovat vždy tu správnou hodnotu.

Odkazování na sebe sama se často používá u atributu <form action>. Pokud ale skriptu např. nechceme předat nějaké další parametry, stačí jako hodnotu použít prázdný řetězec. Jak píše Sean Coates, je potřeba proměnnou 'PHP_SELF' ošetřit stejně jako ostatní uživatelská data.

Jakub Vrána, Výuka, 21.12.2005, diskuse: 7 (nové: 0)

Diskuse

ikona dgx:

Možná by ještě stálo za to do tabulky vložit případ, kdy se volá skript např. "xyz/index.php?params", který není v URI uveden, tedy "xyz/?params".

Jinak používání dirinfo(__FILE__) nebo realpath(dirinfo(__FILE__)) je tak časté, že by stálo za zvážení vytvoření magické konstanty jako __DIR__ :-)

ikona Jakub Vrána OpenID:

Díky za tip, doplnil jsem to.

Místo dirinfo() máš na mysli asi dirname().

Jirka Bráza:

Použití prázdného řetězce ve form action je zrádné - jako cílové URL se totiž odešle URL aktuální, včetně GET parametrů. Pokud tedy stránka obsahující formulář obsahuje nějaké  parametry předané přes GET, a nevyplním action u formuláře, jsou tato data odeslána také. Často to nemusí znamenat nic, ale někdy to má důsledky, které se fakt těžko hledají.

Franta:

To bohužel nefunguje (zrovna by se mi to hodilo) – po odeslání formuláře se GET parametry (?foo=bar&xxx=yyy) ztratí a nová URL obsahuje jen ty parametry, které jsou explicitně uvedené ve formuláři.

Zbyněk:

já to mám napsané takto a vždy to funguje:
<?php
echo "<form method=\"post\" action=\"{$_SERVER["PHP_SELF"]}?{$_SERVER["QUERY_STRING"]}\">";
?>

ikona Jakub Vrána OpenID:

To je špatně z několika důvodů. Jednak to neřeší daný problém, kde se požaduje odeslání metodou GET. Dále PHP_SELF i QUERY_STRING jsou podstrčitelné, takže musí být ošetřeny funkcí htmlspecialchars().

zbyněk:

ano, máte pravdu, špatně jsem si to přečetl, takže jsem byl trochu vedle..

Vložit příspěvek

Používejte diakritiku. Vstup se chápe jako čistý text, ale URL budou převedeny na odkazy a PHP kód uzavřený do <?php ?> bude zvýrazněn. Pokud máte dotaz, který nesouvisí s článkem, zkuste raději diskusi o PHP, zde se odpovědi pravděpodobně nedočkáte.

Jméno: URL:

avatar © 2005-2016 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.