DataBase class methods

PEAR, Smarty, ADOdb, OOP, PHP 5, XML, UML, Şabloane de proiectare, PHP-GTK.

Moderatori: coditza, Emil, Moderatori

Avatar utilizator
comma
PHPRomania Supporter
Mesaje: 20
Membru din: Mar Iun 06, 2006 11:16 am
Localitate: Bucuresti

DataBase class methods

Mesajde comma » Mie Ian 29, 2014 3:00 pm

salut tuturor.

intrebarea mea este ... cum e mai practic, sau mai bine zis cum procedati voi, cei mai experimentati?
de exemplu pentru INSERT am facut o metoda care se apeleaza ceva de genu

Cod: Selectaţi tot

$query = DB::insert("tabel", "values")->execute_query();
$result = $query->results();

- "insert" imi genereaza:

Cod: Selectaţi tot

public function insert($table, $values, $option = null){
                ... ... ...
}
// $this->sql = "INSERT INTO table (field_1, field_2) VALUES (?, ?), (?, ?) ..."
// $this->newVal = array ('value_1', 'value_2', 'value_a', 'value_b', ... )

- "execute_query" deschide conexiunea cu db, imi face escape pentru fiecare valoare din array, imi bindeaza valorile cu queryul, executa queryul, obtine rezultatele/num_rows/affected_rows/last_id ... sau erorile ... apoi inchide conexiunea cu baza de date

la acest INSERT pot sa-i pun obtional IGNORE sau ON DUPLICATE ... nu am facut INSERT INTO ... SELECT

Itrebarea mea este:
pentru SELECT in special ... cum procedati de obicei (cei cu mai multa experienta) ... va creati metode pentru fiecare obtiune a lui SELECT ... de genu GRUP_CONCAT, SUM, FROM, WHERE ... etc
ceva de genu:

Cod: Selectaţi tot

$query = DB::select("ceva", "...")->from('table')->where(...) ... ->execute_query();   // cam cum au mai toate frameworkurile

// sau ceva de genu

$sql = "SELECT * FROM table WHERE name = ? AND email = ? ORDER BY ...etc ... LEFT JOIN ... etc";
$vals = array(v1, v2, v3 ... etc);
$queri DB::exec_query($sql, $vals);

Si pentru DELETE si UPDATE unde acel WHERE poate sa aibe o gramada de combinati ... aceiasi intrebare
sau mai bine spus ... pentru ce sintaxe sql imi recomandati sa fac o metoda de generare a queriului ...


Cu stima.

Avatar utilizator
vectorialpx
Senior Member
Mesaje: 4832
Membru din: Mar Mar 01, 2005 9:48 am
Localitate: Bucuresti
Contact:

Re: DataBase class methods

Mesajde vectorialpx » Mie Ian 29, 2014 4:49 pm

Ca si abordare personala, am:
- mydb::getOne care returneaza array( field => value, field => value ) si
- mydb::getAll care returneaza array( array( field => value ), array( field => value ) ... )
- mydb::insert( $arrayKeyValue, $table )
- mydb::update( $arrayKeyValue, $whereKeyValue, $table )
- mydb::delete( $whereKeyValue, $table )

Cod: Selectaţi tot


$records 
mydb::getAll('
    SELECT * FROM `users` WHERE iduser = :id
'
, array( ':id' => $_GET['iduser'] ));
 


Referitor la structura, folosesc un singleton cu PDO

Cod: Selectaţi tot

<?php

class db 
{

    private static $_conn = null;
    private $PDOStatement = null;
    private $transaction = false;
    private $PDOobj = null;
    
    public function __construct
($type = 'mysql') {
        if(!self::$_conn) {
            try {
                switch($type) {
                    // check PDO::getAvailableDrivers()
                    // to add more drivers, like mssql
                    case 'mssql':
                    case 'pgsql':
                    case 'mysql':
                    case 'cubrid':
                    case 'sqlite':
                    case 'sqlite2':
                        self::$_conn = new PDO($type . ':host=' . HOST . ';dbname=' . DBNAME . ';charset=utf8', USER, PASS);
                        break;

                    default:
                        self::$_conn = new PDO('mysql:host=' . HOST . ';dbname=' . DBNAME . ';charset=utf8', USER, PASS);
                        break;
                }
            } catch(PDOExceptions $e) {
                echo 'Connection failed: ' . $e->getmessage() . '<br>';
            }
        }
    }

