Minulý týden jsem zveřejnil Test znalostí konfiguračních direktiv PHP, dnes přináším jeho řešení:
connect.inc.php. Co je špatného na kódu include "connect.inc.php" a jak ho opravit?Kód se spoléhá na to, že direktiva include_path bude obsahovat
.(aktuální adresář) na prvním místě seznamu (pokud by v jiném adresáři určeném pro vkládání existoval souborconnect.inc.php, použil by se ten). Kód se tedy dá opravit pomocíinclude "./connect.inc.php", čímž se i nepatrně zrychlí. Pokud by se jednalo o skript spouštěný z příkazové řádky z jiného adresáře, bylo by nutné psátinclude rtrim(dirname(__FILE__), "\\/") . "/connect.inc.php".
if (isset($_GET["search"])) echo htmlspecialchars($_GET["search"])?Kód předpokládá vypnutou direktivu magic_quotes_gpc. Dále předpokládá, že kódování dokumentu nebude UTF-7 nebo UTF-16.
fopen("http://www.example.com/favicon.ico", "r") a čím se dá nahradit?Kód nebude fungovat při vypnuté direktivě allow_url_fopen a dá se nahradit funkcí fsockopen:
<?php $fp = fsockopen("www.example.com", 80); fwrite($fp, "GET /favicon.ico\r\n"); fwrite($fp, "Host: www.example.com\r\n"); fwrite($fp, "Connection: close\r\n"); fwrite($fp, "\r\n"); ?>Při zpracování se ale budeme muset poprat s hlavičkami, především
Transfer-Encoding: chunked. Na některých hostinzích je také funkce fsockopen zakázaná. Další možnost je použít rozšíření CURL.
header("Content-Type: image/png"); echo file_get_contents("obrazek.png")?Může doplatit na zbytečnou direktivu magic_quotes_runtime.
<?php if (isset($_POST["nazev"]) && isset($_GET["id"])) { $nazev = (get_magic_quotes_gpc() ? $_POST["nazev"] : addslashes($_POST["nazev"])); mysql_query("UPDATE tabulka SET nazev = '$nazev' WHERE id = " . intval($_GET["id"])); } ?>
Kód se spoléhá na to, že je vypnutá direktiva magic_quotes_sybase a správně by měl vypadat takto:
<?php if (isset($_POST["nazev"]) && isset($_GET["id"])) { $nazev = mysql_real_escape_string(get_magic_quotes_gpc() ? stripslashes($_POST["nazev"]) : $_POST["nazev"]); mysql_query("UPDATE tabulka SET nazev = '$nazev' WHERE id = " . intval($_GET["id"])); } ?>
<% %><? ?><?php ?><script language="php"> </script>Nejpřenositelnější způsob zápisu kódu je
<?php ?>nebo<script language="php"> </script>, protože první dva se dají zakázat direktivami asp_tags resp. short_open_tag.
Měl by informovat o výstupním kódování. Stará se o to direktiva default_charset nebo funkce
header("Content-Type: text/html; charset=utf-8").
echo "Vítejte"; session_start()?Pokud není zapnutá direktiva output_buffering, tak je nutné všechny hlavičky odeslat ještě před začátkem výstupu. Funkce session_start hlavičky posílá, proto může způsobit chybu.
if (isset($HTTP_GET_VARS["id"])) { }?Může doplatit na vypnutou direktivu register_long_arrays.
echo $PHP_SELF nejspíš nic nevypíše?Je to proto, že direktiva register_globals bývá obvykle vypnutá.
hledat.php?jmeno=Franta vypíše kód echo $_REQUEST["jmeno"], pokud bylo na předchozí stránce zavolané setcookie("jmeno", "Pepa")?Záleží to na hodnotě direktivy variables_order a samozřejmě také na tom, jestli má uživatel povolené cookies.
Maximální velikost souboru je <?php echo ini_get("upload_max_filesize"); ?> B?Maximální velikost souboru se bohužel určuje složitěji.
<?php $row = mysql_fetch_assoc(mysql_query("SELECT jmeno FROM uvizvatele")); if ($row) { $jmeno = $row[jmeno]; } ?>
Spoléhá se na vypnutou úroveň chyb E_NOTICE a neexistenci konstanty
jmeno.
$_SESSION["navsteva"] = (isset($_SESSION["navsteva"]) ? $_SESSION["navsteva"] + 1 : 1);?Pokud není zapnutá direktiva session.auto_start, tak je potřeba práci se session proměnnými nejprve zapnout funkcí session_start.
header("Location: http://$_SERVER[SERVER_NAME]/hotovo.php"), pokud používáme session proměnné a chceme podporovat i uživatele bez cookies?Do parametrů URL musíme přidat konstantu SID.
tabulka?
<?php $result = mysql_query("SELECT * FROM tabulka"); while ($row = mysql_fetch_assoc($result)) { // zpracování } ?>
Pokud je zapnutá direktiva mysql.trace_mode, tak se musí všechny výsledky zavřít funkcí mysql_free_result.
getimagesize($_FILES["obrazek"]["tmp_name"]). Za jakých okolností se to nemusí povést a jak to napravit?Pokud je direktiva upload_tmp_dir nastavena na cestu mimo open_basedir, tak funkce skončí chybou. Napravit se to dá přesunutím nahraného souboru pomocí move_uploaded_file a teprve následným testováním obrázku.
Oddělovač řádků je platformově závislý, takže nemusí fungovat na Apple.
Ahoj! a na druhém Povedlo se to?Problém je v tom, že řádky v e-mailu musí být oddělené znaky
\r\n, ale některé Unixové programy na tuto posloupnost automaticky překládají znak\n. Pokud tedy použijeme samotné\n, tak může skončit i na výstupu, pokud použijeme\r\n, může na výstupu skončit\r\r\n. Pro přenositelné posílání e-mailů tedy na funkci mail bohužel musíme zapomenout a použít přímo SMTP třeba přes PEAR Mail.