Nə üçün verilənlər bazası ilə işləmək üçün PDO-dan istifadə etməlisiniz. PHP PDO - verilənlər bazası ilə düzgün işləmək Php sorğusu pdo nümunələrinin silinməsi




Ötən gün php PDO ilə məşğul olmaq qərarına gəldim. Yeni texnologiyaları öyrənmək maraqlı və zəruridir. Rus sənədlərini heç yerdə tapa bilmədim, ona görə də dərc etmək qərarına gəldim. Ümid edirəm bu məqalə sizin üçün maraqlı olacaq.

Giriş

Əvvəlcə PHP Data Objects (PDO) ilə başlayaq - PHP dilində verilənlər bazalarına daxil olmaq üçün yüngül interfeys. MS SQL, Firebird, MySQL, Oracle, PostgreSQL, SQLite və başqaları kimi əksər verilənlər bazası ilə işləyə bilər. Ancaq burada diqqət etmək lazımdır ki, PDO verilənlər bazası ilə işləmək üçün lazımi funksionallığı təmin edir, lakin hər bir verilənlər bazası növü üçün PHP genişləndirilməsi şəklində öz verilənlər bazasına giriş sürücüsü quraşdırılmalıdır.

PDO ilə siz verilənlər bazası tipindən tamamilə asılı olmayan proqramlar yarada bilərsiniz, eyni zamanda verilənlər bazalarının əksər funksiyalarından, məsələn, hazırlanmış bəyanatlar və ya əməliyyatların yaradılması kimi istifadə edə bilərsiniz. Bu funksionallıq verilənlər bazası tərəfindən dəstəklənmirsə, PDO öz vasitələrindən istifadə edərək bu funksiyanı təqlid edir və bununla da proqram məntiqini heç bir şəkildə pozmur.

Qoşulmaq olduqca sadədir, istisna olmaqla, indi bir sətirdə hansı verilənlər bazasına qoşulduğunuzu, host adını və verilənlər bazasının adını dərhal göstərməlisiniz.

Format belədir:

verilənlər bazası_type:host=hostname;db=name

Nümunəyə baxaq, lakin PDO kitabxanasından (PDOException) istisnalardan istifadə etməklə nümunəni bir az mürəkkəbləşdirək. Beləliklə, verilənlər bazası ilə uğursuz bir əlaqə halında, heç bir yerdən gələn bir dəstə kod deyil, bu barədə aydın bir mesaj alırıq.

cəhd edin ( $db = new PDO("mysql:host=localhost;dbname=test" , "root" , "" ); $rows = $db -> exec ("CREATE TABLE `testing'(id INT PRIMARY KEY AUTO_INCREMENT, fname VARCHAR(20) NOT NULL DEFAULT "", e-poçt VARCHAR(50) NOT NULL DEFAULT "")" ) ; ) catch(PDOException $e ) ( ölür("Xəta: " . $e -> getMessage () ); )

SQL ifadəsində səhv etmisinizsə, PDO-nun xüsusi funksiyaları var:

errorCode() – xəta nömrəsini qaytarır və

errorInfo() – həm xətanın nömrəsini, həm də təsvir mətnini ehtiva edən massivi qaytarır

Sorğular birbaşa iki funksiya ilə edilə bilər:

exec() və query()

Aralarındakı fərq qaytarılan nəticənin növündədir, exec sorğu nəticəsində təsirlənmiş sətirlərin sayını qaytarır, ikincisi isə PDOStatement obyektində sorğunun nəticəsini qaytarır, bu barədə bir az danışacağıq. sonra.

İndi bu funksiyaları koda əlavə edək və nümunəni bir az daha mürəkkəb edək:

// konfiqurasiyanın əvvəlində müəyyən edin("DB_DRIVER" , "mysql" ); müəyyənləşdirmək("DB_HOST" , "localhost" ); müəyyənləşdirmək("DB_NAME" , "test" ); müəyyənləşdirmək("DB_USER" , "root" ); müəyyənləşdirmək("DB_PASS" , "" ); cəhd edin ( // verilənlər bazasına qoşulun $connect_str = DB_DRIVER . ":host=" . DB_HOST . ";dbname=" . DB_NAME; $db = new PDO($connect_str , DB_USER, DB_PASS) ; // bir neçə sətir daxil edin əvvəlki nümunədəki cədvəl $rows = $db -> exec ("INSERT INTO `testing` VALUES (null, "Ivan"," [email protected]"), (null, "Petr", " [email protected]"), (null, "Vasili", " [email protected]") "); $error_array = $db -> errorInfo () ; əgər ($db ->
" ; // əgər sorğu uğurlu olarsa, // sonra təsirə məruz qalan sətirlərin sayını çap edin, əgər ($rows ) əks-sədası "Təsirə məruz qalan sətirlərin sayı: " . $rows ."
" ; // indi verilənlər bazasından bir neçə sətir seçin $nəticə = $db -> sorğu ("SEÇ * FROM `test` LIMIT 2" ); // SQL ifadəsində xəta olarsa, $ səhv mesajını göstərin error_array = $db -> errorInfo () ; if ($db -> errorCode () != 0000) əks-səda "SQL xətası: " . $error_array [ 2 ] .

" ; // indi biz PDOStatement sinfindən məlumatları alırıq, bu zaman ($row = $result -> fetch () ) ( // nəticədə print_r assosiativ massivi alırıq.($sətir); ) ) tutmaq (PDOException $e ) ( ölmək("Xəta: " . $e -> getMessage () ); )

Hazırlanmış ifadələr

Hazırlanmış ifadələr adi SQL sorğularına çox bənzəyir, lakin bəzi üstünlüklərə malikdir. Birincisi, onlar daha yüksək icra sürətinə malikdirlər, ikincisi, təhlükəsizlik baxımından daha etibarlıdırlar, çünki onlara ötürülən bütün parametrlər avtomatik olaraq hər cür inyeksiyadan qorunur.

Çoxlu eyni sorğuları yerinə yetirərkən onlar sorğunun hər dəfə yenidən tərtib edilməsi ilə müqayisədə əhəmiyyətli sürət üstünlüyünə malikdirlər. Tətbiq və verilənlər bazası arasında trafik də saxlanılır.

PDO hazırlanmış ifadələrlə işləmək üçün rahat funksiyaları təmin edir. Əgər seçilmiş verilənlər bazası növü hazırlanmış ifadələrlə işləməyi dəstəkləmirsə, PDO sadəcə öz metodları ilə onların işini təqlid edəcək.

Beləliklə, ilk növbədə, hazırlanmış ifadə yaradaq, bunu Prepare() funksiyası yerinə yetirir

Parametr kimi SQL sorğusunu götürür, lakin orada dəyişdirilməli olan dəyərlər əvəzinə sual işarəsi (?) və ya psevdo adı şəklində ola bilən psevdo dəyişənlər yerləşdirilir. iki nöqtə ilə başlayan dəyişən (:)

$sth1 = $db->hazırla("SEÇ * FROM `test` id=:id");

$sth2 = $db->hazırla("SEÇ * FROM `test` id=?");

Dəyişənləri necə təyin etdiyinizdən asılı olaraq gələcək işiniz bundan asılı olacaq.

