Funkce pro získání řádku z databáze

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

V PHP existuje několik funkcí pro získání obsahu řádku z MySQL tabulky. Kromě nejvíce používané mysql_fetch_array jsou k dispozici ještě další tři: mysql_fetch_assoc vrátí sloupce v poli indexovaném názvy sloupců, mysql_fetch_row v poli indexovaném pořadím sloupců a mysql_fetch_object v objektu. mysql_fetch_array vrátí pole indexované jak názvy sloupců, tak jejich pořadím (pokud není druhým parametrem řečeno jinak) a protože tuto vlastnost nikdy nepotřebuji, tak ji zásadně nepoužívám. Díky tomu lze celý řádek např. jednoduše vypsat funkcí implode.

Nejčastěji používám funkci mysql_fetch_assoc a pokud je ve více tabulkách sloupec stejného jména, tak vytvořím alias:

<?php
$result = mysql_query("
    SELECT vyrobky.id, vyrobky.nazev, skupiny.nazev AS skupina_nazev
    FROM vyrobky
    INNER JOIN skupiny ON vyrobky.skupina = skupiny.id
");
?>

Nevyhýbám se používání SELECT *, protože to pomáhá při rozšiřování kódu – pokud se rozhodnu výpis rozšířit např. o cenu, stačí při použití SELECT * do výpisu doplnit $row["cena"], pokud jsou vyjmenované všechny sloupce, je nutné to doplnit na dvě místa. Hvězdičce se vyhýbám pouze v případě, kdy databázový server běží na jiném stroji a tabulka obsahuje objemná data, která při výpisu nepotřebuji (např. text článku u výpisu jejich nadpisů), protože režie spojená s přenosem dat je už zbytečně velká. SELECT * je také nevhodné používat v případě, kdy dotaz pracuje s více tabulkami, tehdy je lepší použít SELECT tabulka.* a sloupce z ostatních tabulek vyjmenovat explicitně.

Funkce mysql_fetch_row vede u větších výpisů k nepřehlednému kódu, protože na první pohled není patrné, co znamená např. $row[8]. Tuto funkci proto používám jen ve výjimečných případech:

<?php
/** Provedení MySQL dotazu a vrácení pole hodnot
* @param string dotaz
* @return array pole s klíči prvního sloupce dotazu a hodnotami druhého sloupce
*/
function mysql_get_vals($query) {
    $return = array();
    $result = mysql_query($query);
    while ($row = mysql_fetch_row($result)) {
        $return[$row[0]] = $row[1];
    }
    mysql_free_result($result);
    return $return;
}
?>

Funkce se hodí např. pro získávání číselníků pro použití spolu se značkou <select>.

Použití mysql_fetch_row se v každém případě vyhněte v kombinaci se SELECT *, nikdy nemůžete vědět, kdy do tabulky přibude další sloupec.

Přijďte si o tomto tématu popovídat na školení Návrh a používání MySQL databáze.

Jakub Vrána, Řešení problému, 5.8.2005, diskuse: 16 (nové: 0)

Diskuse

joe:

http://pear.php.net/package/DB

Michal:

jestli to někdo myslí s databázema vážně, používal bych http://adodb.sourceforge.net/

A "SELECT *" bych rozhodně NIKDY nepoužíval, ať už je MySQL kdekoliv..

ikona spaze:

nebo se snad uz konecne dockame nativni PDO ;)

ikona dgx:

Dočkáme, ale popravdě, nic moc...

johno:

Môžem vedieť prečo? Zase ide klasický pseudoargument o tom, aké je PEAR hrozne veľký a preto aj pomalý na načítanie?

ikona spaze:

Ne, o ten argument nejde, to bych ho uvedl. Proste mam nejak radeji built-in funkce a rozsireni. Navic ADOdb s PEAR nema mnoho spolecnyho, AFAIK.

markon:

SELECT * rozhodně nepoužívejte, protože znatelně snižuje výkon databáze. Ano jsou ojedinělé příkazy, kde se to hodí, ale z většiny je lepší se této konstrukci vyhnout

ikona spaze:

jeste bych doplnil neco, co se sice moc netyka ziskani radku, ale spis ziskani *poctu* radku. (omluvte prosim pseudokod)

echo mysql_num_rows(SELECT *) neni moc spravne, pokud nevime, co delame ;) lepsi je echo(SELECT COUNT(*)) napr.

Proste je lepsi zavolat do kramu, kolik maji rajcat, nez je vsechny koupit, privezt domu a zjistit, ze jich jsou dve tuny ;P

To jen tak, kdyz jsem cetl o tom SELECT *

ikona Jakub Vrána OpenID:

Stačil by odkaz na http://php.vrana.cz/ziskani-poctu-radek.php :-).

Leo:

K te hvezdicce. Pokud chci vytahnout vsechny sloupce tak je podle vas rychlejsi (myslim rychlost dotazu) je v SELECTu vyjmenovat nez pouzit * ? Leo

tark:

Tak tohle se mi osobně moc nelíbí ... Radši bych tu uvítal popis databázových layerů.

PS: Při "získání řádku z db" bych si představil spíš fci db::getRow() z http://kanevinternetu.blacksuns.net/source/db2.phps

rane:

k database abstraction layerom kuk sem: http://jeremy.zawodny.com/blog/archives/002194.html

MaReK Penguin_007:

Nativni funkce pro tu kterou dataazi pouzivam minimalne, jedu pres ez_sql a pak treba pro ziskani clanku pouziji $articles=$db->get_results('SELECT id, title, lastedit, visible FROM '.DBPREFIX.'articles WHERE editor=\''.$_POST['userid'].'\'',ARRAY_A);, kde poslednim parametrem urcuji jakeho typu ma byt navratove pole. Neco malinko jsem o teto knihovnicce psal zde: http://www.linuxsoft.cz/article.php?id_article=664

waka:

ahoj, daju sa nejak pouzit spominane funkcie bez toho aby posunuli internal pointer ukazujuci na riadok v tabulke ?

ikona Jakub Vrána OpenID:

Pokud vím, tak ne. Na co bys to chtěl využít?

waka:

Ide o to ze volam SELECT v rekurzii a potrebujem vediet hodnoty z daneho $row. Nasledne vyskladam SLECET kde vo WHERE clausule pouzijem hodnoty ziskane zo spominaneho $row a tento novo vyskladany SELECT ma opat spracovat ten insty $row. Tym padom ze je to rekurzia tak seek neprichadza do uvahy. Neviem ci som to dost zrozumitelne napisal. Uz som pisal aj na toto forum, http://www.linuxquestions.org/questions/programming-…-mysql-875286/ je tam kod v PHP. Dakujem velmi peknne za kazdu radu.

Diskuse je zrušena z důvodu spamu.

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.