    public static function getConn() {
        if (!self::$_conn) {
            $temp = new db();
        }
        return self::$_conn;
    }
    
    
// don't allow clone
    private function __clone() {} 
    
    
// disconnect - NOT!
    /* public function __destruct() {
        self::$_conn = null;
    } */

    
    
// the only Database execution
    // to add another driver, edit here
    // --- AND also check
    // => $this->DB->lastInsertId($this->table);
    // --- for compatibility with your driver
    public function fetch($sql, $params = array(), $onlyOne = false) {
        // prepare, with CURSOR_FWDONLY
        $this->PDOobj = self::getConn();
        // get the statement
        $this->PDOStatement = $this->PDOobj->prepare($sql, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY));
        // execute prepared SQL
        $start = microtime(true);
        $result = $this->PDOStatement->execute($params);
        $time = microtime(true) - $start;
        // alert if the query takes to long
        if( $time > 5 ) {
            admin::email(ADMIN_EMAIL, 'Long query time: '.$time, '<pre>SQL: '.$sql."\r\n\r\nParams: ".print_r($params, 1).'</pre>' );
        }
        // if something's wrong
        if( false === $result ) {
            throw new PDOException( 'Invalid SQL<br />'.$sql );
        }
        // if need fetch
        if($onlyOne) {
            $rec = $this->PDOStatement->fetch(PDO::FETCH_NAMED);
        } else {
            $rec = $this->PDOStatement->fetchAll(PDO::FETCH_NAMED);
        }
        // close cursor, prepare for next fetch
        $this->PDOStatement->closeCursor();
        if(strpos(strtolower(trim($sql)), 'insert') === 0) {
            return $this->PDOobj->lastInsertId();
        }
        if(strpos(strtolower(trim($sql)), 'update') === 0 || strpos(strtolower(trim($sql)), 'delete') === 0) {
            return $this->PDOStatement->rowCount();
        }
        // return the record
        return $rec;
    }


}

 


Se pot face multe structuri, care mai de care mai complexe - eu prefer KISS ;) (keep it simple, stupid)

De exemplu, la tine, nu inteleg de ce faci

Cod: Selectaţi tot

DB::insert("tabel", "values")->execute_query();

si nu doar DB::insert("tabel", "values"). Mi se pare ca acel execute_query() este un apel in plus.

Ce ai mai putea face cu acel DB::insert, in afara de executie? :)
Daca ai nevoie de o tranzactie, o pui la inceput, sa zicem un DB::transactionStarted(), deci nu are treaba cu un simplu insert.

Avatar utilizator
comma
PHPRomania Supporter
Mesaje: 20
Membru din: Mar Iun 06, 2006 11:16 am
Localitate: Bucuresti

Re: DataBase class methods

Mesajde comma » Mie Ian 29, 2014 5:25 pm

acel execute_query() este intradevar un apel in plus, dar ma gandeam la o chestie de genu DB::select("ceva", "...")->from('table')->join(...)->where(...) care sa imi faca :

Cod: Selectaţi tot

slect(id, nume){
   ...
   return $this->sql [] = // ceva de genu "SELECT id, nume"
}
from(tabel){
   ...
   return $this->sql [] = // ceva de genu "FROM table"
}
// ... si tot asa in continuare

la sfarsit ar rezulta un array in acel "$this->sql" pe care sa-l bag in execute_query(), sa-i fac implode si sa-l execut

si ma gandeam sa pastrez aceiasi idee si pentru insert ... cu toate ca insertul il pot executa direct ...
teoretic, din toate stilurile de abordare ale problemei as vrea sa-mi fac un stil aproximativ propriu ... dar nu as vrea sa ma complic, plus ca as vrea sa fiu cat de cat in linie cu ce-i multi care sunte-ti mai experimentati ... nu vreau sa fiu eu cu stea in frunte
de aceea am intrebat cam cum procedati voi
sunt constient ca nu exista o clasa DB perfecta

pe de alta parte, stau si ma gandesc de ce as face ceva de genu DB::select("ceva", "...")->from('table')->join(...)->where(...) cand pot sa faca direct SELECT * FROM table WHERE name = ? AND email = ? ORDER BY ...etc ... LEFT JOIN ... etc

merci pentru raspuns ... o sa analizez modul tau de abordare a clasei DB
mai astept si alte pareri
Cu stima.