Əgər siz dəyişənləri sual işarəsi ilə təyin etmisinizsə, o zaman dəyişənlərin göründüyü ardıcıllıqla icra funksiyasına bir sıra dəyərlər ötürün.

Əgər dəyişənləri adlarla təyin etmisinizsə, onda siz funksiyalardan istifadə edərək hər bir dəyişənə dəyər təyin etməli olacaqsınız:

bindValue() – psevdo dəyişənə dəyər təyin edir

bindParam() – psevdo dəyişəni real dəyişənə bağlayır və real dəyişən dəyişdikdə artıq heç bir əlavə funksiyaya zəng etmək lazım deyil, dərhal() icra edə bilərsiniz.

Birinci seçimdən istifadə nümunəsi:


Nəzərə alın ki, PDO obyekti PDOStatement sinfində hazırlanmış ifadə yaratdıqdan sonra biz ondan yalnız istifadə edirik; müvafiq olaraq onun öz errorCode, errorInfo funksiyaları, həmçinin sorğuların icrasının nəticəsi var ki, bu da dərhal orada saxlanılır.

İndi ikinci yol.

Pseudo dəyişənə dəyər təyin etmək üçün bindValue() funksiyasından istifadə edin

Bu kodu psevdo dəyişəni real ilə əlaqələndirməklə daha sadə şəkildə yazmaq olar:

Onu da əlavə etmək lazımdır ki, üçüncü parametr kimi dəyişənin növünü göstərmək (lazımsız səhvlərə yol verməmək üçün) çox arzuolunandır. Şəxsən mən dəyişən tipi olmadığından WHERE ifadəsində səhvlərlə qarşılaşdım, çünki o dəyişəni rəqəm deyil, mətn hesab edirdi.

$sth3->bindParam(':id',$id, PDO::PARAM_INT);

$sth3->bindParam(':id',$id, PDO::PARAM_STR);

Bu cür hazırlanmış ifadələrdən istifadə etməyin başqa bir çox gözəl üstünlüyü dəyişənlərdən qaçmaqdır. Prosedura əvəz etməzdən əvvəl bütün dəyişənlər qaçır və heç bir SQL inyeksiyası qorxulu deyil.

Əməliyyatlar

Tranzaksiya hamısı yerinə yetirilməli olan verilənlər bazası sorğularının toplusudur. Hər hansı sorğu tamamlanmazsa və ya xəta ilə icra olunmazsa, əməliyyat ləğv edilir və verilənlər bazasında məlumat dəyişikliyi baş vermir.

Bu, çoxsaylı sorğular üzrə məlumatların bütövlüyünün təmin edilməsi üçün lazımdır. məsələn, hesabdan hesaba vəsait köçürərkən.

PDO-da əməliyyatı başa çatdırmaq üçün siz əl ilə təsdiqləmə rejiminə keçməlisiniz.

Yeri gəlmişkən, əməliyyatlar hər zaman istifadə olunur, lakin adətən PDO avtomatik təsdiq rejimində işləyir, ona görə də bütün əməliyyatlar bir sorğudan ibarətdir.

Avtomatik təsdiqləmə rejimini söndürmək üçün əmri yerinə yetirin:

$db->beginTransaction();

Bundan sonra, bu əməliyyatda etmək üçün verilənlər bazasına lazım olan qədər sorğu yerinə yetiririk.

Və yalnız bütün sorğular tamamlandıqdan sonra funksiya ilə əməliyyatı təsdiqləyə bilərsiniz

$db->commit();

və ya əməliyyatı ləğv edin

$db->geri qaytarma();

Budur əməliyyatların kiçik bir nümunəsi:

cəhd edin ( $connect_str = DB_DRIVER . ":host=" . DB_HOST . ";dbname=" . DB_NAME; $db = yeni PDO($connect_str , DB_USER, DB_PASS) ; $rows = $db -> exec ("CREATE TABLE ` testing`(id INT PRIMARY KEY AUTO_INCREMENT, fname VARCHAR(20) NOT NULL DEFAULT "", email VARCHAR(50) NOT NULL DEFAULT "", money INT NOT NULL DEFAULT 0) ENGINE=InnoDB;" ) ; $sətirlər = $b -> exec ("Sınaq DƏYƏRLƏRİNƏ DAXİL EDİN (null, "İvan", " [email protected]", 15000), (null, "Petr", " [email protected]", 411000), (null, "Vasiliy", " [email protected]", 1500000) " ); // Gəlin 50000 məbləğini İvandan // Peterə köçürməyə çalışaq $summ = 50000 ; $transaction = true ; $db -> startTransaction (); $sth1 = $db -> sorğu ("WHERE fname="İvan" testindən pul SEÇİN" ); $sth2 = $db -> sorğu ("WHERE fname="Petr" testindən pul SEÇİN" ); $row1 = $sth1 -> gətir () ; $row2 = $sth2 -> gətir () ; əgər (! $row1 || ! $row2 ) $transaction = false ; $total2 = $summ + $row2 [ "pul" ] ; $total1 = $row1 [ "pul" ] - $summ ; əgər (ümumi $1< 0 || $total2 < 0) $transaction = false ; $num_rows1 = $db ->exec ( . $total1 . "" WHERE fname="İvan"" ) ; $num_rows2 = $db -> exec ("YENİLƏNİB `test` SET money="" . $total2 . "" WHERE fname="Petr"") ; if ($transaction ) ( "Əməliyyat uğurla tamamlandı" əks-sədası ; $db -> commit () ; ) else ( "Əməliyyat uğursuz oldu" ; $db -> geri qaytarma () ; ) ) catch(PDOException $e ) ( ölmək("Xəta: " . $e -> getMessage () ); )

Onu da qeyd etmək lazımdır ki, bütün cədvəl növləri əməliyyatları dəstəkləmir, ona görə də bu nümunədə standart MyISAM əvəzinə InnoDb cədvəlindən istifadə etdim.

Sonda demək istərdim ki, bu, PDO ilə bağlı tam təlimatdan uzaqdır. Siz həmişə ən son və tam məlumatı burada əldə edə bilərsiniz: http://www.php.net/manual/en/book.pdo.php

Araşdırın və yaradın.

Bu gün mən PDO-ya həsr olunmuş bir sıra məqalələrə başlayıram, burada PDO-nun nə olduğunu, niyə ehtiyacımız olduğunu və ondan necə istifadə edəcəyimizi nəzərdən keçirəcəyik.

Şübhəsiz ki, çoxları PDO abreviaturasını artıq eşitmişlər, lakin bunun nə olduğunu az adam bilir. Beləliklə, bu gün bu barədə danışaq.

PDO nədir?

PDO (PHP Data Objects) sadəcə olaraq bizə müəyyən verilənlər bazasından mücərrədləşməyə imkan verən interfeysdir. Bir nümunə ilə göstərmək daha yaxşıdır.

Mysql_connect($host, $user, $pass); // MySQL
mysql_select_db($db);

Sqlite_open($db); //sqlite

Pg_connect("host=$host, dbname=$db, user=$user, password=$pass"); // PostgreSQL

Yuxarıdakı kod üç müxtəlif verilənlər bazasına qoşulma üsullarını təqdim edir: MySQL, sqlite və PostgreSQL. Gördüyünüz kimi, hər bir verilənlər bazasının funksiyaları fərqlidir.

Eyni şey digər hərəkətlərə də aiddir. Məsələn, verilənlər bazasından məlumatların seçilməsi.

$sql = "INSERT INTO(ad, pass) VALUES($name, $pass)";

Mysql_query($sql); // MySQL
sqlite_query($sql); //sqlite
pg_query($sql); // PostgreSQL

PDO nə üçün lazımdır?

Təsəvvür edək ki, bizim nəhəng PostgreSQL verilənlər bazamız var və biz onu MySQL-ə dəyişməyə qərar verdik. Çoxlu kodu yenidən yazmalı olacağıq və çox güman ki, bəzi səhvlər olacaq. Bu problemi həll etmək üçün müəyyən bir verilənlər bazasından asılı olmamağa imkan verən PDO mövcuddur.

İndi necə qoşula biləcəyimizə baxaq.

$db = yeni PDO("mysql:host=$host;dbname=$db", $user, $pass); // MySQL
$db = yeni PDO("sqlite:host=$host;dbname=$db", $user, $pass); //sqlite
$db = yeni PDO("pgsql:host=$host;dbname=$db", $user, $pass); // PostgreSQL

Yuxarıdakı koddan da göründüyü kimi, bu üç əlaqədə yalnız verilənlər bazasının adı olan sətir dəyişir, qalanları isə eynidir.

Bir şeyi seçmək üçün belə yaza bilərik:

$db->exec($sql);

Hamısı! Hansı verilənlər bazasına malik olmağımızdan asılı olmayaraq sorğu icra olunacaq.

Dəstək

PDO PHP 5.1-dən bəri mövcuddur. Hansı verilənlər bazasından istifadə etdiyimizi "unuda bilməmiz" üçün onların sürücüləri bizim üçün hər şeyi edir. Onları aktivləşdirmək üçün php.ini faylına keçin və orada extension=php_pdo_ ilə başlayan sətirləri, sonra verilənlər bazası adını tapın və şərhləri silin.

Bütün bunlar giriş məqaləsi üçündür və növbəti məqalədə biz PDO-dan necə istifadə edəcəyimizi anlamağa başlayacağıq.












PDO-nun öz ağıllı əlaqə metodu var. Üstəlik, əlaqə zamanı bəziləri çox faydalı olan çoxlu seçimlər təyin edə bilərsiniz. Tam siyahı tapıla bilər, lakin yalnız bir neçəsi vacibdir.

Düzgün əlaqə nümunəsi:

$host = "127.0.0.1" ;
$db = "test" ;
$user = "root" ;
$pass = "" ;
$charset = "utf8" ;

$dsn = "mysql:host= $host ;dbname= $db ;charset= $charset " ;
$opt = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => yanlış,
];
$pdo = yeni PDO ($dsn, $user, $pass, $opt);

