Sep 1 2009

UTF-8, MySQL, kódování a PHP funkce pro práci s řetězci: strlen, substr aj.

Možná jste při práci s PHP narazili na problém s UTF-8 kódováním. Doposud jste využívali kódování cp1250 nebo iso-8859-2 a nebyl problém. Okolnosti vás přinutily požívat UTF-8 a najednou bum. Na stránkách se vám chybně vypisují znaky s českou diakritikou a nevíte co s tím.

Jak správně použít UTF-8 a MySQL?

Je třeba dodržet následující pravidla:

  1. Po připojení nastavit kódování, ve kterém bude probíhat komunikace s databázovým serverem:
    mysql_query("SET NAMES 'utf8'");
    nebo 
    mysql_query('SET CHARACTER SET utf8');
    
    Od PHP 5.2.3 a MySQL 5.0.7 raději použijte:
    mysql_set_charset('utf8');
    
    Je to správná a bezpečná varianta
    pro použití mysql_real_escape_string(). Více: 1, 2, 3.
  2. Kódování PHP souborů nastavit na UTF-8 (pozor na počáteční UTF-8 boom znak)
  3. Odesílat hlavičky s UTF-8 kódováním:
    header('Content-Type: text/html; charset=utf-8');
  4. Nastavit UTF-8 kódování v HTML (meta tagy, xml hlavička aj.)
  5. Používat PHP řetězcové funkce, které zvládají UTF-8 (viz dále)

Pokračování článku


Jun 23 2009

MySQL: Rychlost UPDATE sloupce v závislosti na přítomnosti indexů

Nedávno jsme s Lukášem Churým a Ondrou Vašíčkem řešili rychlost operace UPDATE v závislosti na tom, jestli upravovaný sloupec má či nemá nastavený index.

Představte si, že máme v MySQL 5.0 tabulku o několika sloupcích, dva z nich jsou “id” a “xy”. Nad sloupcem “id” je přidělený index. Sloupec “xy” index nemá. Rychlost UPDATE sloupce “xy” trvá nějaký čas.

Otázka zní, jestli UPDATE zabere stejný čas i v případě, kdyby sloupec “xy” měl přidělený index.

Udělal jsem jednoduchý test, který přináší odpověď.

Pokračování článku


May 21 2009

Jak na to: SQL injection, magic_quotes_gpc, addslashes() a stripslashes()

V názvu článku jsem vyjmenoval slova, která jsou strašákem nejednoho PHP programátora. Strašák to je ale pouze uměle vytvořený, vycházející z neznalosti problematiky.

Dost často se ve spojení s SQL injection (typ útoku hackera) zmiňuje PHP konstanta magic_quotes_gpc. Prý, že pokud je zapnutá, tak se dá SQL injection předejít. A víte, že od PHP 5.3 bude standardně magic_quotes_gpc vypnutá?

Znamená to, že poté budou SQL dotazy napadnutelné pomocí SQL injection? Ale vůbec ne.

Konstanta magic_quotes_gpc totiž s ochranou SQL injection nemá v podstatě nic společného. Pouze zde existuje průsečík v možnosti jejího využití. Proto ji neznalí programátoři začali přisuzovat větší váhu, než má. Váha magic_quotes_gpc je samozřejmě nulová, zvláštně, když od PHP 5.3 bude vypnutá a v PHP 6 zanikne úplně.

Vysvětleme si tedy, oč jde. SQL injection je vážný problém.

Pokračování článku


May 6 2009

MySQL: Pokud záznam neexistuje, vytvoř nový. Jinak původní aktualizuj

Typický příklad. Máme tabulku, kam ukládáme nějaké záznamy o činnosti uživatele. Tentokrát třeba návštěvu vlákna ve fóru, spolu s časem a počtem příspěvků ve vláknu.

Pokud takový záznam neexistuje (vázaný na ID uživatele a ID vlákna), tak vytvoříme nový záznam (INSERT), jinak provedeme aktualizaci záznamu (UPDATE), tedy čas a počet příspěvků.

Nabízí se několik možností, jak tento proces provést.

Možnost A

  1. Zjistit, jestli záznam existuje (SELECT COUNT(*)…)
  2. Pokud existuje, provést aktualizaci (UPDATE)
  3. Pokud neexistuej, vložit nový (INSERT)