Avatar utilizator
Birkoff
Senior Member
Mesaje: 6380
Membru din: Joi Mar 18, 2004 2:34 pm
Localitate: Bucuresti
Contact:

Re: DataBase class methods

Mesajde Birkoff » Mie Ian 29, 2014 5:46 pm

eu personal folosesc o clasa proprie (daca o vrea cineva sa o ceara, am si exemple de folosire) cu care lucrez si pe mysql/mysqli/mssql/sqlite (pe alte tipuri nu am avut nevoie pana acum dar se poate extinde)

am preferat asa deoarece cu alte clase aveam mari probleme la tranzactii (se duceau pe apa sambetei) si eu folosesc des tranzactii in interogari.
+ ca vroiam sa invat si am preferat sa invat facand o astfel de clasa :)

ca stil de lucru, fac ceva de genul

Cod: Selectaţi tot

$db = new SQL_DB('tip bd - mysql, mysqli, etc', 'server', 'port', 'user', 'parola', 'db_name', 'bd_encoding - de obicei utf-8', 'conexiune persistenta sau nu');
if ( ! $db->open() ) {
    die ('eroare la conectarea la sql, verificati datele de conectare');
}
$query = "SELECt a.*, b.* FROM tabel1 a LEFT JOIN tabel2 b ON a.bblabla = b.blabla";
$result = $db->query($query);
if ( ! $result ) { echo 'eroare la interogare, verificati sintaxa din query'; }
if ( ! $db->num_rows ) { echo 'selectul nu a returnat nici un rezultat'; }
else {
    while($row = $db->fetch_array($result) ) {
        echo 'fa ceva cu randurile primite';
    }
}
1) CMS, ERP, CRM, etc... (doar pentru clienti))
2) Portofoliu, servicii, contact, blog
3) Folositi aceasta clasa sql in proiectele voastre (open source)
4) Vrei un magazin virtual la cheie, usor de folosit, cu api-uri incluse pentru maximizarea vanzarilor si multe alte facilitati? Da un semn si discutam.

Avatar utilizator
vectorialpx
Senior Member
Mesaje: 4832
Membru din: Mar Mar 01, 2005 9:48 am
Localitate: Bucuresti
Contact:

Re: DataBase class methods

Mesajde vectorialpx » Mie Ian 29, 2014 6:15 pm

comma scrie:ma gandeam la o chestie de genu DB::select("ceva", "...")->from('table')->join(...)->where(...)

Nu are rost sa re-inventezi o roata. Exista deja si, este foarte OK.
http://framework.zend.com/manual/2.0/en ... b.sql.html

tot ce trebuie sa faci este sa folosesti libraria de la Zend.
Personal, mi se pare complex si inutil (din nou, e o parare personala) pentru ca poti ajunge la SQL-uri care nu sunt acoperite de structurile astea (subselect-uri, select-uri de agregate mai complexe, variabile etc) sau, daca sunt acoperite, cand citesti un astfel de SQL dupa 20 de zile... nu mai intelegi nimic.

Avatar utilizator
comma
PHPRomania Supporter
Mesaje: 20
Membru din: Mar Iun 06, 2006 11:16 am
Localitate: Bucuresti

Re: DataBase class methods

Mesajde comma » Mie Ian 29, 2014 10:48 pm

@vectorialpx
stiu ca roata aia exista deja, am mentionat si eu undeva in primul post despre frameworkuri. ba chiar de acolo mi-a venit si ideea asta, dar exact cum spui si tu, nu o sa pot sa acopar toate cazurile de SQL-uri ...
- pe de o parte ma gandeam sa acopar o parte din cele mai uzuale queryuri,
- pe de alta parte nu cred ca are rost ...ori ca scriu $x->select('a.*', 'b.*')->from(tabel)->...->exec(), ori ca scriu $x = "SELECT a.*, b.* FROM tabel ..." e tot una, ba chiar cu a doua varianta sigur o sa acopar tot.
- si pe de a treia parte, cum zice Birkoff, vreau sa invat ... si in final sa imi faca propria mea clasa, care bine inteles nu o sa acopere tot dare care sa fie cat de cat simpla si sa poata sa inteleaga usor si altii ce am facut eu / si sa inteleg si eu ce au facut altii ... (acum nu activez in domeniu, dar probabil in viitor (sper apropiat) o sa ajung sa lucrez intr-o echipa ... si mi-as dori sa fiu cat mai compatibil cu echipa)
chiar daca copii o clasa a alcuiva, vreau totusi sa stiu ce e acolo ... nu vreau sa folosesc o clasa, gen cele din frameworkuri, fara sa stiu/inteleg ce are in ea
am incercat sa ma uit in sursele catorva frameworkuri, si mi-am prins rau usechile in cateva metode care aparent am crezut ca sunt simple.

