Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

5 Stron V   1 2 3 > »   
Reply to this topicStart new topic
> [PHP][MySQL][PDO] Przepisanie funkcji z MySQL na PDO
Kshyhoo
post
Post #1





Grupa: Opiekunowie
Postów: 3 855
Pomógł: 317
Dołączył: 4.01.2005
Skąd: że




Rozpocząłem starcie z PDO smile.gif Postanowiłem przepisać nieco kodu z MySQL na PDO w ramach treningu. Początkowo szło dobrze, ale teraz przegrywam walkę. Połączenie to zdaje się błahostka:
  1. try {
  2. $pdo = new PDO('mysql:host='.$db_host.';dbname='.$db_name.';encoding=utf8', $db_user, $db_pass);
  3. //echo 'Połączenie nawiązane!';
  4. } catch(PDOException $e) {
  5. echo 'Error: ' . $e->getMessage(). "<br/>";
  6. die();
  7. }

Zacząłem od takiej oto funkcji, zwracającej dane usera:
  1. function getUser($id) {
  2. $User = mysql_fetch_array(mysql_query("SELECT * FROM g_users WHERE user=$id"));
  3. if(!empty($User))
  4. $User['data_product'] = mysql_fetch_array(mysql_query("SELECT * FROM g_products WHERE product=".$User['id_product']));
  5. if(empty($User))
  6. $User['function'] = -1;
  7. return $User;
  8. }

  1. function getUser2($id) {
  2. extract($GLOBALS);
  3. $r = $pdo->query("SELECT * FROM g_users WHERE user=$id");
  4. $User = $r->fetch(PDO::FETCH_ASSOC);
  5. if(!empty($User)) {
  6. $r = $pdo->query("SELECT * FROM g_products WHERE product=".$User['id_product']."");
  7. $User['data_product'] = $r->fetch(PDO::FETCH_ASSOC);
  8. }
  9. if(empty($User))
  10. $User['function'] = -1;
  11. return $User;
  12. }

Funkcja zwraca identyczne dane. Czy można to zrobić lepiej?


--------------------
Go to the top of the page
+Quote Post
redeemer
post
Post #2





Grupa: Zarejestrowani
Postów: 915
Pomógł: 210
Dołączył: 8.09.2009
Skąd: Tomaszów Lubelski/Wrocław

Ostrzeżenie: (0%)
-----


Jeżeli chodzi o PDO to używaj "prepared statements".

1) extract($GLOBALS); - naprawdę?

2)
  1. if(!empty($User)) {
  2. ....
  3. }
  4. if(empty($User))
To można zamienić na if else.

3) te dwa zapytania do bazy na 99% można zastąpić jednym


--------------------
Go to the top of the page
+Quote Post
Kshyhoo
post
Post #3





Grupa: Opiekunowie
Postów: 3 855
Pomógł: 317
Dołączył: 4.01.2005
Skąd: że




1. Inaczej zgłasza błąd Fatal error: Call to a member function query()
2. No można.
3. Ledwie skleciłem to wink.gif Muszę wpierw załapać PDO.


--------------------
Go to the top of the page
+Quote Post
redeemer
post
Post #4





Grupa: Zarejestrowani
Postów: 915
Pomógł: 210
Dołączył: 8.09.2009
Skąd: Tomaszów Lubelski/Wrocław

Ostrzeżenie: (0%)
-----


Cytat(Kshyhoo @ 22.03.2014, 14:59:13 ) *
1. Inaczej zgłasza błąd Fatal error: Call to a member function query()
Zgadza się, jest to związane z zakresem zmiennych (funkcja getUser2() nie ma dostępu do zmiennej $pdo).

Opcje:
1) wystarczy: global $pdo; (brzydko)
2) przekaż do funkcji zmienną $pdo jako argument (lepiej)
3) przepisać to na kod obiektowy np. z użyciem wzorca singleton i poczytać o dependency injection (najlepiej) wink.gif


--------------------
Go to the top of the page
+Quote Post
Kshyhoo
post
Post #5





Grupa: Opiekunowie
Postów: 3 855
Pomógł: 317
Dołączył: 4.01.2005
Skąd: że