Burda nə baş verir?

$dsn işləyəcəyimiz verilənlər bazası növünü (mysql), host, verilənlər bazası adını və simvol dəstini müəyyən edir.
- sonra istifadəçi adı və parol
- bundan sonra təlimatların heç birində yazılmayan bir sıra seçimlər göstərilir.

Baxmayaraq ki, bu massiv yuxarıda qeyd edildiyi kimi son dərəcə faydalı bir şeydir. Ən vacibi odur ki, səhv rejimi yalnız istisnalar şəklində təyin edilməlidir.
- Birincisi, çünki bütün digər rejimlərdə PDO səhv haqqında anlaşılan heç nə bildirmir,
- ikincisi, istisna həmişə əvəzolunmaz yığın izini ehtiva etdiyi üçün,
- üçüncüsü, istisnaları idarə etmək olduqca rahatdır.

Üstəlik, çalışqan hamsterlərin sevdiyi kimi HƏR sorğuya yazmamaq üçün FETCH_MODE-u defolt olaraq təyin etmək çox rahatdır.
Həmçinin burada pconnect rejimini, hazırlanmış ifadələrin emulyasiyasını və bir çox başqa qorxulu sözləri təyin edə bilərsiniz.

Nəticədə biz bütün skript boyu işlədiyimiz $pdo dəyişənini alırıq.

Sorğuları yerinə yetirmək üçün iki üsuldan istifadə edə bilərsiniz.
Əgər sorğuya heç bir dəyişən ötürülmürsə, onda siz query() funksiyasından istifadə edə bilərsiniz. O, sorğunu yerinə yetirəcək və xüsusi obyekti - PDO bəyanatını qaytaracaq. Çox təxmini olaraq, onu mysql_query() tərəfindən qaytarılan mysql resursu ilə müqayisə edə bilərsiniz. Bu obyektdən məlumatları ya ənənəvi üsulla, while və ya foreach() vasitəsilə əldə edə bilərsiniz. Alınan məlumatları aşağıda müzakirə olunan xüsusi formatda qaytarmağı da xahiş edə bilərsiniz.
$stmt = $pdo -> sorğu ("İstifadəçilərdən ad SEÇİN" );
isə ($sətir = $stmt -> gətir ())
{
}

Əgər sorğuya ən azı bir dəyişən ötürülürsə, bu sorğu yalnız hazırlanmış ifadələr vasitəsilə yerinə yetirilməlidir. Bu nədir? Bu, adi SQL sorğusudur, burada dəyişən yerinə xüsusi marker yerləşdirilir - yer tutucu. PDO, ötürülən dəyişənlərin sırasının vacib olduğu mövqe tutucularını (?) və sıralamanın vacib olmadığı adlandırılmış yertutanları (:name) dəstəkləyir. Nümunələr:
$sql = ;
$sql = ;
Belə bir sorğunu yerinə yetirmək üçün onu ilk növbədə hazırlamaq () funksiyasından istifadə etməklə hazırlamaq lazımdır. O, həmçinin PDO bəyanatını qaytarır, lakin hələ heç bir məlumat olmadan. Onları əldə etmək üçün əvvəllər dəyişənləri daxil edərək bu sorğunu yerinə yetirməlisiniz. Onu iki yolla köçürə bilərsiniz:
Çox vaxt siz sadəcə olaraq execute() metodunu yerinə yetirərək ona dəyişənlər massivini keçirə bilərsiniz:
$stmt = $pdo -> hazırlamaq ("İstifadəçilərdən adı SEÇİN E-poçt ünvanı =?" );
$stmt -> icra (massiv($email ));

$stmt = $pdo -> hazırlamaq ("İstifadəçilərdən ad SEÇİN HARƏDƏ email = :e-poçt" );
$stmt -> icra (array("email" => $email ));
Gördüyünüz kimi, adlandırılmış yer tutucular üçün açarların yer tutucuların adlarına uyğun gəlməli olduğu massiv icra() üçün ötürülməlidir.

Bəzən, çox nadir hallarda, dəyişənlər bindValue() / bindParam() istifadə edərək sorğuya bir-bir bağlandıqda və sonra yalnız yerinə yetirildikdə ikinci üsul tələb oluna bilər. Bu halda, heç bir şey icra () üçün ötürülmür. Bir nümunə təlimatda tapıla bilər.
Bu metoddan istifadə edərkən həmişə bindValue()-ə üstünlük verilməlidir? çünki bindParam() funksiyasının davranışı yeni başlayanlar üçün aydın deyil və problemlərə gətirib çıxaracaq.