Všetři tři kroky uzavřeme do stransakce (viz Jakub Vrána).

Možnost B

  1. Provést aktualizaci (UPDATE)
  2. Zjistit počet ovlivněných řádků (mysql_affected_rows())
  3. Pokud “nula” (záznam neexistuje), tak provedeme vložení nového (INSERT)

Pokračování článku


Apr 8 2009

MySQL: Jak překopírovat/přesunout řádky do jiné tabulky?

Možná jste někdy narazili na potřebu v rámci jedné databáze překopírovat řádky z jedné tabulky do tabulky druhé. Nabízí se obstrukční řešení, kde získáme pomocí SELECT všechny položky, poté výsledky proženeme skrz while cyklus a mysql_fetch_array, a v každém průchodu cyklu provést INSERT. Případně si takový INSERT „poskládat“ a provést jen jednou; zde ale pozor na případný limit ve velikosti dotazu.

Takový způsob by byl samozřejmě zdlouhavý a chybný. Existuje naprosto jednoduché a elegantní řešení.

Pokračování článku


Mar 23 2009

MySQL: délka řetězce a nefunkční strlen()

V databázi máme například jména. Chceme získat všechna jména, která jsou kratší než 7 znaků. Jak na to?

Známá funkce strlen() v MySQL neexistuje, zato můžeme použít funkci CHAR_LENGTH().

Pokračování článku


Feb 15 2009

MySQL: Jak získat předposlední záznam?

Někdy je potřeba vypsat několik předposledních záznamů z tabulky, třeba článků. Pro vypsání stačí data seřadit od nejnovějšího a použít LIMIT včetně offsetu.

Pokračování článku


Dec 20 2008

RSS 2.0, MySQL a vytvoření data publikace (pubDate)

Kvůli RSS někdy potřebujeme vytvořit zápis data a času v požadovaném tvaru.

Třeba v takovém: Sat, 20 Dec 2008 13:21:00 GMT+1

Uvedený formát můžeme vygenerovat v PHP nebo přímo pomocí SQL dotazu.

Pokračování článku


Nov 21 2008

phpMyAdmin 3.0.1: blesková správa MySQL databáze

Při vývoji většinou pracuji přímo s databází na webhostingu (přes vzdálený přístup). Pokud je vyvíjená aplikace přístupná pro úzký okruh testerů, je daleko snazší, když webová aplikace využívá stejnou databázi, a to jak z localhostu, tak i přímo na serveru. Vždy mám totiž přístup ke stejným datům.

Proto nějaká lokální databáze, databáze na serveru, synchronizace, atp., jsou pro mě spíše zdržování. Abych si usnadnil práci a nemusel se připojovat na phpMyAdmina na serveru, využívám u sebe na localhostu lokální instalaci phpMyAdmin. Instalace je ale dosti nadnesené slovo. Stačí stáhnout, rozbalit, nastavit pět hodnot a spustit.

Doposud jsem využíval phpMyAdmin ve verzi 2.9.2. Nyní jsem přešel na phpMyAdmin 3.0.1.1. A co že přináší? Nejmarkantnější rozdíl oproti předchozí používané verzi je v rychlosti. Ta se totiž zvýšila, ale rapidně.

Pokračování článku


Nov 13 2008

Hostmonster.com: přístup přes více účtů do phpMyAdmin (MySQL)

Pokud využíváte webhosting Hostmonster.com, možná jste narazili na nepříjemnost týkající se nemožnosti přístupu k phpMyAdminovi přes více uživatelských MySQL účtů. Hostmonster sice přes administraci cPanel umožňuje vytváření vlastních databází, uživatelů a přidělování práv. Můžete propojit jednotlivé uživatele a databáze, ale ke všem databázím můžete přistupovat pouze přes standardní phpMyAdmin s hlavním účtem do cPanelu.

Spravujete-li více webů – projektů, neobejdete se bez nutnosti poskytnout přihlašovací údaje do databáze dalším lidem, například programátorům či správcům. A zde právě nastává kámen úrazu. Je tedy zcela nemyslitelné, abyste hlavní heslo poskytli dalším uživatelům. Naštěstí existuje řešení, jak na Hostmonster.com zpřístupnit phpMyAdmin pro více uživatelských účtů MySQL databáze.

Pokračování článku