incercand sa invat singur, nu are cine sa ma indrume, sa imi spuna "nu are rosta complicaciunea aia cand se poate faca mai simplu",
si incerc sa iau cate putin de la fiecare din cei mai experimentati, sa inteleg ce si cum, si sa aplic si eu cu mici mudificari dupa cum cred eu ca mi-ar fi de folos

@Birkoff
chiar te rog daca poti sa-mi trimiti si mie clasa ta de db ... cu tot cu exemple ... eventual o clasa "user" si inca una, care sa apeleze clasa db si sa aibe queriuri comune ... ceva gen class user extends db_common_querys

merci anticipat
Cu stima.

Avatar utilizator
vectorialpx
Senior Member
Mesaje: 4832
Membru din: Mar Mar 01, 2005 9:48 am
Localitate: Bucuresti
Contact:

Re: DataBase class methods

Mesajde vectorialpx » Mie Ian 29, 2014 11:45 pm

comma scrie:- pe de o parte..
- pe de alta parte..
- si pe de a treia parte .. o sa ajung sa lucrez intr-o echipa ... si mi-as dori sa fiu cat mai compatibil cu echipa)

In primul rand, nu te gandi la a treia parte, asta o sa vezi atunci (fiecare programator codeaza in stilul propriu).
Daca stii ce faci, o sa te potrivesti cu oricine.

Apoi, gandeste-te la ce vrei sa ajungi (ce rezultat vrei sa ai in final), stabileste-ti un tel si urmeaza-l.
Daca scopul tau este strict educational atunci iti va prinde bine aceasta idee, cu clasa de baza de date (te vei lovi de chestii concrete).
Fa-ti o imagine in cap despre ceea ce vrei sa iasa si apuca-te de ea. Cand dai cu capul de zid: (1)google, (2)php.net, (3)intrebi pe forum
Bafta!

PS:
comma scrie:eventual o clasa "user" si inca una, care sa apeleze clasa db si sa aibe queriuri comune ... ceva gen class user extends db_common_querys

Ma indoiesc ca Birkoff are o clasa "users" care extinde "db_common_querys" :) pentru ca asta incalca principiile OOP-ului

Avatar utilizator
comma
PHPRomania Supporter
Mesaje: 20
Membru din: Mar Iun 06, 2006 11:16 am
Localitate: Bucuresti

Re: DataBase class methods

Mesajde comma » Joi Ian 30, 2014 12:00 am

vectorialpx scrie:... pentru ca asta incalca principiile OOP-ului

adica ?
Cu stima.

Avatar utilizator
Birkoff
Senior Member
Mesaje: 6380
Membru din: Joi Mar 18, 2004 2:34 pm
Localitate: Bucuresti
Contact:

Re: DataBase class methods

Mesajde Birkoff » Joi Ian 30, 2014 6:22 am

comma scrie:
vectorialpx scrie:... pentru ca asta incalca principiile OOP-ului

adica ?


adica, daca ai o clasa pentru flori, nu o extinzi si pentru caramizi :D
daca ai o clasa pentru un tip de sql, o extinzi eventual pentru alt tip de sql sau tot legat de acelasi sql cu alte metode care imbunatatesc clasa de baza, nu te apuci sa o specializezi pe useri ca dupa aia cand ajungi la alt script sa nu o mai poti folosi ca aia e specifica pentru users si tie iti trebuie acum pentru sales sau mai stiu eu ce...

[offtopic] iti trimit pe pm link de unde poti lua clasa mea sa o studiezi
1) CMS, ERP, CRM, etc... (doar pentru clienti))
2) Portofoliu, servicii, contact, blog
3) Folositi aceasta clasa sql in proiectele voastre (open source)
4) Vrei un magazin virtual la cheie, usor de folosit, cu api-uri incluse pentru maximizarea vanzarilor si multe alte facilitati? Da un semn si discutam.

