- Materiály ke studiu PHP
- Kde hledat víc informací
- Tematicky zaměřené odkazy
- PHP 7
- Výkonnost aplikace
- Escapování
- Uvozovky
- Regulární výrazy
- Návrh aplikace
- Cron
- Řešení nejčastějších chyb
- Parse error: syntax error, …
- Warning mysql_*: supplied argument is not a valid MySQL result resource…
- Headers already sent…
- Nefungují proměnné z formuláře nebo z URL (vypnuté register globals)
- Lomítka ve vstupních hodnotách
- Kam zmizelo odřádkování za „
?>
“ - Allowed memory size... (Překročení paměti)
- Jak něco udělat
- Získaní IP adresy
- Jak předat proměnnou vkládanému souboru
- Co dávat a co nedávat do uvozovek
- Práce s XML
- Kódování e-mailu, aneb abychom neposílali otazníky.
- Odeslání více položek
- Rekurzivní zipování
- Registrace uživatelů
- Solený hash
- Výpis výsledků z databáze (nebo z jiného zdroje) do tabulky o více sloupcích
- Odlišení lichých a sudých řádků
- Upload souborů
- Vypsání náhodného obrázku
- Nadpis skupiny nejen při výpisu z databáze
- Jak získat zpět text zakódovaný přes MD5 (SHA-1, SHA-256, …)?
- Jak na funkci „zapomenuté heslo“, když mám jen otisk (hash) hesla?
- Zkrácení článku pro výpis perexu
- Testování mailů na localhostu
- Záloha databáze
- Komunikace mezi javascriptem a PHP
- Jak přenést proměnnou z javascriptu do PHP
- Jak přenést proměnnou z PHP do javascriptu
- Rozdíl ve viditelnosti cookies při vytvoření javascriptem a PHP
- Konfigurace PHP
- Nalezení správného php.ini souboru
- Konfigurace PHP pomocí .htaccess
- Zapnutí výpisu všech chyb a varování
- Více verzí PHP na jednom počítači
- Správné kódování v PHP
- Jaké kódování použít pro pro stránku anebo pro ukládání do databáze?
- Divný znak (čtvereček) na začátku includovaného souboru v UTF-8
- Zastaralé (deprecated) funkce
- Co to je?
- Mám kód přesně podle návodu a přesto vidím tuto hlášku
- Kdy přestanou fungovat?
Materiály ke studiu PHP# Kde hledat víc informací• Především PHP manuál (php.net), anglicky. Reference jazyka, reference funkcí. Nevíte, jak funguje nějaká funkce? Určitě ji vyhledejte v manuálu, např. explode().• Rozpracovaná učebnice PHP od členů djpw Základní kurz 1: Úvod. • Pokročilejší články a moderní trendy ve vývoji aplikací v PHP lze najít na Zdrojáku s nálepkou PHP (databáze). • Kdysi dobrý, ale dnes zastaralý PHP tutoriál (linuxsoft.cz). Je psán pro PHP 4, v současnosti nebudou jeho scripty s defaultním nastavením fungovat. Inspirujte se, ale neberte vše doslova. • Mírně pokročilejší témata: PHP triky, phpFashion. • Anglicky psané net.tutsplus.com/category/tutorials/php, phpmaster.com/category/php-tutorials a nikic's Blog • MySQL: MySQL Documentation (anglicky), MySQL >= 4.1 a čeština • SQLite: SQLite.org • Slepice nebo vejce? Podobně věčná je i otázka jestli používat framework, než založite vlastní téma, přečtěte si Framework: Ano, či ne?, pokud se pro nějaký framework rozhodnete, s výběrem může pomoci Best PHP Framework for 2015 - SitePoint Survey Results. Tematicky zaměřené odkazy# PHP 7• Stručná prezentace novinek v PHP 7• Detailní přehled změn v PHP 7 I pokud vás nezajímají nové vlastnosti, měla by vás zajímat změna těch starších. • Throwable Exceptions and Errors in PHP 7 - Aaron Piotrowski • PHP: rfc:remove_deprecated_functionality_in_php7, zdůrazňuji konec ext/mysql .
# Výkonnost aplikace• Disproving the Single Quotes Performance Myth# EscapováníEscapování - definitivní příručka# Uvozovky# Regulární výrazyOnline testování a stručný přehledPodrobné shrnutí syntaxe, návody a hotová řešení Seriál na rootu V PHP používejte funkce z rodiny preg_, skupina ereg_ je deprecated (tj. zavržená, v dalších verzích bude zrušena). Pro testování shody a získání výsledků preg_match() a preg_match_all(). Pro úpravy řetězce preg_replace(). Modifikátory v PHP manuálu. Další odkazy: Regulární výrazy na wikipedii phpfashion.com/zradne-regularni-vyrazy-v-php # Návrh aplikaceTriviální způsob includování obsahu stránky spolu s titulkem# CronÚlohy v PHP na serveru Programujte.com |
Řešení nejčastějších chybVypsal vám PHP interpret některou z následujících hlášek? Nebo pozorujete některý z následujících problémů? Zde snad naleznete řešení.# Parse error: syntax error, …Chyba syntaxe znamená, že máte špatně napsaný skript. Zde dvojnásob platí: Zkuste to řešit samostatně předtím než pošlete dotaz do diskuse. I začátečník by měl znát základní syntaxi jazyka a být schopný si opravit překlep.Jak na tuto chybu? Hláška vypadá nějak takto: Parse error: syntax error, unexpected něco in /cesta/soubor.php on line číslo. Zvýrazněné části jsou název souboru a číslo řádku. Překontrolujte kód na daném řádku daného souboru a také o řádek výše (např. zapomenutý středník na konci předchozího příkazu). Pokud přesto nic neobjevíte, pošlete dotaz do diskuse, přiložte několik řádků kódu kolem problémového místa (nekopírujte celé skripty s desítkami/stovkami řádků kódu!) a označte řádek, kam odkazuje chybová hláška. Tip: Syntaktickým chybám lze předcházet používáním vhodného PHP editoru (respektive IDE), kde se syntaktické chyby zvýrazňují už během psaní. # Warning mysql_*: supplied argument is not a valid MySQL result resource…případně Warning: mysql_num_rows() expects parameter 1 to be resource, boolean given…Znamená, že nejspíš máte chybu v SQL dotazu, jehož výsledek se snažíte přečíst. Funkce mysql_query může krom výsledku dotazu vrátit i FALSE (Viz manuál) a ve skriptu byste s tím měli počítat. Příklad: $result = mysql_query($sql); if(!$result){ /* Kód pro zalogování chyby a zobrazení nějaké chybové stránky uživateli. */ } mysql_error() - k problémům projevujícím se výše uvedenou hláškou přikládejte rovnou i výsledek mysql_error()!
Poznámka: Stejně jako u všech ostatních chyb, ani tady není vhodné nechat chybové hlášky vypisovat na ostrém webu přímo do stránky, tedy např.: mysql_query($sql) or die(mysql_error()); je přípustné pro testovací prostředí, ale na ostrém webu by to nemělo být.
$query = 'select * from tabulka where id = 5'; $result = mysql_query($query); if (!$result) { # zde by šlo doplnit podmínku && DEBUG == true, ale začátečníci to asi řešit nebudou a pak použijí jiný db layer echo "<br>\n", htmlspecialchars($query, ENT_QUOTES), "<br>\n", mysql_error(), "<br>\n"; } while ($item = mysql_fetch_assoc($result)) { // normální zpracování výsledku, // stále je ale možné, že nebyly nalezeny žádné výsledky, to nekontrolujeme, viz mysql_num_rows() } # Headers already sent…Pokud už byl generovaný nějaký výstup, tak už nelze používat funkceheader() , setcookie() ani session_start() . Jejich volání skončí chybou.
Přesvědčete se, že před začátkem <?php ?> není žádný text (ani mezera) a že nebylo nic odesláno třeba funkcemi jako echo nebo print .
# Nefungují proměnné z formuláře nebo z URL (vypnuté register globals)K hodnotě vstupního pole s názvem „nazev “ se dříve přistupovalo přes proměnnou $nazev . Z bezpečnostních důvodů je dnes tato možnost na většině serverů zakázaná.
K hodnotám zaslaným metodou POST lze přistupovat přes $_POST['nazev'] , metodou GET přes $_GET['nazev'] . K proměnným z cookies přes pole $_COOKIE .
Případně lze využít pole $_REQUEST , ve kterém jsou všechny proměnné zaslané metodou GET, POST i v cookies.
Podobně lze získávat hodnoty serverových proměnných z pole $_SERVER a session z $_SESSION .
Chceme-li uploadovat soubor, pracujeme s $_FILES. Register globals lze zapnout (pokud je to povoleno) vložením následujícího kódu do .htaccess. Tento přístup ale nelze doporučit a navíc není od verze PHP 5.4* podporován. php_flag register_globals on # Lomítka ve vstupních hodnotáchPři určitém nastavení PHP se v hodnotách z formulářů samo přidá zpětné lomítko před znaky uvozovek (" ), apostrofů (' ) a zpětných lomítek (\ ).
Pokud je to tak nastavené, funkce get_magic_quotes_gpc() vrací 1 , jinak 0 . Zařídit, aby $_GET['promenna'] nebyla takto olomítkována lze takto:
<?php if (get_magic_quotes_gpc()) { $_GET['promenna'] = stripslashes($_GET['promenna']); } ?> Jestliže se ve skriptu volá session_start() , je obvykle rozumné volání dát hned jako první příkaz, případně nejblíže začátku skriptu jak je možné.
Pokud je text v UTF-8, tím výstupem může být i tzv. BOM signatura, vizte výše zmíněný Divný znak (čtvereček). # Kam zmizelo odřádkování za „Pokud je hned za ukončením PHP ještě znak „ |
Jak něco udělat# Získaní IP adresyIP adresu lze najít v poli $_SERVER, viz register globalsecho 'Vaše IP adresa je: '.$_SERVER['REMOTE_ADDR']; # Jak předat proměnnou vkládanému souboruSouboru vkládaném pomocíinclude /require nelze předat proměnnou tímto způsobem:
<?php include 'soubor.php?e=mc2'; // NELZE !!! ?> <?php $promenna = 'hodnota'; include 'soubor.php'; ?> Předání title z includovaného souboru do indexu # Co dávat a co nedávat do uvozovekDo uvozovek či apostrofů se dávají pouze řetězce. Nepište uvozovky (ani apostrofy) kolem hodnot jiných datových typů, ani kolem proměnných:$text = "Ahoj!"; // správně $druhy = "$text"; // špatně, zde uvozovky být nemají $cislo = "10"; // špatně, čísla pro matematické výpočty se nepíší do uvozovek $cislo = 10; // správně $logicka = "false"; // velmi špatně, logické hodnoty nikdy nedávejte do uvozovek, protože "false" se převede na true! $logicka = false; // správně $telefon = "123456789"; // správně, sice je to telefonní „číslo“, ale obvykle s ním nechcete dělat matematické výpočty a v PHP ho používáte jako řetězec // zde chceme řetězec "true" a ne logickou hodnotu true, proto použijeme uvozovky $pozice = strpos("Slovo true je obsaženo v tomto řetězci", "true"); // vyhledáváme v řetězci slovo "true" # Práce s XMLMetody parsování XML |
Problémy s e-maily
Jednoduché použití funkce mail() se 3 povinnými parametry často nestačí. # Kódování e-mailu, aneb abychom neposílali otazníky.Text musíme posílat s uvedeným kódováním. Dříve se doporučovalo ISO-889-2, dnes bych neměl strach z UTF-8 a vzhledem k předpokládanému vývoji ho doporučuji.Kódování předmětu (a dalších hlaviček) a zprávy samotné se zadávají samostatně. Předmět zakódovat musíme, zakódováním těla zprávy nic nezkazíme. Hlavičky by mohly vypadat nějak takhle: $head = "MIME-Version: 1.0".PHP_EOL; Zde je zadané kódování zprávy. Když budeme posílat html mail, zde změníme na text/html. $head .= "Content-Type: text/plain; charset=\"utf-8\"".PHP_EOL; Tuto hlavičku uvedeme, pokud kódujeme i tělo zprávy. $head .= "Content-Transfer-Encoding: base64".PHP_EOL; To by ze základních hlaviček mohlo být vše. Teď kódování předmětu: $predmet = "=?utf-8?B?".base64_encode(autoUTF($predmet))."?="; Všimněte si, že pracujeme s utf-8 a používáme funkci autoUTF(), viz následující. Pokud budeme chtít použít jméno, poskládáme hlavičku takto: "From: =?UTF-8?B?".base64_encode(autoUTF("Moje Jméno"))."?=<ja@email.cz>".PHP_EOL; Už zbývá jen zakódování zprávy samotné, opět použijeme base64_encode() $zprava = base64_encode(autoUTF($zprava)); Abychom bez námahy získali text v utf, použijeme k tomu funkci od Davida Grudla. Dokážete-li získat data ve správném kódování (např. máte vše v utf-8), lze tento krok vynechat. To je vše, vypadá to trochu složitě, ale vše můžeme naskládat do vlastní funkce. <?php /* *************** diskuse.jakpsatweb.cz *** PHP FAQ ********************** */ function autoUTF($s) { if (preg_match('#[\x80-\x{1FF}\x{2000}-\x{3FFF}]#u', $s)) // detect UTF-8 { return $s; } elseif (preg_match('#[\x7F-\x9F\xBC]#', $s)) // detect WINDOWS-1250 { return iconv('WINDOWS-1250', 'UTF-8', $s); } else // assume ISO-8859-2 { return iconv('ISO-8859-2', 'UTF-8', $s); } } function cs_mail($to, $predmet, $zprava, $head = "") { $predmet = "=?utf-8?B?".base64_encode(autoUTF($predmet))."?="; $head .= "MIME-Version: 1.0".PHP_EOL; $head .= "Content-Type: text/plain; charset=\"utf-8\"".PHP_EOL; $head .= "Content-Transfer-Encoding: base64".PHP_EOL; $zprava = wordwrap(base64_encode(autoUTF($zprava)), 78, PHP_EOL, true); return mail($to, $predmet, $zprava, $head); } /* ********************************************************************** ** */ Jak to použít? Zkopírujte si do stránky výše uvedený kód a pak stačí tuto funkci zavolat. Ukázka použití: <?php $mail = 'jmeno@email.cz'; $predmet = 'ěščřžýáíé46'; $zprava = "Test, \r\n ěščřžýáíé123456789"; if (cs_mail($mail, $predmet, $zprava, "From: vas@web.cz".PHP_EOL)) { echo 'E-mail byl úspěšně odeslán.<br>'; } else { echo 'E-mail se bohužel nepodařilo odeslat.<br>'; } To je vše, už jen vysvětlit. $mail obsahuje e-mailovou adresu příjemce, $predmet předmět e-mailu a $zprava zprávu samotnou. To je asi jasné. 4. parametr obsahuje další hlavičky, oddělené koncem řádku. # Odeslání více položekČasto máme obsáhlejší formulář a potřebujeme z něj odeslat všechny jeho položky, řešení je jednoduché. Stačí všechny proměnné spojit do $zprava.Pokud posíláme mail jako html, je vhodné ošetřit vstupy funkcí htmlspecialchars($s, ENT_QUOTES) .
$zprava = "Jméno: {$_POST['jmeno']}".PHP_EOL; $zprava .= "Příjmení: {$_POST['prijmeni']}".PHP_EOL; $zprava .= "Telefon: {$_POST['telefon']}".PHP_EOL; $zprava .= "Ulice: {$_POST['ulice']}".PHP_EOL; $zprava .= "Žádost: {$_POST['zadost']}".PHP_EOL; $zprava .= "Poznámka: {$_POST['poznamka']}".PHP_EOL; Teď stačí $zprava vložit jako třetí parametr funkce mail. Pro složitější věci (např. přílohy) doporučuji PHPMailer nebo Nette mail. |
# Rekurzivní zipováníSkript pro rekurzivní zipování souborů |
# Registrace uživatelůZde původně uváděný script již neodpovídá současnému stylu programování a nechci ho nadále doporučovat. Než se shodneme na nové verzi, doporučuji přihlašovací script gist.github.com/JanTvrdik/8d813cfc7a4a8e0db2c7 od Jana Tvrdíka. # Solený hashStručné vysvětlení principu soli od JokeraPodrobnější informace o bezpečnosti hesel, nejen solení. Taktéž od Jokera. |
# Výpis výsledků z databáze (nebo z jiného zdroje) do tabulky o více sloupcíchTestovcí tabulka obsahuje 7 dní.CREATE TABLE `dny` ( `den` varchar(10) default NULL ); INSERT INTO `dny` VALUES ('Pondělí'), ('Úterý'), ('Středa'), ('Čtvrtek'), ('Pátek'), ('Sobota'), ('Neděle'); Řazení po řádcích Výsledek vypadá takhle: 1. Pondělí 2. Úterý 3. Středa 4. Čtvrtek 5. Pátek 6. Sobota 7. Neděle Kód, který to zajistí: $result = mysql_query("select den from dny"); define ("COLS", 3); // počet sloupců echo "<table>\n"; for ($i = 0; $zaznam = mysql_fetch_assoc($result); $i++) { if ($i % COLS == 0) echo "<tr>"; echo "<td>".($i+1).". ".$zaznam['den']."</td>"; if ($i % COLS == COLS - 1) echo "</tr>\n"; } if ($i % COLS != 0) { while ($i++ % COLS != 0) { echo "<td> </td>"; } echo "</tr>\n"; } echo "</table>\n"; Řazení po sloupcích Tentokrát to vypadá takhle: 1. Pondělí 4. Čtvrtek 7. Neděle 2. Úterý 5. Pátek 3. Středa 6. Sobota A kód, kterým to vytvoříme: $result = mysql_query("select den from dny"); while ($line = mysql_fetch_assoc ($result)) $zaznamy[] = $line; define ("COLS", 3); $pocetRadku = ceil(count ($zaznamy) / COLS); echo "<table>\n"; for ($i = 0; $i < $pocetRadku; $i++) { echo "<tr>"; for ($j = 0; $j < COLS; $j++) { echo "<td>"; if (isset($zaznamy[$j*$pocetRadku + $i])) echo ($j*$pocetRadku + $i + 1).". ".$zaznamy[$j*$pocetRadku + $i]['den']; else echo " "; echo "</td>"; } echo "</tr>\n"; } echo "</table>\n"; |
# Odlišení lichých a sudých řádkůPři výpisu dat (nejen z databáze) často potřebujeme odlišit liché a sudé řádky.Vytvoříme si dvě CSS třídy. .licha {font-weight: bold; color: #00f} .suda {font-style: italic; color: #063} V praxi bychom asi měnili jen pozadí, ale to nemohu v této diskusi demonstrovat. Teď již zbývá jen vypsat data a odlišit jednotlivé řádky. Využijeme tabulku z předchozího přikladu. $result = mysql_query("select den from dny"); // výběr dat z databáze echo "<table>"; $m = 0; // pomocná proměnná, můžeme ji zároveň použít pro číslování řádků while ($line = mysql_fetch_assoc($result)) // data vypisujeme v cyklu { echo "<tr class=\"".(++$m % 2 ? "licha" : "suda")."\">"; // tady se za pomoci modula a ternárního operátoru vypíše vhodná třída echo "<td>$m. {$line['den']}</td>"; // zde je $m využita jako číslo řádku echo "</tr>\n"; } echo "</table>"; Jak to funguje? Hodnota proměnné $m se při každém průchodu cyklem zvyšuje o 1. Využitím matematické funkce modulo (zbytek po celočíselném dělení) určíme, jestli je daný řádek lichý nebo sudý, a pomocí ternárního operátoru vložíme správnou třídu. Jak to vypadá? Výhodou tohoto řešení je možnost využít $m k číslování řádků. 1. Pondělí 2. Úterý 3. Středa 4. Čtvrtek 5. Pátek 6. Sobota 7. Neděle Další možností (a tentokrát zapsanou přehedněji) je neustálé prohazovaní hodnot true a false v jedné proměnné. echo "<ul>"; $suda = false; while ($line = mysql_fetch_assoc($result)) { $trida = $suda ? "suda" : "licha"; // stejné jako minule $suda = !$suda; // ! neguje současnou hodnotu a negaci ukládá pro příští iteraci echo "<li class=\"$trida\">{$line['den']}</li>"; } echo "</ul>"; Tentokrát ukázka generuje seznam. • Pondělí • Úterý • Středa • Čtvrtek • Pátek • Sobota • Neděle |
# Upload souborůUpload a download souborů na LinuxsoftuPHP triky – Zabezpečený upload souborů PHP triky – Velikost uploadovaných souborů PHP triky – Zmenšení obrázků # Vypsání náhodného obrázku<?php $obrazky = array( // pole s adresami obrázků "img/9.jpg", "img/21.jpg", "img/e02.jpg", ); shuffle($obrazky); echo "<img src=\"$obrazky[0]\">"; // jeden náhodný echo "<img src=\"$obrazky[1]\">"; // druhý náhodný ?> Jestli chceme vybírat ze všech .jpg souborů v adresáři bez jejich vypisování, stačí předchozí script upravit na: <?php $path = "img/"; $obrazky = glob("$path*.jpg"); shuffle($obrazky); echo "<img src=\"$obrazky[0]\">"; // jeden náhodný echo "<img src=\"$obrazky[1]\">"; // druhý náhodný Pokud jsou obrázky v databázi, lze je jednoduše vybrat dotazem: select obrazek from obrazky order by rand() limit 2 Podstatné je order by rand(), zbytek si upravte dle potřeby. |
# Jak získat zpět text zakódovaný přes MD5 (SHA-1, SHA-256, …)?Nijak, nejde to.V první řadě je nutné si uvědomit, že MD5 (SHA-1, SHA-256, atp.) je otisk, ne zašifrování ani zakódování. Samotný otisk nedává dost informací, aby z něj šlo rekonstruovat vstup, ze kterého byl vytvořen. Logicky když např. MD5 otisk má vždy 32 bajtů a vstup může být téměř libovolně velký, musejí být různé vstupy dávající stejné otisky. Ze samotného otisku pak nelze poznat, který z možných vstupů k němu vedl. # Jak na funkci „zapomenuté heslo“, když mám jen otisk (hash) hesla?(častá otázka po zjištění, že hash nejde „dekódovat“)Toto se obvykle řeší tak, že se uživateli nastaví nové náhodně vygenerované heslo a to se mu pošle. Lepší řešení je poslat uživateli výzvu s odkazem na stránku, kde si může heslo změnit. Zabráníme tak případnému měnění hesel útočníkem (který heslo sice nezíská, ale obtěžuje naše uživatele). Schopnost zaslat uživateli jeho původní heslo lze považovat za příznak vážné bezpečnostní chyby. Znamená to totiž, že vůbec existuje možnost heslo získat. A když to dokáže aplikace, dokáže to i případný útočník, který by se do ní naboural. Viz Poslání zapomenutého hesla. |
# Zkrácení článku pro výpis perexuČasto je třeba vypsat v seznamu článků jen jejich krátkou ukázku, tzv. perex. Pokud článek neobsahuje html značky, lze použít jednoduchéselect substring_index(`obsah`, ' ', 10) perex from `clanky` Tento dotaz vrátí text zkrácený na počet slov (oddělených mezerou) specifikovaný ve třetím parametru. Jednoduchou úpravou select concat(substring_index(`obsah`, ' ', 10), '…') perex from `clanky` Pokud zkracujeme na pevnou délku (nehledáme mezery) lze upravit tak, aby se … doplnil jen když se zkracuje: select concat(substr(`obsah`, 1, 200), if(length(`obsah`) > 200, '…', '')) perex from `clanky` Na úrovni PHP lze zkrácení textu dosáhnout funkcí substr(), případně mb_substr(). echo substr("Lorem ipsum dolor sit amet, consectetur adipiscing elit.", 0, 17)."…"; Složitější úpravy, např. vyřešení problémů s neuzavřenými html značkami, se obvykle řeší v PHP. Často stačí, když všechny značky odstraníme, tj. použijeme funkci strip_tags(), a následně zkrátíme (druhý script v Zkrácení textu s XHTML značkami). Pokud je nutné značky zachovat, viz Zkrácení textu s XHTML značkami. V obou případech je u delších článků vhodné z databáze vybrat určitý nadlimitní počet znaků, který se v PHP dále zkrátí. Není nutné načítat celé články. Pokud používáte nějaký šablonovací systém, postará se o konečnou fázi sám. Latte filter v Nette: <a href="…">{$linkText|truncate:20}</a> Smarty modifikátor truncate: <h1>{$articleTitle|truncate:30:"…":true}</h1> # Testování mailů na localhostuBěžná instalace vývojového prostředí obvykle nezahrnuji zajištění a konfiguraci SMTP serveru. Důsledkem je, že nám na localhostu nefunguje funkce mail(). Správné nastavení nebývá vždy jednoduché, viz např. možnosti posílání emailů přes gmail SMTP.Pokud ale emaily nepotřebujete skutečně odesílat a stačí vám je testovat, doporučuji vynikající Test Mail Server Tool. # Záloha databázeNávod na zálohování databáze pomocí Clevis/DatabaseBackup |
Komunikace mezi javascriptem a PHP# Jak přenést proměnnou z javascriptu do PHPMám tento kód, ale nefunguje mi dle očekávání:<script> var i = confirm('blablbla'); </script> <?php echo $i; Proč to nemůže fungovat? Protože PHP se nejdříve zpracuje na serveru, teprve výsledná html stránka se odešle klientovi a ten začne vyhodnocovat javascript. V této chvíli sice může vyvolat dialogové okno a zeptat se uživatele na informace, ale již vygenerovanou stránku nelze zpětně upravit. Jak to udělat jinak? Je důležité si uvědomit, že proměnné naplněné v js lze do php odeslat nejdříve při dalším požadavku na server. Pak máme několik možností. • Přesměrování stránky na sebe sama a doplnění informací do url – výhodou je možnost okamžitého překreslení nové stránky již na serveru, nevýhodou je velká prodleva, než se uživateli nová stránka načte a ztráta všechny neuložených věcí (u rozepsaného formuláře). • Odeslání skrytého formuláře na server (např. do iframe), možnost použít kromě dat v url i post data – výhodou je možnost odeslání post dat nebo třeba i upload obrázku na pozadí, přenáší se pouze užitečná data, stránka se znovu nenačítá. Nevýhodou je obtížnější získání odpovědi serveru. • Vyvolat jiný požadavek na server, např. v js vytvořit objekt obrázku. Nevýhodou je, že nezískáme odezvu serveru, data lze tedy přenášet jen jedním směrem. • Vytvořit cookies, která se při dalším požadavku na server odešle automaticky. Tento způsob je také v dané chvíli jednosměrný a je zde riziko, že uživatel stránku opustí a data se na server už nedostanou. Je to ale použitelné např. pro jednoduchou anktetu. • Využít AJAX – hlavní výhodou je, že lehce najdete hotové řešení, i když ne vždy optimální (jednoduchá ukázka, řešení s jQuery – jen na tohle je framework zbytečně velký, ale jestli už ho stejně načítáte, proč ho nepoužít). Tato metoda je univerzální a častou používaná. Počítá se zde s okamžitou odpovědí serveru, která vyvolá předem určenou js funkci (která může reagovat na odpověď např. změnou stránky). Komunikace se serverem je asynchronní, tj. zpracování dalšího javascriptu nečeká na dokončení předchozí požadavku. Tato řešení jsou bohužel závislá na funkčním javascriptu, když základ řešení necháte na html formuláři, bude to fungovat vždy (myslete i na mobilní zařízení). # Jak přenést proměnnou z PHP do javascriptuTento směr je značně jednodušší, protože PHP část se vykonává dříve.var vekUzivatele = <?php echo $vekUzivatele; ?>; // kdyby se předával string, musí se použít uvozovky a správné escapování Pokud přenášíte více hodnot, mohl by se vám hodit JSON. Umí s ním pracovat php i javascript. # Rozdíl ve viditelnosti cookies při vytvoření javascriptem a PHPData obsažená v cookies se mezi javascriptem a PHP předávají v http hlavičce. V době jejich platnosti jsou ukládána a spravována prohlížečem klienta. Pokud tedy v js vytvoříme cookies, je odezva okamžitá a hned na dalším řádku kódu ji můžeme přečíst. Jakmile ale zapojíme PHP (vytvoření cookie pomocí funkce setcookie), musíme počítat s čekáním na další požadavek (načtení stránky). Teprve s ním prohlížeč vloží do své žádosti o novou stránku aktuální data z cookies a serverový script je uvidí.Cookies v PHP fungují tak, že při na začátku zpracování requestu (počáteční fáze zpracování stránky) je vytvořeno superglobální pole $_COOKIE, které obsahuje přijatá data. Toto pole potom již v průběhu běhu scriptu zůstává samo o sobě neměnné. Nezmění ho ani funkce setcookie(), která pouze přidá do nové hlavičky odesílané klientovi nová data. Z toho plyne, že PHP cookies uvidí až po znovunačtení stránky. Pokud chceme, můžeme si sami modifikovat pole $_COOKIE . Tato změna se ale sama o sobě, na rozdíl od změny $_SESSION , nepřenese na další stránky.
|
# Konfigurace PHPPHP interpreta globálně nastavujeme editací souboru php.ini. Tuto možnost využijeme především na vlastním počítači, protože změněná nastavení se nám projeví (po restartu PHP (obvykle restartujeme Apache)) ve všech scriptech.Někdy chceme změnit nastavení jenom pro určitý script, pak použijeme ini_set(), jehož volba v aktuálním scriptu přepíše globální hodnotu v php.ini. Podobně můžeme nastavení změnit prostřednictvím souboru .htaccess (pokud pracujeme na Apache), detaily syntaxe jsou níže. Tato varianta úpravy konfigurace se hodí zvláště na sdíleném hostingu. Byly uvedeny 3 způsoby nastavení běhového prostředí, jejich použití ale není ekvivalentní. Zatímco v php.ini můžeme změnit cokoliv, pokud k němu máme přístup, funkce ini_set() i nastavení v .htaccess lze omezit, s tím se setkáme hlavně na sdíleném. Navíc ani z technických důvodů není možné vždy využít všech variant, v manuálovém přehledu možných nastavení je uveden sloupec Changeable, jehož hodnoty oznamují, kde lze danou hodnotu nastavení změnit. Zvláště upozorňuji, že nastavení upload_max_filesize s changeable hodnotou PHP_INI_PERDIR není možné změnit funkcí ini_set() (protože se daný script začne zpracovávat až po dokončení uploadu).
# Nalezení správného php.ini souboruČastou chybou je editace špatného souboru. Ten správný naleznete ve výpisu phpinfo() pod klíčem Loaded Configuration File .# Konfigurace PHP pomocí .htaccessNejdřív je potřeba zjistit v přehledu konfiguračních direktiv, jestli se dané nastavení vůbec dá změnit pomocí .htaccess. Pokud ano, musí tam být u něj napsané "PHP_INI_ALL" nebo "PHP_INI_PERDIR". Potom si kliknutím na název direktivy zobrazíme její podrobnější popis - tady nás zajímá hlavně datový typ (je uvedený hned za názvem direktivy).# takto nastavujeme logické hodnoty (boolean) php_flag název On #nebo php_flag název Off # všechny ostatní typy nastavujeme pomocí php_value. Příklady: php_value iconv.internal_encoding "UTF-8" # pokud řetězec neobsahuje mezeru, uvozovky jsou nepovinné. php_value upload_max_filesize 5M # zkrácený zápis datové velikosti, viz dále php_value error_reporting 30719 # odpovídá hodnotě E_ALL v PHP 5.3. Na rozdíl od php.ini nemůžeme používat konstanty. php_value název none # klíčové slovo "none" zruší předchozí nastavení # Zapnutí výpisu všech chyb a varování1) V globálním konfiguračním souboru php.ini nebo od PHP 5.3 v souboru .user.ini display_errors = On error_reporting = E_ALL 2) V souboru .htaccess (pokud PHP běží jako modul mod_php5 v Apache) <IfModule mod_php5.c> php_flag display_errors On php_value error_reporting 30719 </IfModule> 3) Na začátku skriptu (neukáže např. syntaktické chyby, ke kterým dojde před spuštěním skriptu) <?php ini_set('display_errors', 'On'); error_reporting(E_ALL); Všechny typy chyb jsou popsány v dokumentaci PHP - Predefined Constants. # Více verzí PHP na jednom počítačiPokročilejší uživatelé mají PHP pro testování nainstalováno ve více verzích. Pro jejich pohodlné testování lze využít PhpVersionSwitcher – nástroj na přepínání verzí PHP od Jana Tvrdíka. |
# Správné kódování v PHP# Jaké kódování použít pro pro stránku anebo pro ukládání do databáze?a Ať nastavím stránce/skriptu/databázi jakékoliv kódování, některé (všechny) texty se zobrazují špatně.Co se týká výběru kódování: Použijte UTF-8, nemáte-li důvod použít nějaké jiné kódování. (Např. při úpravě existující aplikace v nějakém kódování použijte stávající kódování té aplikace.) Pro správné zobrazení textů jsou důležité tyto věci: • Kódování souboru, ve kterém je stránka fyzicky uložená (tj. kódování nastavené v editoru při ukládání souboru). • Pokud do stránky vkládáte jiné soubory (např. přes include), kódování, v jakém jsou (opět fyzicky) uložené tyto soubory. • Jaké kódování stránka řekne prohlížeči. To lze nastavit HTTP hlavičkou content-type (v PHP přes funkci header), nebo v HTML kódu <meta> značkou charset nebo content-type. • Pokud používáte databázi, kódování pro komunikaci s databází. Standardní SQL na to má příkaz SET NAMES kódování (najdete v manuálu k příslušné databázi). Poznámka, například MySQL umožňuje také nastavit kódování pro konkrétní sloupec, což je něco jiného, podstatné je nastavit komunikační kódování.
Poznámka: Z databázových systémů běžně používaných s PHP by mělo SET NAMES fungovat v MySQL a PostgreSQL. V MS-SQL by mělo kódování jít nastavit přes konfigurační položku mssql.charset, SQLite má zdá se pevně dané kódování UTF-8. Všechny výše uvedené odrážky musejí být nastavené na totéž kódování. Jestliže používáte databázi, opravili jste komunikační kódování (takže teď už máte všechny odrážky správně) a přesto texty z databáze jsou špatně, pravděpodobně máte špatně uložená už data v databázi. Bude potřeba stará data překonvertovat a uložit znovu a ujistit se, že se komunikační kódování nastavuje i při ukládání dat. # Divný znak (čtvereček) na začátku includovaného souboru v UTF-8Soubor v kódování UTF-8 a UTF-16 může začínat takzvanou BOM signaturou. V případě UTF-8 je sice zcela zbytečná, přesto ji některé editory vkládají.Řešením je ve svém editoru nastavit, aby BOM nevkládal (v PSPadu Nastavení » Nastavení Programu » Program 2), nebo to nějakým způsobem odmazat. V některých editorech to nelze. A stručný popis UTF-8 Někdy lze BOM poznat dle prázdného místa. |
# Zastaralé (deprecated) funkce# Co to je?PHP se jako ostatní jazyky postupně vyvíjí. Většinou je přidávána nová funkčnost, avšak někdy dojde naopak k odebrání zastaralých prvků, zpravidla funkcí. S cílem usnadnění práce vývojářům je před definitivním odebráním daných funkcí zařazena přípravná fáze, ve které tyto funkce generují chybové hlášení o tom, že použitá funkce je zastaralá a brzy bude zrušena.Deprecated: Function ereg() is deprecated in ... Nejen kvůli tomu doporučuji na vývojovém serveru zobrazovat všechna chybová hlášení a vhodně ho aktualizovat. Vždy je lepší se o problému dozvědět dříve, než se rozbije produkční verze. # Mám kód přesně podle návodu a přesto vidím tuto hláškuProblémem je, že značná část návodů pro PHP (zvláště v češtině) je buď příliš stará, nebo jejich autoři (zvláště blogy menšího rozsahu) ignorují, že se s některými funkcemi do budoucna nepočítá. Např. oblíbený seriál o PHP na linuxsoftu vycházel v roce 2004 a je psán pro PHP 4, ve stejném roce (2004) vyšlo PHP 5. Ano, je to už opravdu dlouho a hodně věcí se změnilo.[h2#deprecated-functionsJakých funkcí se to týká?[/h2] Nejlepší přehled získáte pravidelným sledováním PHP changelogu, ten je více než dlouhý (ale je možné tam v prohlížeči vyhledat výrazy „deprecated“). Běžně stačí pročíst články, které se vždy objeví při vydání významných změn, a občas kouknout na fórum (to by měl programátor stejně dělat běžně). • Aktuálně nejčastěji zřejmě narazíte na zastaralost mysql_ extenze pro přístup k databázi. Např. u funkce mysql_connect() vidíme, že je označena jako deprecated a vývojáři nám doporučují použít MySQLi nebo PDO. Detailněji si o tom můžete přečíst na Fisirovo doupě: Proč nepoužívat funkce mysql_*?. Alternativně lze použít databázovou vrstvu třetí strany, např. dibiphp.com/cs/quick-start, které dokáže pracovat s různými extenzemi a jejich výběr závisí jen na konfiguraci. • Další v pořadí je celá rodina funkcí ereg_, místo které je doporučeno používat preg_ funkce. # Kdy přestanou fungovat?Tohle se obecně přesně neví, manuál mluví o příštích verzích. Konkrétně např. mysql extenze a mnohé další (wiki.php.net/rfc/remove_deprecated_functionality_in_php7) označované od 5.x jako deprecated nebudou součástí PHP 7, která má vyjít na konci roku 2015. Vydání nové verze však neznamená, že na ni váš hosting hned přejde.Nemusíte se bát, že to bude za měsíc. Zvláště free hostingy obvykle s aktualizací nikam nespěchají (a zvláště po této změně nebudou), takže to může fungovat ještě několik let. U nyní vyvíjených projektů byste se však měli těmto funkcí vyhnout. Všechny mají (lepší) náhradu, takže technicky to není problém. Nenechte se zmást tím, že na webu na některé zastaralé konstrukce narazíte na každém kroku. |
Toto téma je uzamčeno. Odpověď nelze zaslat.
0