Daha sonra siz PDO ifadəsini yuxarıdakı kimi istifadə edə bilərsiniz. Məsələn, foreach vasitəsilə:
$stmt = $pdo -> hazırlamaq ("İstifadəçilərdən adı SEÇİN E-poçt ünvanı =?" );
$stmt ->
foreach ($stmt kimi $sətir)
{
echo $row [ "ad" ] . "\n" ;
}

ƏHƏMİYYƏTLİ: Hazırlanmış ifadələr PDO-dan istifadə etməyin əsas səbəbidir, çünki bu, dəyişənləri əhatə edən SQL sorğularını yerinə yetirməyin yeganə təhlükəsiz yoludur.

Həmçinin, hazır () / execute() müxtəlif məlumat dəstləri ilə bir dəfə hazırlanmış sorğunu təkrar icra etmək üçün istifadə edilə bilər. Praktikada bu çox nadir hallarda tələb olunur və çox sürət qazandırmır. Ancaq eyni tipli çoxlu sorğular etmək lazım gələrsə, bunu belə yaza bilərsiniz:

$data = massiv(
1 => 1000,
5 => 300,
9 => 200,
);

$stmt = $pdo -> hazırlamaq ("YENİLƏNİB istifadəçilər SET bonus = bonus + ? HARADAN id =?" );
foreach ($id => $bonus kimi $data)
{
$stmt -> icra et ([ $bonus , $id ]);
}

Burada sorğunu bir dəfə hazırlayırıq və sonra dəfələrlə icra edirik.

Biz artıq verilənlər bazasından sətirlərin ardıcıl alınması üçün istifadə olunan fetch() metodu ilə tanış olmuşuq. Bu metod mysq_fetch_array() funksiyasının və oxşarlarının analoqudur, lakin o, fərqli fəaliyyət göstərir: burada bir çox funksiya əvəzinə biri istifadə olunur, lakin onun davranışı ötürülən parametrlə müəyyən edilir. Bu parametrlər haqqında daha sonra ətraflı yazacağam, lakin qısa tövsiyə olaraq FETCH_LAZY rejimində fetch() funksiyasından istifadə etməyi tövsiyə edərdim:
$stmt = $pdo -> hazırlamaq ("İstifadəçilərdən adı SEÇİN E-poçt ünvanı =?" );
$stmt -> icra ([ $_GET [ "e-poçt" ]]);
isə ($sətir = $stmt -> gətir (PDO :: FETCH_LAZY ))
{
echo $sətir [ 0 ] . "\n" ;
echo $row [ "ad" ] . "\n" ;
echo $row -> ad. "\n" ;
}
Bu rejimdə heç bir əlavə yaddaş sərf edilmir və bundan əlavə sütunlara üç yolla - indeks, ad və ya mülkiyyət vasitəsilə daxil olmaq olar.

PDO bəyanatında tək sütunun dəyərini almaq üçün köməkçi funksiya da var. Yalnız bir sahə tələb etsək çox rahatdır - bu halda yazının miqdarı əhəmiyyətli dərəcədə azalır:
$stmt = $pdo -> hazırlamaq ("WHERE id= Cədvəldən adı SEÇİN?" );
$stmt -> icra (massiv($id ));
$name = $stmt -> fetchColumn();

Lakin ən maraqlı funksiyası, ən böyük funksionallığı ilə fetchAll() funksiyasıdır. Məhz bu, PDO-nu yalnız aşağı səviyyəli sürücü deyil, verilənlər bazası ilə işləmək üçün yüksək səviyyəli kitabxanaya çevirir.

FetchAll() sorğunun qaytardığı bütün sətirlərdən ibarət massivi qaytarır. Bundan iki nəticə çıxarmaq olar:
1. Sorğu çoxlu məlumat qaytardıqda bu funksiyadan istifadə edilməməlidir. Bu halda fetch() ilə ənənəvi loopdan istifadə etmək daha yaxşıdır.
2. Müasir PHP proqramlarında verilənlər heç vaxt alındıqdan dərhal sonra çıxarılmadığından, lakin bu məqsədlə şablona köçürüldüyündən, fetchAll() sadəcə əvəzolunmaz hala gəlir və bu, dövrələrin əl ilə yazılmasının qarşısını almağa və bununla da kodun miqdarını azaltmağa imkan verir.

Sadə massiv əldə etmək.
Parametrlər olmadan çağırılan bu funksiya standart olaraq FETCH_MODE-da göstərilən formatda verilənlər bazasından sətirləri ehtiva edən müntəzəm indeksləşdirilmiş massivi qaytarır. PDO::FETCH_NUM, PDO::FETCH_ASSOC, PDO::FETCH_OBJ sabitləri formatı tez dəyişə bilər.

Sütun əldə etmək.
Bəzən bir dəstə sətirdən tək bir sahə tələb etməklə sadə bir ölçülü massiv əldə etmək lazımdır. Bunun üçün PDO::FETCH_COLUMN rejimindən istifadə edin
$data = $pdo -> sorğu ("İstifadəçilərdən ad SEÇİN" ) -> fetchAll (PDO :: FETCH_COLUMN );
massiv (
0 => "John" ,
1 => "Mayk",
2 => "Məryəm",
3 => "Kati",
)

Açar-dəyər cütləri əldə edilir.
Eyni sütunu əldə etmək istənildikdə, lakin nömrələrlə deyil, sahələrdən biri ilə indeksləşdirilən məşhur formatdır. Bunun üçün PDO::FETCH_KEY_PAIR sabiti cavabdehdir.
$data = $pdo -> sorğu ("ID, istifadəçilərdən ad SEÇİN" ) -> fetchAll (PDO :: FETCH_KEY_PAIR );
massiv (
104 => "John",
110 => "Mayk" ,
120 => "Məryəm",
121 => "Kati",
)

Bütün sətirləri sahə ilə indeksləşdirin.
Həm də tez-tez verilənlər bazasından bütün sətirləri almaq lazımdır, həm də nömrələrlə deyil, unikal sahə ilə indeksləşdirilir. PDO::FETCH_UNIQUE sabiti bunu edir.
$data = $pdo -> sorğu ("İstifadəçilərdən * SEÇİN") -> fetchAll (PDO :: FETCH_UNIQUE );
massiv (
104 => massiv (
"name" => "John" ,
"avtomobil" => "Toyota" ,
),
110 => massiv (
"name" => "Mayk",
"avtomobil" => "Ford",
),
120 => massiv (
"name" => "Məryəm",
"avtomobil" => "Mazda" ,
),
121 => massiv (
"name" => "Kati",
"avtomobil" => "Mazda" ,
),
)
Yadda saxlamaq lazımdır ki, sütunda əvvəlcə unikal sahəni seçməlisiniz.

PDO-da bir yarım ondan çox müxtəlif məlumat əldəetmə rejimi var. Üstəlik, onları birləşdirə bilərsiniz! Ancaq bu ayrı bir məqalənin mövzusudur.

Hazırlanmış ifadələrlə işləyərkən başa düşməlisiniz ki, yer tutucu yalnız sətri və ya rəqəmi əvəz edə bilər. Nə açar söz, nə identifikator, nə də sətirin bir hissəsi və ya sətirlər toplusu yertutan vasitəsilə əvəz edilə bilməz. Buna görə də, LIKE üçün əvvəlcə bütün axtarış sətirini hazırlamalı və sonra onu sorğuda əvəz etməlisiniz:

