Temat: sposób na modele przez pdo

Witam od pewnego czasu uczę się stosować PDO w swoich projektach i natknąłem na pewna sprzeczność. Generalnie idea modelowania baz danych nakazuje tworzenie dla każdej operacji osobnego zapytania, z kolei funkcje (metody) powinny być jak najbardziej "uniwersalne" by móc je wielokrotnie wykorzystać. Do tej pory radziłem sobie z tym po przez przekazywanie do funkcji modelującej jakiś argumentów z dodatkowym kodem sql...w przypadku używania PDO wychodzi to dosyć śmiesznie...(ze względu na quote...). Najlepiej wytłumaczę o co mi chodzi na przykładzie.
To pewien wycinek mojej klasy

/**
* Zwraca uczestników zadań
* @param int $zid klucz obcy - id zadania, domyślnie puste
* @param string $login nazwa użytkownika (uczestnika zadań), domyslnie puste
* @param int|string $status domyślnie puste, status z domeny danych [0..2] (w trakcie,wykonane,niepowodzenie). String z kodem SQL
* @param string $sortowanie domyślnie puste, sposób sortowania
* @return array tablica asocjacyjna z rekordami uczestnikami zadań
* @static
* @access public
*/
public static function getUczestnicy($zid='',$login='',$status='',$sortowanie='') {

$db = self::$db;
$warunki = 'WHERE ';
if($zid != '') $warunki .= '(zid = :zid)';
if($login != '') $warunki .= ' and (login = :login)';
if(is_int($status)) $warunki .= ' and (status = :status)';
else
if($status != '') $warunki .= ' and '.$status;

if($zid == '' AND $login == '' AND $status == '') $warunki = '';

if($sortowanie != '') $sortowanie = ' ORDER BY '.$sortowanie;

$uczestnicy = $db->prepare('SELECT * FROM zadania_uczestnicy '.$warunki.$sortowanie);

if($zid != '') $uczestnicy->bindValue(':zid', $zid, PDO::PARAM_INT);
if($login != '') $uczestnicy->bindValue(':login', $login, PDO::PARAM_STR);
if($status != '') $uczestnicy->bindValue(':status', $status, PDO::PARAM_INT);

if(!$uczestnicy->execute()) return false;

return $uczestnicy->fetchAll();

}

Absurdalność tego zapisu to zmienne $warunki i $sortowanie, których nie mogę wpisać przez PDO::quote a powinienem...Czyżby za bardzo poszedłem na łatwiznę? Powinienem dla każdego przypadku (np. warunków) tworzyć osobne metody? Co wtedy z sortowaniem ?

Generalnie moje marzenie to napisać kod w jednej linijce, co wszystko robi:D (mam ten kompleks)Ten post został edytowany przez Autora dnia 01.06.13 o godzinie 13:13

Temat: sposób na modele przez pdo

Zapoznaj się z jakimś ORM np Doctrine.
A jak chcesz przez PDO to niestety musisz się męczyć.Ten post został edytowany przez Autora dnia 01.06.13 o godzinie 14:59
Paweł Z.

Paweł Z. IT Manager

Temat: sposób na modele przez pdo

Zadaj sobie pytanie, czy będzie użyta metoda bez parametrów. Chyba niepotrzebnie wszystkim przypisujesz wartość domyślną.

Nie musisz też bindować wartości, gdy wiesz że powinny być numeryczne, wystarczy zwykłe is_numeric() lub intval() .

Kolejna sprawa to wartościom nie nadawaj żadnych znaków ucieczki. Tym powinno zajmować się właśnie bind. Gdy z niego korzystasz, inne escape'y możesz sobie darować.

Składanie zapytania w każdej metodzie oddzielnie rozdzielając elementy to lekka przesada.
Już lepiej stworzyć funkcję do rozszerzenia klasy PDO, która jako parametry przyjmuje poszczególne składowe i zwraca ciąg będący zapytaniem, gotowym do wstawienia w execute() + tablicę do bindowania.Ten post został edytowany przez Autora dnia 01.06.13 o godzinie 16:00

Temat: sposób na modele przez pdo

Paweł Z.:
Już lepiej stworzyć funkcję do rozszerzenia klasy PDO, która jako parametry przyjmuje poszczególne składowe i zwraca ciąg będący zapytaniem, gotowym do wstawienia w execute() + tablicę do bindowania.
tego nie do końca rozumiem, jak by to miało wyglądać?
Paweł Z.

Paweł Z. IT Manager

Temat: sposób na modele przez pdo

 
class Data extends PDO {
public function builder(array $fields, $table, $where = '', $sort = '', $limit = '')
{
// składanie zapytania do postaci SELECT `pole` FROM tabela WHERE `id` > :jakies ORDER BY `id` DESC;
}
}


Możesz już tutaj wpisać indeksy do bindowania, zamiast wartości. Chodzi o to, by nie składać zapytania w wielu funkcjach, jeżeli nie ma takiej potrzeby. Jak dla mnie wygodniej jest jednak składać, ale wynika to z tego, że z góry wiem, jakie elementy będą w zapytaniu, natomiast w Twojej funkcji jest odwrotnie.

http://mbe.ro/2009/08/30/fast-and-easy-php-mysql-class/Ten post został edytowany przez Autora dnia 01.06.13 o godzinie 19:09

Temat: sposób na modele przez pdo

ok, dzięki serdeczne :-)
Paweł Z.

Paweł Z. IT Manager

Temat: sposób na modele przez pdo

Nie wiem czy można, jak nie to proszę by moderator usunął.

https://github.com/extreme-fusion/eXtreme-Fusion-CMS/bl...
Tutaj masz przykład klasy napisanej pod PDO.
Szczególnie ułatwia bindowanie i skraca zapytania.
Teraz tylko obuduj sobie metodę getData i problem rozwiązany.