legendarboy
PHPRomania Supporter
Mesaje: 12
Membru din: Sâm Aug 17, 2013 9:31 pm

Re: DataBase class methods

Mesajde legendarboy » Dum Mai 11, 2014 5:31 am

vectorialpx scrie:
comma scrie:- pe de o parte..
- pe de alta parte..
- si pe de a treia parte .. o sa ajung sa lucrez intr-o echipa ... si mi-as dori sa fiu cat mai compatibil cu echipa)

In primul rand, nu te gandi la a treia parte, asta o sa vezi atunci (fiecare programator codeaza in stilul propriu).
Daca stii ce faci, o sa te potrivesti cu oricine.

Apoi, gandeste-te la ce vrei sa ajungi (ce rezultat vrei sa ai in final), stabileste-ti un tel si urmeaza-l.
Daca scopul tau este strict educational atunci iti va prinde bine aceasta idee, cu clasa de baza de date (te vei lovi de chestii concrete).
Fa-ti o imagine in cap despre ceea ce vrei sa iasa si apuca-te de ea. Cand dai cu capul de zid: (1)google, (2)php.net, (3)intrebi pe forum
Bafta!

PS:
comma scrie:eventual o clasa "user" si inca una, care sa apeleze clasa db si sa aibe queriuri comune ... ceva gen class user extends db_common_querys

Ma indoiesc ca Birkoff are o clasa "users" care extinde "db_common_querys" :) pentru ca asta incalca principiile OOP-ului


Despre care principii vorbim aici? Cu siguranta nu incarca nici un principiu al OOP-ului, din contra, faciliteaza design pattern-ul Entities si permite folosirea accesorilor si mutatorilor. De asemenea, la un nivel mai complex poate fi interpretat ca un ORM, si permite integrarea intr-un sistem MVC.

Ce doreste el, exista deja, intr-o varianta matura. Numele ei este Doctrine, poate face cunostinta cu ea la adresa http://docs.doctrine-project.org/projects/doctrine1/en/latest/en/manual/introduction-to-models.html.

Ca tot intepretam lucrurile ca obiecte, daca ai un unealta care manipuleaza trandafiri o vei extinde din unealta care manipuleaza flori, si vei particulariza unealta care manipuleaza trandafiri intr-un mod incapsulat - fara a afecta unealta generala - si vei respecta principiul mostenirii.

Avatar utilizator
vectorialpx
Senior Member
Mesaje: 4832
Membru din: Mar Mar 01, 2005 9:48 am
Localitate: Bucuresti
Contact:

Re: DataBase class methods

Mesajde vectorialpx » Lun Mai 12, 2014 4:42 pm

legendarboy scrie:Ce doreste el, exista deja, intr-o varianta matura. Numele ei este Doctrine, poate face cunostinta cu ea la adresa http://docs.doctrine-project.org/projects/doctrine1/en/latest/en/manual/introduction-to-models.html.

Daca te referi la Doctrine_Record, nu are nicio legatura cu ceea e se discuta in acest subiect.
Aceea este o "super-clasa" care aduce anumite proprietati tuturor obiectelor, este o entitate.

Faptul ca baza de date este folosita in orice proiect asta nu inseamna ca devine brusc entitatea oricarui proiect.

Wiki
wikipedia.org scrie:Entity Abstraction is a design pattern, applied within the service-orientation design paradigm which provides guidelines for designing reusable services whose functional contexts are based on business entities.[3]

Deci nu, baza de date nu poate sa fie o entitate, nu este o componenta de business.

sim72
PHPRomania Supporter
Mesaje: 22
Membru din: Mie Feb 26, 2014 10:43 am
Contact:

Re: DataBase class methods

Mesajde sim72 » Vin Mai 30, 2014 3:42 pm

Birkoff scrie:eu personal folosesc o clasa proprie (daca o vrea cineva sa o ceara, am si exemple de folosire) cu care lucrez si pe mysql/mysqli/mssql/sqlite (pe alte tipuri nu am avut nevoie pana acum dar se poate extinde)


Salutare Birkoff,
daca o mai ai pe stoc ... parca m-as baga si eu la o lectura.
Multumesc.


Înapoi la “PHP Avansat”

Cine este conectat

Utilizatori ce ce navighează pe acest forum: Niciun utilizator înregistrat și 18 vizitatori