$name = "% $ad %" ;
$stm = $pdo -> hazırlamaq ("SEÇ * Cədvəldən HARADA ad LIKE ?" );
$stm -> icra (massiv($name));
$data = $stm -> fetchAll();

Yaxşı, fikri başa düşürsən. Burada da hər şey pisdir. PDO identifikatorlarla işləmək üçün ümumiyyətlə heç bir alət təqdim etmir və onlar köhnə üsulla, əl ilə formatlaşdırılmalıdır (və ya buna baxmayaraq, bir çox digər məsələlər kimi, bunun da sadə və zərif şəkildə həll edildiyi SafeMysql-ə baxın).
Yadda saxlamaq lazımdır ki, identifikatorların formatlaşdırılması qaydaları müxtəlif verilənlər bazaları üçün fərqlidir.

MySQL-də identifikatoru əl ilə formatlaşdırmaq üçün iki şeyi etməlisiniz:
- onu arxa işarələrə ("`") əlavə edin.
- ikiqat artıraraq identifikator daxilində bu simvolları axtarın.

$field = "`" . str_replace ("`" , "``" , $_GET [ "sahə" ]). "`" ;
$sql = $field " ;

Bununla belə, burada bir xəbərdarlıq var. Təkcə formatlaşdırmaq kifayət olmaya bilər. Yuxarıdakı kod bizi klassik inyeksiyadan qoruyur, lakin bəzi hallarda biz düşünmədən birbaşa sorğuda sahə və cədvəl adlarını əvəz etsək, düşmən hələ də arzuolunmaz bir şey yaza bilər. Məsələn, istifadəçilər cədvəlində admin sahəsi var. Əgər daxil olan sahə adları süzülməsə, hər hansı bir axmaq POST-dan avtomatik sorğu yaradan zaman bu sahəyə hər hansı pis şeylər yazacaq.

Buna görə də, aşağıdakı nümunədə olduğu kimi istifadəçidən gələn cədvəllərin və sahələrin adlarının etibarlılığını yoxlamaq məsləhətdir.

Çoxsaylı dərsliklərdə görünə bilən hər hansı bir yerləşdirmə kodu melanxoliya və apsteni öldürmək istəyi gətirir. Eyni adların təkrarı ilə çox kilometrlik konstruksiyalar - $_POST indekslərində, dəyişən adlarında, sorğuda sahə adlarında, sorğuda yer tutucu adlarında, bağlama zamanı yer tutucu adlarında və dəyişən adlarında.
Bu koda baxmaq məndə kimisə öldürmək və ya heç olmasa onu bir az qısaltmaq istəyi yaradır.

Bu, formadakı sahə adlarının cədvəldəki sahə adlarına uyğun olması haqqında konvensiya qəbul etməklə edilə bilər. Sonra bu adları yalnız bir dəfə sadalamaq olar (yuxarıda qeyd olunan əvəzetmədən qorunmaq üçün) və sorğunun yığılması üçün kiçik köməkçi funksiyadan istifadə edilə bilər ki, bu da mysql-in xüsusiyyətlərinə görə həm INSERT, həm də INSERT üçün uyğundur. YENİLƏNİB sorğular:

pdoSet funksiyası ($allowed, & $values, $source = array()) (
$set = "" ;
$dəyərlər = massiv();
əgər (! $mənbə ) $mənbə = & $_POST ;
foreach ($field olaraq icazə verilir) (
if (isset($source [ $field ])) (
$set .= "`" . str_replace ("`" , "``", $field ). "`". "=: $field , " ;
$dəyərlər [ $field ] = $mənbə [ $field ];
}
}
substr qaytarın ($set, 0, - 2);
}

Müvafiq olaraq, yerləşdirmə kodu olacaq

$allowed = massiv("ad" , "soyad" , "e-poçt" ); // icazə verilən sahələr
$sql = "İstifadəçilər SET INSERT INTO" . pdoSet ($ icazə verilir, $ dəyərlər);
$stm = $dbh -> hazırlamaq ($sql );
$stm -> icra ($dəyərlər);

Və yeniləmə üçün - bu:

$allowed = massiv("ad" , "soyad" , "e-poçt" , "parol" ); // icazə verilən sahələr
$_POST ["parol" ] = MD5 ($_POST [ "giriş" ]. $_POST [ "parol" ]);
$sql = "İstifadəçilər SET YENİLƏNİB " . pdoSet ($ icazə verilir, $ dəyərlər). "HERE id = :id" ;
$stm = $dbh -> hazırlamaq ($sql );
$dəyərlər ["id" ] = $_POST ["id" ];
$stm -> icra ($dəyərlər);

Çox təsir edici deyil, amma çox təsirli. Yeri gəlmişkən, xatırlatmaq istərdim ki, əgər siz MySQL ilə təhlükəsiz və rahat iş üçün Class istifadə edirsinizsə, onda bütün bunlar iki sətirdə aparılır.

PDO və açar sözlər
Burada filtrdən başqa bir şey tapmaq mümkün deyil. Buna görə də, sorğuda birbaşa göstərilməyən bütün operatorları ağ siyahı vasitəsilə idarə etmək axmaqlıqdır:

$dirs = massiv("ASC" , "DESC" );
$key = array_search($_GET["dir"], $dirs));
$dir = $sifarişlər [ $key ];
$sql = "Seç * `cədvəl` SİPARİŞ BY $field $dir " ;

Verilənlər bazası ilə əlaqə PDO sinifinin nümunəsi yaradıldıqda qurulur. Hansı sürücüdən istifadə etməyi seçdiyinizin əhəmiyyəti yoxdur; Siz həmişə PDO sinifindən istifadə etməlisiniz. Onun konstruktoru verilənlər bazası mənbəyini (DSN kimi tanınır) təyin etmək üçün parametrləri və istifadəçi adı və parol üçün əlavə parametrləri qəbul edir.

MySQL-ə qoşulma: $dbh = new PDO("mysql:host=localhost;dbname=test", $user, $pass);

Hər hansı bir əlaqə xətası baş verərsə, bir istisna atılacaq: PDOException sinifinin obyekti. Bu vəziyyəti idarə etmək istəyirsinizsə, onu tuta bilərsiniz və ya set_exception_handler() vasitəsilə təyin olunan qlobal istisna işləyicisi üçün buraxa bilərsiniz.

Bağlantı xətalarının idarə edilməsi: cəhd edin ( $dbh = new PDO("mysql:host=localhost;dbname=test", $user, $pass); foreach($dbh->query('SEÇ * FOO'dan) $sətir kimi) ( print_r($row); ) $dbh = null; ) catch (PDOException $e) ( die("Xəta! Budur. Biz gəldik...".$e->getMessage()); )

Xəbərdarlıq: PDO konstruktoru tərəfindən atılan istisnanı tutmasanız, zend mühərriki tərəfindən görülən standart tədbir skripti dayandırmaq və geriyə izləmə göstərməkdir. Bu cəfəngiyat verilənlər bazası ilə ünsiyyətinizin bütün intim detallarını aşkar edəcək. Yəni istifadəçi adı və parol daxil olmaqla verilənlər bazası bağlantısının ətraflı təfərrüatlarını göstərəcək! Bu istisnanı ya açıq şəkildə (try catch ifadəsi ilə) və ya gizli şəkildə set_exception_handler() vasitəsilə tutmaq sizə bağlıdır.

