Databázový layer

MyEgo.cz

home foto blogy mywindows.cz kontakt

Databázový layer

PHP 04.11.04

Představuji k volnému použití (licence GNU GPL) jednoduchý dababázový layer, který je určen pro MySQL 3.23 až 4.0 (mysql), MySQL 4.1 (mysqli), SQLite a PostgreSQL.

Tento layer je záměrně psán neobjektově. Proč? Je určen pro úpravu starých skriptů, které jsou natvrdo psány pro MySQL 4.0, aby co nejdříve fungovaly s DB-layerem (na libovolné open-source databázi).

Názvy funkcí layeru jsou navrženy tak, aby byly shodné se syntaxí MySQL funkcí, jen místo mysql budete psát sql, tedy například místo mysql_connect budete psát sql_connect. Teoreticky je tak možné na Vašem skriptu udělat hromadný search-and-replace slov mysql_ na sql_, a Vaše aplikace by měla fungovat s DB-layerem.

Pro nový vývoj je samozřejmě vhodnější použít DB-layer objektový, uvedu jej zde zítra.

Zdrojové kódy layeru jsou zde.

Použití layeru pro MySQL:

Typické použití pro MySQL 4.1 bude spočívat ve vytvoření souboru config.php s tímto obsahem:

<?php
include ('db.php');
$SQL_HOST='localhost'; // adresa DB
$SQL_USERNAME='root'; // uzivatel
$SQL_PASSWORD=''; // heslo
$SQL_DATABASE='test'; // nazev databaze
$SQL_TYPE=_MYSQL41; // typ databaze
$SQL_PREFIX=''; // prefix tabulek
?>

Příklad pro SQLite:

<?php
include ('db.php');
$SQL_DATABASE='/Dev/www/test.db'; // nazev souboru SQLite
$SQL_TYPE=_SQLITE; // typ databaze
$SQL_PREFIX=''; // prefix tabulek
?>

Prefix tabulek:

Uvedený skript počítá rovněž s prefixem tabulek. Ten je velice důležitý, typicky máte na web-hostingu povolenou jen jednu MySQL/PGSQL databázi, a potom je nezbytně nutné jednotlivé instalace stejné aplikace odlišit právě prefixem v názvech tabulek.

Použití tohoto skriptu?

Náš index.php může vypadat například takto, a bude fungovat na MySQL 4.0, MySQL 4.1, SQLite a PostgreSQL:

<?php
// DB layer
include('config.php');
// pripojeni k DB
sql_connect(true);
// shutdown funkce
register_shutdown_function('sql_disconnect');
// vlastni kod
$query = sql_query( 'select * from '.sql_table('test') );
while ( $obj = sql_fetch_object($query) ) {
  // zpracovani vysledku
}
sql_free_result($query);
?>