To, o czym mówiłem:

function insert($table, array $fields)
{
$keys = implode('`, `', array_keys($fields));
$values = implode("', '", array_values($fields));

return $this->exec("INSERT INTO ".$table." (`".$keys."`) VALUES ('".$values."')");

} // end of insert();


Zamiast w każdej metodzie składać zapytanie, używasz tej metody.Ten post został edytowany przez Autora dnia 01.06.13 o godzinie 21:30

Temat: sposób na modele przez pdo

Odkopuję temat bo po próbowałem kilka tych sposobów ale nadal wychodzi sieczka.

Zrobiłem sobie klasę budującą zapytania (rozszerzając PDO). Na wzór frameworków po robiłem osobne klasy dla każdej tabeli dziedziczące po tej budującej... i już się zamotałem. Bo chodź fajnie mieć taki porządek (wiem gdzie szukać jakiegoś zapytania) to pojawią się takie implikacje jak:

1) załadowanie klas i plików (każda klasa ma swój plik)...rozumiem, że najlepiej mieć po prostu funkcje która automatycznie załaduje modele? (bez korzystania z frameworków oczywiście)
2) jeśli te klasy rozszerzają PDO (łącznie z klasą budującą) to dla każdej muszę utworzyć nowe połączenie...a gdy np. zechce użyć mechanizmu transakcji? To będzie on dotyczył tylko danej tabeli...chyba, że przekaże uchwyt do wszystkich z osobna ...ale to niezbyt eleganckie, tak?
3) przy takim sposobie modelowania, nie wiem gdzie powinienem umieścić zapytanie wykorzystujące podzapytania lub złączenia (w sensie fizycznie jaki plik powinien to zawierać)

operowanie relacjami już pominę bo za chwile się okaże, że piszę swój framework.
Jak można nazwać taki sposób składania zapytań i modelowania tabel? Poszukałbym coś w google na ten temat...
Paweł Z.

Paweł Z. IT Manager

Temat: sposób na modele przez pdo

Dominik Z.:
1) załadowanie klas i plików (każda klasa ma swój plik)...rozumiem, że najlepiej mieć po prostu funkcje która automatycznie załaduje modele? (bez korzystania z frameworków oczywiście)

To zależy. Jeśli chodzi o zwykłe ładowanie klas, to rzeczywiście warto sobie loadera z spl zaciągnąć.
Jeśli o przekazywanie modelu do widoku, to można zrobić to na kilka sposobów.
2) jeśli te klasy rozszerzają PDO (łącznie z klasą budującą) to dla każdej muszę utworzyć nowe połączenie...a gdy np. zechce użyć mechanizmu transakcji? To będzie on dotyczył tylko danej tabeli...chyba, że przekaże uchwyt do wszystkich z osobna ...ale to niezbyt eleganckie, tak?

Nie powinny rozszerzać. Przekazuj klasę rozszerzającą PDO do swoich obiektów parametrem. Masz wtedy tylko w jednym miejscu łączenie się z bazą.Ten post został edytowany przez Autora dnia 28.06.13 o godzinie 17:45
Kamil S.

Kamil S. Backend Engineer and
Symfony Developer

Temat: sposób na modele przez pdo

Mniej wiecej tak jak wszystko sobie teraz rozpisales dziala Propel, on ogrywa wszystko od poczatku do konca.
Jesli koniecznie chcesz miec cos swojego to przynajmniej zapoznaj sie z takimi zagadnieniami jak: Propel, ORM, Container albo DI, Singletone.
Dominik Z.:
Odkopuję temat bo po próbowałem kilka tych sposobów ale nadal wychodzi sieczka.

Zrobiłem sobie klasę budującą zapytania (rozszerzając PDO). Na wzór frameworków po robiłem osobne klasy dla każdej tabeli dziedziczące po tej budującej... i już się zamotałem. Bo chodź fajnie mieć taki porządek (wiem gdzie szukać jakiegoś zapytania) to pojawią się takie implikacje jak:

1) załadowanie klas i plików (każda klasa ma swój plik)...rozumiem, że najlepiej mieć po prostu funkcje która automatycznie załaduje modele? (bez korzystania z frameworków oczywiście)
2) jeśli te klasy rozszerzają PDO (łącznie z klasą budującą) to dla każdej muszę utworzyć nowe połączenie...a gdy np. zechce użyć mechanizmu transakcji? To będzie on dotyczył tylko danej tabeli...chyba, że przekaże uchwyt do wszystkich z osobna ...ale to niezbyt eleganckie, tak?
3) przy takim sposobie modelowania, nie wiem gdzie powinienem umieścić zapytanie wykorzystujące podzapytania lub złączenia (w sensie fizycznie jaki plik powinien to zawierać)

operowanie relacjami już pominę bo za chwile się okaże, że piszę swój framework.
Jak można nazwać taki sposób składania zapytań i modelowania tabel? Poszukałbym coś w google na ten temat...
Łukasz C.

Łukasz C. Senior Technical
Architect

Temat: sposób na modele przez pdo

Poczytaj o DDD, tematy ktore Cie interesuja to: Encja, Repozytorium, Agregat i taka drobna rada: odzielaj warstwe logiki biznesowej od infrastruktury, a więc niech twoje modele nie mają NIC wspólnego z baządanych / PDO, od tego są repozytoria i agregatory aby martwić się o zapis / odczyt encji (modeli).

Temat: sposób na modele przez pdo

super, dzięki..o to mi chodziło

Następna dyskusja:

ustawienie kodowania latin2...




Wyślij zaproszenie do