Verilənlər bazası bağlantısı uğurlu olduqdan sonra o, PDO obyekt instansiyasının bütün ömrü boyu aktiv qalır. Əlaqəni bağlamaq üçün siz obyekti məhv etməlisiniz, ona qalan bütün istinadların silinməsini təmin etməlisiniz - bu, obyekti ehtiva edən dəyişənə NULL dəyəri təyin etməklə edilə bilər. Bunu açıq şəkildə etməsəniz, skript çıxdıqda PHP avtomatik olaraq əlaqəni bağlayacaq.

Bağlantının bağlanması: $dbh = new PDO("mysql:host=localhost;dbname=test", $user, $pass); // Biz burada nəsə edirik: ... // İndi isə diqqət: əlaqənin sonu! $dbh = null;

Bir çox veb proqramlar verilənlər bazası serverləri ilə davamlı əlaqə yaratmaqdan faydalanır. Davamlı bağlantılar skript çıxdıqda bağlanmır, lakin başqa skript eyni əlaqə etimadnaməsini istifadə edərək əlaqə tələb etdikdə keşlənir və yenidən istifadə olunur. Davamlı əlaqə önbelleği, skriptin verilənlər bazası ilə əlaqə saxlaması üçün hər dəfə yeni bir əlaqə yaratmaq üçün əlavə yükdən qaçır, nəticədə veb proqramlar daha sürətli işləyir.

Davamlı əlaqənin qurulması: $dbh = new PDO("mysql:host=localhost;dbname=test", $user, $pass, array(PDO::ATTR_PERSISTENT => true));

Nəzərə alın: Davamlı bağlantıdan istifadə etmək istəyirsinizsə, təyin etməlisiniz PDO::ATTR_PERSISTENT PDO sinif konstruktoruna ötürülən sürücü seçimləri massivində. Obyekt yaradıldıqdan sonra bu atributu PDO::setAttribute() vasitəsilə təyin etməklə, sürücü davamlı keçidlərdən istifadə etməyəcək. Həm də, bu halda, bəzi ehtiyaclarınız üçün PDOStatement sinifini genişləndirə bilməyəcəksiniz, yəni. quraşdırmaq mümkün olmayacaq: PDO::ATTR_STATEMENT_CLASS

  • Tərcümə

Bir çox PHP tərtibatçıları verilənlər bazası ilə işləmək üçün mysql və mysqli uzantılarından istifadə etməyə vərdiş etmişlər. Ancaq PHP-də 5.1 versiyasından bəri daha rahat bir yol var - PHP Data Objects. Qısaca PDO adlanan bu sinif məhsuldarlığınızı əhəmiyyətli dərəcədə yaxşılaşdıracaq obyektlərlə və hazırlanmış ifadələrlə işləmək üçün metodlar təqdim edir!

PDO-ya giriş "PDO - PHP Məlumat Obyektləri çoxsaylı verilənlər bazası ilə işləmək üçün universal üsul təklif edən təbəqədir."
Bu, müxtəlif DBMS-lərin sintaksis xüsusiyyətləri ilə bağlı narahatlığı tərtibatçının öhdəsinə buraxır, lakin platformalar arasında keçid prosesini daha az ağrılı edir. Çox vaxt bu, yalnız verilənlər bazası bağlantısı sətirinin dəyişdirilməsini tələb edir.


Bu məqalə mysql və mysqli-dən istifadə edən insanlar üçün yazılmışdır ki, onlara daha güclü və çevik PDO.DBMS Dəstəyinə miqrasiyaya kömək etsin. Bu genişləndirmə PDO sürücüsünün mövcud olduğu istənilən verilənlər bazası idarəetmə sistemini dəstəkləyə bilər. Yazı zamanı aşağıdakı sürücülər mövcuddur:
  • PDO_CUBRID (CUBRID)
  • PDO_DBLIB (FreeTDS / Microsoft SQL Server / Sybase)
  • PDO_FIREBIRD (Firebird/İnterbase 6)
  • PDO_IBM (IBM DB2)
  • PDO_INFORMIX (IBM Informix Dynamic Server)
  • PDO_MYSQL (MySQL 3.x/4.x/5.x)
  • PDO_OCI (Oracle Zəng İnterfeysi)
  • PDO_ODBC (ODBC v3 (IBM DB2, unixODBC və win32 ODBC))
  • PDO_PGSQL (PostgreSQL)
  • PDO_SQLITE (SQLite 3 və SQLite 2)
  • PDO_SQLSRV (Microsoft SQL Server)
  • PDO_4D (4D)
Bununla belə, onların hamısı serverinizdə deyil. Mövcud sürücülərin siyahısını belə görə bilərsiniz:
print_r(PDO::getAvailableDrivers()); Müxtəlif DBMS-lərə qoşulmaq üçün qoşulma üsulları bir qədər fərqli ola bilər. Aşağıda ən populyar olanlara qoşulma nümunələri verilmişdir. SQLite-dən fərqli olaraq ilk üçünün eyni sintaksisə malik olduğunu görəcəksiniz.
cəhd edin ( # MS SQL Server və PDO_DBLIB vasitəsilə Sybase $DBH = yeni PDO("mssql:host=$host;dbname=$dbname", $user, $pass); $DBH = yeni PDO("sybase:host=$host" ;dbname=$dbname", $user, $pass); # PDO_MYSQL vasitəsilə MySQL $DBH = yeni PDO("mysql:host=$host;dbname=$dbname", $user, $pass); # SQLite $DBH = yeni PDO("sqlite:my/database/path/database.db"); ) catch(PDOException $e) ( echo $e->getMessage(); )
Zəhmət olmasa try/catch blokuna diqqət yetirin - bu, həmişə bütün PDO əməliyyatlarınızı onun içinə yığmağa və istisna mexanizmindən istifadə etməyə dəyər (bu barədə daha sonra).

$DBH “verilənlər bazası idarəsi” deməkdir və məqalə boyu istifadə olunacaq.

Siz dəyişənini null olaraq yenidən təyin etməklə istənilən əlaqəni bağlaya bilərsiniz.
# əlaqəni bağlayır $DBH = null;
Müxtəlif DBMS-lərin fərqləndirici variantları və onlara qoşulma üsulları mövzusunda daha ətraflı məlumatı php.net saytında tapa bilərsiniz.

İstisnalar və PDO PDO xətalara istisnalar ata bilər, buna görə də hər şey cəhd/tutmaq blokunda olmalıdır. Bağlantı yaratdıqdan dərhal sonra PDO üç səhv rejimindən hər hansı birinə daxil edilə bilər:
$DBH->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT); $DBH->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING); $DBH->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
Ancaq qeyd etmək lazımdır ki, qoşulmağa çalışarkən xəta həmişə istisna yaradır. PDO::ERRMODE_SILENT Bu standart rejimdir. Siz mysql və mysqli uzantılarında səhvləri tutmaq üçün təxminən eyni şeydən istifadə edəcəksiniz. Aşağıdakı iki rejim QURU proqramlaşdırma üçün daha uyğundur PDO::ERRMODE_WARNING Bu rejim standart Xəbərdarlığa səbəb olacaq və skriptin icrasını davam etdirməsinə imkan verəcək. Sazlama üçün əlverişlidir.PDO::ERRMODE_EXCEPTION Əksər hallarda skriptin icrasına nəzarətin bu növünə üstünlük verilir. Səhvləri ağılla idarə etməyə və həssas məlumatları gizlətməyə imkan verən bir istisna yaradır. Məsələn, burada:
# verilənlər bazasına qoşulmağa cəhd edin ( $DBH = new PDO("mysql:host=$host;dbname=$dbname", $user, $pass); $DBH->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION) ; # Lənət olsun! SEÇİN əvəzinə DELECT yazdım! $DBH->prepare("İnsanlardan adı SİL")->execute(); ) catch(PDOException $e) ( echo "Hyuston, problemimiz var."; file_put_contents ("PDOErrors .txt", $e->getMessage(), FILE_APPEND); )
SQL ifadəsində istisna yaradacaq sintaksis xətası var. Biz xətanın təfərrüatlarını log faylında qeyd edə və istifadəçiyə insan dilində nəyinsə baş verdiyinə işarə edə bilərik.Daxil et və Yenilə Yeni məlumatların daxil edilməsi və mövcud verilənlərin yenilənməsi ən çox yayılmış verilənlər bazası əməliyyatlarından biridir. PDO vəziyyətində bu proses adətən iki mərhələdən ibarətdir. (Növbəti bölmə həm YENİLƏMƏ, həm də INSERT haqqındadır)