Komentáře

  1. 1 stv@seznam.cz 04.11.04, 14:49:50
    FB

    Tvuj strukturalne programovany db layer me konecne prinutil, abych si naprogramoval vlastni db layer objektovy.
    Tak schvalne, jestli je lepsi, nez ten tvuj, co uverejnis zitra ;) Pak hodim linky.

  2. 2 Vašek 04.11.04, 15:00:56
    FB

    Z manualu:
    mysql_fetch_assoc() is equivalent to calling mysql_fetch_array() with MYSQL_ASSOC for the optional second parameter.

    Nevidim u tebe potom rozdil ve funkcich
    sql_fetch_array a sql_fetch_assoc

    Dale kdyz uz tam mas escapovani, nema sqlite escapovane apostrofy?

    Opravdu chces uzivatelum pri chybe v query vypisovat, jaky dotaz se nepovedl? :-)

  3. 3 Radek Hulán 04.11.04, 17:31:47

    [2] sql_fetch_array udělá asociativní pol epodle názvů položek v SELECTu a sql_fetch_assoc podle názvů i podle čísel.. Chce to číst lépe dokumentaci.

    Ohledně chyb v SQL - není důvod, aby aplikace dělala při běhu chyby v SQL, takže ano, je tam výpis natvrdo, a může se objevit jen tehdy, když to programuji..

  4. 4 Michal Tuláček 04.11.04, 22:47:52
    FB

    Hmm... kdybych nemel se svym projektem komercni zamery, hned bych to bral, ale ta GNU me odrazuje... takze si budu muset napsat vlastni :D

    Btw: jaky mate kdo nazor na GNU/GPL? Pomaha svobodne tvorbe programu jak byl jeji zamer a nebo skodi? Pac muj nazor je takovy (a nemam ho sam), ze firmy si stejne musi ta reseni napsat samy, pokud nechteji porusit ty licence, takze to trosku ztraci smysl...

  5. 5 Vašek 05.11.04, 09:24:10
    FB

    [3] Nemůžu si pomoct, ale v manuálu php pro mysql funkce to čtu přesně obráceně, než to říkáš.

    To escapování sglite tam máš, toho jsem si nevšim, promiň.

  6. 6 Radek Hulán 05.11.04, 10:00:40

    [5] máš pravdu, moje chyba, děkuji, opravil jsem to

  7. 7 Marek Fábry 05.11.04, 11:49:47
    FB

    Chtěl bych doporučit ADODB - něco podobného, podpora větší sady databází. Používám již několik let a díky tomu že pracuji s různými databázemi jsem si ušetřil dost času, přemýšlením nad názvy potřebných funkcí :-) Cache výsledků dotazů také není od věci.

    Díky licenci je možné vkládat do komerčních projektů bez nutnosti zveřejnit zdrojové kódy.

    http://adodb.sourceforge.net/

  8. 8 msw 05.11.04, 16:59:09
    FB

    [3] Chyba je treba i poruseni IO treba UNIQUE (no na MySQL asi nic jinyho ne) a to se imo stavat muze a mela by to zpracovat aplikace (takhle nemuze). Ten SELECT navic by byl casto zbitecny.

    [7] ADODB je pekny ale trochu jinde uz jen tech ~400kB kodu :)

    fetch_field by alespon priblizne slo i posgres

    function sql_fetch_field(&$resource, $field_number=0){
    //pgsql $i = pg_num_fields($resource);
    if($field_number<$i)
    {
    $field = array();
    $field['name'] = $name = pg_field_name($resource, $j);
    $field['type'] = pg_field_type($resource, $j);
    $field['max_length'] = pg_field_size($resource, $j); //priblizne ;) return $field;
    }
    else
    {
    return array();
    }

    a pouzivat pro indexy OID mi prijde min prakticke nez tohle :)

    sql_insert_id()
    _PGSQL:
    $result = @pg_query($activedb,$query)
    or
    die ("Invalid query: ".htmlspecialchars($query)." <br><br>Error: <b>".sql_error()."</b>");
    if(preg_match("/^\s*INSERT\s+INTO\s+(\w*)/i",$query, $matches))
    {
    global $_pg;
    $_pg = $matches[ 1 ];
    }
    break;
    sql_insert_id(){
    _PGSQL:
    global $_pg; if(!empty($_pg))
    { $result = @pg_query('SELECT currval(\''.$_pg.'_id_'.$_pg.'_seq\')');
    if(empty($result)) return 0;
    else
    {
    $row=pg_fetch_row($result);
    return $row[ 0 ];
    }
    }
    break;

  9. 9 egli 05.11.04, 18:18:46
    FB

    mysql_fetch_array() je i s parametrem MYSQL_ASSOC o 40% pomalejší než mysql_fetch_assoc()

    Takže používejte pouze mysql_fetch_row() nebo mysql_fetch_assoc()

    Benchmark on a table with 38567 rows:
    mysql_fetch_array:
    MYSQL_BOTH: 6.01940000057 secs
    MYSQL_NUM: 3.22173595428 secs
    MYSQL_ASSOC: 3.92950594425 secs

    mysql_fetch_row: 2.35096800327 secs

    mysql_fetch_assoc: 2.92349803448 secs

  10. 10 Radek Hulán 05.11.04, 18:31:59

    [9] ale ta čísla neříkají naprosto nic..

  11. 11 egli 05.11.04, 22:24:58
    FB

    V PHP 5 jsou ty rozdíly už menší, když budeme brát mysql_fetch_row jako 100%:

    mysql_fetch_row - 100%
    mysql_fetch_array(MYSQL_NUM) - 113%
    mysql_fetch_assoc - 118%
    mysql_fetch_array(MYSQL_ASSOC) - 127%
    mysql_fetch_array - 150%

    Čili není to už tak výrazné, ale proč nepoužít rychlejší funkci...

  12. 12 Radek Hulán 05.11.04, 22:42:31

    [11] chtěl jsem říci, že alespoň bez znalosti STD a testovacího skriptu, jsou ta čísla jen "vycucaná z prstu"...

  13. 13 Tomáš Kubát 20.11.04, 13:19:54
    FB

    Upozorňuji na drobnost v ukázkovém config.php souboru. Je zde uvedeno: $SQL_USERNAME;

    Kdežto v definovaných funkcích se používá global $SQL_USER;

  14. 14 Špéťa 14.01.05, 21:44:53
    FB

    Zdravim,

    jen jsem se chtel zeptat, jak to vypada s tim objektovym resenim DB layer;-)? Najek jsem ho nenasel.

    Diky

  15. 15 Vašek 15.01.05, 14:53:28
    FB

    [14] chytrý student si dodělá za domácí úkol ;-)

  16. 16 Jer 06.03.05, 21:36:13
    FB

    Mohl bych se zeptat, kde je ten slibovany objektovy layer? Nejak ho nemuzu mezi novejsimi clanky najit...

  17. 17 Radek Hulán 06.03.05, 21:44:46

    [16] udělat z toho objekt je práce na 10 minut, proto se mi do toho moc nechce, to zvládne každý sám..

  18. 18 Jakub Bouček 13.03.06, 00:15:23
    FB

    Tak jsem si to zkušebně převedl a teď bych se chtel podívat, ja to udělá profík, abych zjistil, co musím ještě dohnat... Jinak by to chtělo odstranit ten slib: ", uvedu jej zde zítra".

Nový komentář

Pro přidání komentáře se musíte nejdříve  registrovat Facebookem

Banan.cz