1. global $pdo nie działało sad.gif
2. to ma sens
3. a świstak siedzi i zawija w sreberka wink.gif

Mam kolejny problem. Taki kod:
  1. $prods = mysql_query("SELECT * FROM tabela1 LEFT JOIN tabela2 ON prod=prod_id WHERE kat_id=".$User['id_kat']);
  2.  
  3. if(mysql_num_rows($prods) == 0) {

na taki:
  1. $prods = $pdo->query("SELECT * FROM tabela1 LEFT JOIN tabela2 ON prod=prod_id WHERE kat_id=".$User['id_kat']);
  2.  
  3. if ($prods->fetchColumn() === 0) {

To działa, zwraca takie same wyniki, ale czy można lepiej?

Druga rzecz. Kodowanie połączenia. Miałem:
  1. mysql_query("SET NAMES 'utf8'");

W bazie polskie znaki, pliki również UTF-8 a po zmianie na PDO wychodzą krzaki...


--------------------
Go to the top of the page
+Quote Post
Turson
post
Post #6





Grupa: Zarejestrowani
Postów: 4 291
Pomógł: 829
Dołączył: 14.02.2009
Skąd: łódź

Ostrzeżenie: (0%)
-----


Łącząc się z bazą za pomocą PDO musisz ustalić kodowanie
  1. $db = new PDO('mysql:host=localhost;dbname=xxx', 'user', 'pass', array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8'"))
Go to the top of the page
+Quote Post
viking
post
Post #7





Grupa: Zarejestrowani
Postów: 6 380
Pomógł: 1116
Dołączył: 30.08.2006

Ostrzeżenie: (0%)
-----


A w jaki sposób to wywołujesz? Dla mysql możesz bezpośrednio
  1. $connect = new PDO(
  2. "mysql:host=$host;dbname=$db",
  3. $user,
  4. $pass,
  5. PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
  6. PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"
  7. )
  8. );


albo ....exec("set names utf8");


--------------------
Go to the top of the page
+Quote Post
Kshyhoo
post
Post #8





Grupa: Opiekunowie
Postów: 3 855
Pomógł: 317
Dołączył: 4.01.2005
Skąd: że




W pierwszym poście zamieściłem połączenie z bazą. Czyli coś takiego powinienem użyć?
  1. $pdo = new PDO('mysql:host='.$db_host.';dbname='.$db_name.';encoding=utf8', $db_user, $db_pass, array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8'"))



--------------------
Go to the top of the page
+Quote Post
Turson
post
Post #9





Grupa: Zarejestrowani
Postów: 4 291
Pomógł: 829
Dołączył: 14.02.2009
Skąd: łódź

Ostrzeżenie: (0%)
-----


Zobacz czy działa a potem pytaj wink.gif
Go to the top of the page
+Quote Post
Kshyhoo
post
Post #10





Grupa: Opiekunowie
Postów: 3 855
Pomógł: 317
Dołączył: 4.01.2005
Skąd: że




No właśnie, nie działa...


--------------------
Go to the top of the page
+Quote Post
viking
post
Post #11





Grupa: Zarejestrowani
Postów: 6 380
Pomógł: 1116
Dołączył: 30.08.2006

Ostrzeżenie: (0%)
-----


Jaka wersja PHP? Poniżej 5.coś nie działało. Spróbuj jeszcze drugą metodę z exec


--------------------
Go to the top of the page
+Quote Post
Kshyhoo
post
Post #12





Grupa: Opiekunowie
Postów: 3 855
Pomógł: 317
Dołączył: 4.01.2005
Skąd: że




Nie, nie, mam powyżej 5. Być może to wina tego zapytania ostatniego. Zauważyłem teraz, że ucina mi pierwszy rekord.


--------------------
Go to the top of the page
+Quote Post
Turson
post
Post #13





Grupa: Zarejestrowani
Postów: 4 291
Pomógł: 829
Dołączył: 14.02.2009
Skąd: łódź

Ostrzeżenie: (0%)
-----


  1. $prods = $pdo->query("SELECT * FROM tabela1 LEFT JOIN tabela2 ON prod=prod_id WHERE kat_id=".$User['id_kat']);
  2. if($prods->rowCount()>0){
  3. while($row=$prods->fetchAll()){
  4. //cos tam
  5. }
  6. }
  7. else echo "Brak wyników";


poza tym powinieneś bindować dane, inaczej stosowanie PDO nie ma sensu

Ten post edytował Turson 23.03.2014, 15:23:28
Go to the top of the page
+Quote Post
Kshyhoo
post
Post #14





Grupa: Opiekunowie
Postów: 3 855
Pomógł: 317
Dołączył: 4.01.2005
Skąd: że




To wiem, tak robię. Tylko nigdzie nie mogę znaleźć dobrego artykułu na temat PDO. Nie wiem np., czy ma sens bindowanie zapytań z danymi niepochodzącymi z formularzy i linków...


--------------------
Go to the top of the page
+Quote Post
vonski
post
Post #15





Grupa: Zarejestrowani
Postów: 292
Pomógł: 89
Dołączył: 27.12.2006
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


Cytat(Turson @ 23.03.2014, 16:22:51 ) *
  1. $prods = $pdo->query("SELECT * FROM tabela1 LEFT JOIN tabela2 ON prod=prod_id WHERE kat_id=".$User['id_kat']);
  2. if($prods->rowCount()>0){
  3. while($row=$prods->fetchAll()){
  4. //cos tam
  5. }
  6. }
  7. else echo "Brak wyników";


while($row = $prods->fetchAll()) ?

Bardziej: while($row=$prods->fetch()){ .. }


--------------------
Zend Certified Engineer | Microsoft Certified Professional: Programming in HTML5 with JavaScript & CSS3 | Blog
Go to the top of the page
+Quote Post
Kshyhoo
post
Post #16





Grupa: Opiekunowie
Postów: 3 855
Pomógł: 317
Dołączył: 4.01.2005
Skąd: że




Tak właśnie miałem, zmieniłem:
  1. while($prod = mysql_fetch_array($prods)) {

na:
  1. while($prod = $prods->fetch()) {

Inaczej nie zwracało wyników.

Nadal nie mam polskich znaków. Tabele w utf8_general_ci.


--------------------
Go to the top of the page
+Quote Post
trueblue
post
Post #17





Grupa: Zarejestrowani
Postów: 6 806
Pomógł: 1828
Dołączył: 11.03.2014

Ostrzeżenie: (0%)
-----


Po połączeniu wykonaj trzy zapytania:
SET character_set_connection=utf8
SET character_set_client=utf8
SET character_set_results=utf8


--------------------
Go to the top of the page
+Quote Post
viking
post
Post #18





Grupa: Zarejestrowani
Postów: 6 380
Pomógł: 1116
Dołączył: 30.08.2006

Ostrzeżenie: (0%)
-----


Więc może te dane nie są w UTF-8 albo nie ustawiasz header. W stopce mam artykuł o PDO. Może Ci pomoże.


--------------------
Go to the top of the page
+Quote Post
Kshyhoo
post
Post #19





Grupa: Opiekunowie
Postów: 3 855
Pomógł: 317
Dołączył: 4.01.2005
Skąd: że




Czytałem ten artykuł. Wszystko wyświetla się dobrze, z zapytań MySQL, po zmianie na PDO krzaczy.


--------------------
Go to the top of the page
+Quote Post
Turson
post
Post #20





Grupa: Zarejestrowani
Postów: 4 291
Pomógł: 829
Dołączył: 14.02.2009
Skąd: łódź

Ostrzeżenie: (0%)
-----


Cytat(vonski @ 23.03.2014, 15:28:41 ) *
while($row = $prods->fetchAll()) ?

Bardziej: while($row=$prods->fetch()){ .. }

$dane = $prods->fetchAll();
foreach($dane as $v)

tak zazwyczaj piszę stąd mi się pomyliło.

Kschyhoo, ja zawsze robię tak:
- baza w utf8_polish_ci
- plik w utf8, dokument w utf8
- połączenie z bazą jak podałem
i nigdy nie mam problemu z pl znakami
Go to the top of the page
+Quote Post

5 Stron V   1 2 3 > » 
Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 20.08.2025 - 17:11