Yeni məlumatların daxil edilməsinin mənasız bir nümunəsi:
# STH "İfadə Dəstəyi" deməkdir $STH = $DBH->hazırlamaq("INSERT INTO folks (first_name) values ​​("Cathy")"); $STH->execute();
Əslində, eyni şeyi bir exec() metodu ilə edə bilərsiniz, lakin iki addımlı metod hazırlanmış ifadələrin bütün üstünlüklərini verir. Onlar SQL inyeksiyalarından qorunmağa kömək edir, ona görə də onlardan hətta birdəfəlik sorğu üçün istifadə etmək məntiqlidir.Hazırlanmış bəyanatlar Hazırlanmış ifadələrdən istifadə SQL inyeksiyalarına qarşı müdafiəni gücləndirir.
Hazırlanmış bəyanat serverə yalnız müxtəlif məlumat dəstləri göndərməklə dəfələrlə yerinə yetirilə bilən əvvəlcədən tərtib edilmiş SQL ifadəsidir. Əlavə üstünlük ondan ibarətdir ki, yer tutucularda istifadə olunan məlumatlar vasitəsilə SQL inyeksiyasını həyata keçirmək mümkün deyil.

Aşağıda hazırlanmış bəyanatların üç nümunəsi verilmişdir.
# yer tutucusuz - SQL inyeksiyalarının qapısı açıqdır! $STH = $DBH->prepare("INSERT INTO folks (ad,adr,şəhər) dəyərlərini ($name, $addr, $city)"); # adsız yer tutucular $STH = $DBH->prepare("INSERT INTO folks (ad, adr, city) dəyərləri (?, ?, ?)"); # adlı yer tutucular $STH = $DBH->prepare("INSERT INTO folks (ad, adr, city) dəyərləri (:name, :addr, :city)");
Birinci nümunə burada yalnız müqayisə üçün verilmişdir və bundan qaçınmaq lazımdır. Adsız və adlandırılmış yer tutucular arasındakı fərq məlumatları hazırlanmış ifadələrə necə ötürdüyünüzdür.

Adsız yertutanlar # hər bir yertutana dəyişənlər təyin edir, indeksləri 1-dən 3-ə qədər $STH->bindParam(1, $name); $STH->bindParam(2, $addr); $STH->bindParam(3, $şəhər); # bir sətir daxil edin $name = "Daniel" $addr = "1 Pis Yol"; $city = "Arlington Heights"; $STH->execute(); # fərqli verilənlərlə başqa sətir daxil edin $name = "Steve" $addr = "5 Dairəvi Sürücü"; $city = "Şaumburq"; $STH->execute();
Burada iki addım var. Birincisində biz dəyişənləri bütün yer tutuculara təyin edirik (sətir 2-4). Sonra bu dəyişənlərə qiymətlər təyin edirik və sorğunu yerinə yetiririk. Yeni məlumat dəstini göndərmək üçün sadəcə dəyişən dəyərləri dəyişdirin və sorğunu yenidən işə salın.

Əgər SQL ifadəniz çoxlu parametrlərə malikdirsə, onda hər birinə dəyişən təyin etmək çox əlverişsizdir. Belə hallarda siz məlumatları massivdə saxlaya və ötürə bilərsiniz:
# daxil edəcəyimiz verilənlər toplusu $data = array("Cathy", "9 Dark and Twisty Road", "Cardiff"); $STH = $DBH->prepare("INSERT INTO folks (ad, ünvan, şəhər) dəyərləri (?, ?, ?)"); $STH->icra ($data);
$data birinci yer tutanın yerinə, $data ikincinin yerinə və s. daxil ediləcək. Ancaq diqqətli olun: indeksləriniz qarışıqdırsa, bu işləməyəcək.

Nominal yer tutucular # birinci arqument yertutucunun adıdır # adətən iki nöqtə ilə başlayır # baxmayaraq ki, onlarsız işləyir $STH->bindParam(":name", $name);
Burada siz də massiv ötürə bilərsiniz, lakin o, assosiativ olmalıdır. Düymələr, təxmin etdiyiniz kimi, yer tutanların adları olmalıdır.
# daxil etdiyimiz data $data = array("name" => "Cathy", "addr" => "9 Dark and Twisty", "city" => "Cardiff"); $STH = $DBH->prepare("INSERT INTO folks (ad, adr, city) dəyərləri (:name, :addr, :city)"); $STH->icra ($data);
Adlandırılmış yer tutucuların istifadəsinin rahatlıqlarından biri, əgər əmlak adları parametr adlarına uyğun gələrsə, obyektləri birbaşa verilənlər bazasına daxil etmək imkanıdır. Məsələn, bu kimi məlumatları daxil edə bilərsiniz:
# sadə obyekt sinfi şəxs üçün sinif ( public $name; public $addr; public $city; funksiya __construct($n,$a,$c) ( $this->name = $n; $this->addr = $ a ; $this->city = $c; ) # s on... ) $cathy = new person("Cathy","9 Dark and Twisty","Cardiff"); # və burada maraqlı hissə var $STH = $DBH->prepare("INSERT INTO folks (ad, adr, city) dəyərləri (:name, :addr, :city)"); $STH->execute((massiv)$cathy);
Execute() zamanı obyektin massiləyə çevrilməsi xassələrin massiv açarları kimi qəbul edilməsinə səbəb olur.

Məlumat ->fetch() metodundan istifadə etməklə əldə edilə bilər. Zəng etməzdən əvvəl onları hansı formada tələb etdiyinizi açıq şəkildə göstərməyiniz məsləhətdir. Bir neçə variant var:
  • PDO::FETCH_ASSOC: açar kimi sütun adları olan massivi qaytarır
  • PDO::FETCH_BOTH (standart): həm sütun adları, həm də sütun nömrələri ilə indeksləşdirilmiş massivi qaytarır
  • PDO::FETCH_BOUND: ->bindColumn() metodu ilə müəyyən edilmiş uyğun dəyişənlərə sütun dəyərləri təyin edir.
  • PDO::FETCH_CLASS: Göstərilən sinfin müvafiq xassələrinə sütun dəyərləri təyin edir. Bəzi sütun üçün heç bir xüsusiyyət yoxdursa, o yaradılacaq
  • PDO::FETCH_INTO: müəyyən edilmiş sinfin mövcud nümunəsini yeniləyir
  • PDO::FETCH_LAZY: PDO::FETCH_BOTH və PDO::FETCH_OBJ-ni birləşdirir
  • PDO::FETCH_NUM: sütun nömrələri kimi düymələri olan massivi qaytarır
  • PDO::FETCH_OBJ: sütun adlarına uyğun xassələri olan anonim obyekti qaytarır
Praktikada sizə adətən üç lazımdır: FETCH_ASSOC, FETCH_CLASS və FETCH_OBJ. Məlumat formatını təyin etmək üçün aşağıdakı sintaksisdən istifadə edin:
$STH->setFetchMode(PDO::FETCH_ASSOC);
Siz həmçinin ->fetch() metodunu çağırarkən onu birbaşa təyin edə bilərsiniz.FETCH_ASSOC Bu format sütun adları ilə indekslər kimi assosiativ massiv yaradır. Bu, mysql/mysqli uzantılarından istifadə edənlərə tanış olmalıdır.
# bu, yer tutucuları olmayan adi sorğu olduğundan, # siz dərhal query() metodundan istifadə edə bilərsiniz $STH = $DBH->query("Ad, ünvan, insanlardan şəhər seçin"); # gətirmə rejimini təyin edin $STH->setFetchMode(PDO::FETCH_ASSOC); while($row = $STH->fetch()) ( echo $row["name"] . "\n"; echo $row["addr"] . "\n"; echo $row["city"] . "\n";)
while() döngəsi bütün sorğu nəticəsini təkrarlayacaq.FETCH_OBJ Bu tip məlumatların alınması hər bir sıra üçün std sinifinin nümunəsini yaradır.
# sorğu yaradın $STH = $DBH->query("Ad, ünvan, insanlardan şəhər seçin"); # gətirmə rejimini seçin $STH->setFetchMode(PDO::FETCH_OBJ); # nəticəni çap edərkən ($row = $STH->fetch()) ( echo $row->name . "\n"; echo $row->addr . "\n"; echo $row->city . " \ n"; ) FETCH_CLASS fetch_class istifadə edərkən, verilənlər göstərilən sinfin nümunələrinə yazılır. Bu halda, dəyərlər konstruktoru çağırmadan əvvəl obyektin xassələrinə təyin edilir. Sütun adlarına uyğun adları olan xassələr mövcud deyilsə, onlar avtomatik olaraq yaradılacaq (ictimai əhatə ilə).

Əgər məlumatlarınız verilənlər bazasından alındıqdan dərhal sonra məcburi emal tələb edirsə, o, sinif konstruktorunda həyata keçirilə bilər.

Məsələn, bir insanın yaşayış ünvanının bir hissəsini gizlətmək lazım olduğu bir vəziyyəti götürək.
sinif sirri_şəxsi ( ictimai $adı; ictimai $addr; ictimai $şəhər; ictimai $other_data; funksiya __construct($digər = "") ( $this->addr = preg_replace("//", "x", $this-> adr); $this->other_data = $digər; ) )
Obyekt yaratarkən bütün kiçik latın hərfləri x ilə əvəz olunmalıdır. yoxlayaq:
$STH = $DBH->query("Ad, ünvan, insanlardan şəhər seçin"); $STH->setFetchMode(PDO::FETCH_CLASS, "gizli_şəxs"); while($obj = $STH->gəlmə()) ( echo $obj->addr; )
Əgər verilənlər bazasındakı ünvan '5 Rosebud' kimi görünürsə, o zaman çıxış '5 Rxxxxxx' olacaq.

Əlbəttə, bəzən siz dəyər təyin etməzdən ƏVVƏL konstruktorun çağırılmasını istəyəcəksiniz. PDO da buna imkan verir.
$STH->setFetchMode(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, "gizli_şəxs");
İndi siz əvvəlki nümunəni əlavə seçimlə (PDO::FETCH_PROPS_LATE) tamamladınız, ünvan dəyişdirilməyəcək, çünki dəyərlər yazıldıqdan sonra heç nə baş vermir.

Nəhayət, lazım gələrsə, obyekti yaratarkən arqumentləri birbaşa konstruktora ötürə bilərsiniz:
$STH->setFetchMode(PDO::FETCH_CLASS, "gizli_şəxs", massiv("material"));
Siz hətta hər bir obyektə müxtəlif arqumentlər ötürə bilərsiniz:
$i = 0; while($rowObj = $STH->gəlmək(PDO::FETCH_CLASS, "gizli_şəxs", massiv($i))) ( // nəsə edin $i++; )

Digər Faydalı Texnikalar Bu məqalə PDO ilə işləməyin bütün aspektlərini əhatə edə bilməsə də (və buna cəhd etməsə də) (bu, böyük moduldur!), aşağıdakı bir neçə xüsusiyyəti qeyd etmədən nəzərdən qaçırmaq olmaz.
$DBH->lastInsertId();
->lastInsertId() metodu son daxil edilmiş qeydin id-sini qaytarır. Qeyd etmək lazımdır ki, o, həmişə ifadəli ($STH) obyektdə deyil, verilənlər bazası obyektində (bu məqalədə $DBH adlanır) çağırılır.
$DBH->exec("1-ci YERDƏN SİLİN"); $DBH->exec("SET saat qurşağı = "-8:00"");
->exec() metodu onların təsir etdiyi qeydlərin sayından başqa heç bir məlumatı qaytarmayan əməliyyatlar üçün istifadə olunur.
$safe = $DBH->quote($təhlükəsiz);
->quote() metodu sitatları sətir məlumatlarına yerləşdirir ki, onlardan sorğularda istifadə etmək təhlükəsiz olsun. Hazırlanmış ifadələrdən istifadə etməsəniz faydalıdır.
$sətirlərdən_təsirlənən = $STH->rowCount();
->rowCount() metodu əməliyyatda iştirak edən qeydlərin sayını qaytarır. Təəssüf ki, bu funksiya PHP 5.1.6-a qədər SELECT sorğuları ilə işləmirdi. PHP versiyasını yeniləmək mümkün deyilsə, qeydlərin sayını bu şəkildə əldə etmək olar:
$sql = "İnsanlardan COUNT(*) SEÇİN"; if ($STH = $DBH->query($sql)) ( # qeydlərin sayını yoxlayın if ($STH->fetchColumn() > 0) ( # data tapıldığı üçün burada tam seçim edin! ) else ( # sorğunu qane edən heç bir məlumatın tapılmadığı mesajını çap edin) ) Nəticə Ümid edirəm ki, bu material bəziləriniz üçün mysql və mysqli uzantılarından köçməyə kömək edəcək.