PDO ilə necə işləmək olar? Tam bələdçi. Php teqi SQL sorğusu üçün PDO bağlantısı Pdo ifadəsini necə düzgün konfiqurasiya etmək olar

  • 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 çox şey var rahat yol- PHP məlumat obyektləri. 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 Data Objects təklif edən təbəqədir universal üsulçoxlu verilənlər bazası ilə işləmək."

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ə daha güclü və çevik PDO-ya köçməkdə kömək etmək üçün mysql və mysqli istifadə edən insanlar üçün yazılmışdır.

DBMS dəstəyi

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)
Lakin, 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());

Əlaqə

Müxtəlif DBMS-lərə 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 = new 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 səhvlərə istisnalar ata bilər, ona 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 bir səhv həmişə bir istisna atacaq.

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. Növbəti 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əyə 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! "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 edin və Yeniləyin

Yeni məlumatların daxil edilməsi və mövcud məlumatların yenilənməsi ən çox yayılmış verilənlər bazası əməliyyatlarındandır. 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ə fayda yer tutucularda istifadə olunan məlumatlar vasitəsilə SQL inyeksiyasının həyata keçirilməsinin mümkünsüzlüyüdür.

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

# 1-dən 3-ə kimi indekslərlə hər bir yertutana dəyişənlər təyin edin $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.

Adlandırılmış yer tutucular

# birinci arqument yer tutanın 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əlumatların seçilməsi



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 (defolt): həm sütun adları, həm də onların seriya nömrələri şəklində indeksləri olan 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 yaradır assosiativ massiv indekslər kimi sütun adları ilə. 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 əldə edilməsi 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-> addr); $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 əvvəlki nümunəni tamamladınız əlavə seçim(PDO::FETCH_PROPS_LATE), ünvan dəyişdirilməyəcək, çünki dəyərlər yazdı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ı Metodlar

Bu məqalə PDO ilə işləməyin bütün aspektlərini əhatə edə bilməsə də (və cəhd etməsə də) (bu, böyük moduldur!), Aşağıdakı bir neçə xüsusiyyəti qeyd etmədən qeyd etmək 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ığı bir mesaj çap edin) )

Nəticə

Ümid edirəm ki, bu material sizlərdən bəzilərinə mysql və mysqli uzantılarından köçməyə kömək edəcək.

meta etiket açar sözlər nümunəsi (4)

Hədəf

Gördüyüm kimi, bu işdə məqsədiniz ikidir:

  • hər bir verilənlər bazası üçün tək/təkrar istifadə edilə bilən əlaqə yaratmaq və saxlamaq
  • əlaqənin düzgün konfiqurasiya edildiyinə əmin olun

Həll

$provider = function() ( $instance = new PDO("mysql:......;charset=utf8", "username", "password"); $instance->setAttribute(PDO::ATTR_ERRMODE, PDO: :ERRMODE_EXCEPTION $instance->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); $fabrika = yeni StructureFactory($provayder);

Sonra başqa bir faylda və ya aşağıda eyni faylda:

$bir şey = $fabrika->yarat("Nəsə"); $foobar = $factory->create("Foobar");

Zavodun özü belə görünməlidir:

Class StructureFactory ( qorunan $provider = null; qorunan $bağlantı = null; ictimai funksiya __construct(cağrılan $provider) ( $this->provider = $provider; ) ictimai funksiya yaratmaq($name) ( əgər ($this->bağlantı =) == null) ( $this->bağlantı = call_user_func($this->provider); ) yeni $name qaytarın($this->bağlantı))

Beləliklə, əlaqənin yalnız lazım olduqda yaradılmasını təmin edən mərkəzləşdirilmiş bir quruluşa sahib ola bilərsiniz. Bu da prosesi asanlaşdıracaqdı vahid sınağı və xidmət.

Bu halda təchizatçı yükləmə mərhələsində haradasa tapılacaq. Bu yanaşma həmçinin DB-yə qoşulmaq üçün istifadə etdiyiniz konfiqurasiyanı təyin edə biləcəyiniz aydın bir yer verəcəkdir.

Nəzərə alın ki, bu son dərəcə sadələşdirilmiş nümunə. Siz həmçinin aşağıdakı iki videoya baxmaq istəyə bilərsiniz:

Bundan əlavə, PDO-dan istifadə haqqında düzgün təlimatı oxumağı çox tövsiyə edirəm (onlaynda pis bir dərslik qeydi var).

Zaman zaman verilənlər bazasına qoşulma ilə bağlı suallar görürəm.
Cavabların çoxu bunu necə etdiyim deyil və ya sadəcə düzgün cavab verə bilmirəm. Hər halda; Bu barədə heç düşünməmişəm, çünki bunu etdiyim üsul mənim üçün işləyir.

Amma burada bir dəli fikir var; Bəlkə də bütün bunları səhv edirəm və əgər belədirsə; Mən, həqiqətən, məlumat bazasına necə düzgün qoşulmağı bilmək istərdim MySQL məlumatları ilə PHP istifadə edərək və PDO və onu əlçatan etmək.

Mən bunu necə edirəm:

Birincisi, bura mənimdir fayl strukturu (kəsilmiş) :

Public_html/ * index.php * initialize/ -- load.initialize.php -- configure.php -- sessions.php

index.php
Ən yuxarıda tələb edirəm ("initialize/load.initialize.php"); ,

load.initialize.php

# saytın konfiqurasiyası tələb olunur("configure.php"); # verilənlər bazasına qoşulmaq tələb olunur ("root/somewhere/connect.php"); // daha yaxşı təhlükəsizlik üçün bu fayl public_html xaricində yerləşdirilib. # foreach sinifləri daxildir (glob("assets/classes/*.class.php") as $class_filename)( include($class_filename); ) # foreach funksiyaları daxildir (glob("assets/functions/*.func.php") kimi $func_filename)( include($func_filename); ) # idarə seansları tələb edir("sessions.php");

Dərsləri daxil etməyin daha yaxşı və ya daha düzgün yolu olduğunu bilirəm, amma bunun nə olduğunu xatırlamıram. Hələ buna baxmağa vaxtım olmadı, amma məncə, bu, avtomatik yükləmə ilə bağlı bir şey idi. belə bir şey...

configure.php
Burada mən, əsasən, bəzilərini üstün tuturam php.ini-xassələr və sayt üçün bəzi digər qlobal parametrlər edin

connect.php
Siniflə əlaqəni elə qurdum ki, digər siniflər də edə bilsin genişləndirmək bu...

Sinif connect_pdo ( qorunan $dbh; ictimai funksiya __construct() ( cəhd edin ( $db_host = " "; // hostname $db_name = " "; // verilənlər bazası adı $db_user = " "; // istifadəçi adı $user_pw = " "; // parol $con = new PDO("mysql:host=".$db_host."; dbname=".$db_name, $db_user, $user_pw); $con->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $con->exec("SET CHARACTER SET utf8"); // bütün sql sorğularını UTF-8 kimi qaytarın) catch (PDOException $err) ( "əgər əlaqə uğursuz olarsa, zərərsiz xəta mesajı"; $err->getMessage() .
"; file_put_contents("PDOErrors.txt",$err, FILE_APPEND); // public_html die(); // əlaqəni dayandırmaq ) xaricində xəta jurnalına bəzi təfərrüatları yazın ) ictimai funksiya dbh() ($this->dbh qaytarın ; ) ) # daha asan daxil olmaq üçün verilənlər bazası işləyicisini var-a qoyun $con = new connect_pdo();

Bu yaxınlarda OOP öyrənməyə başladığım və mysql əvəzinə PDO istifadə etdiyim üçün kütləvi təkmilləşdirmə üçün yer olduğuna həqiqətən inanıram.
Beləliklə, mən yeni başlayanlar üçün bir neçə dərslik izlədim və müxtəlif şeyləri sınadım...

sessions.php
Normal seansları idarə etməklə yanaşı, sessiyada bəzi dərsləri də bu kimi işə salıram:

Əgər (!isset($_SESSION["sqlQuery"]))( session_start(); $_SESSION["sqlQuery"] = yeni sqlQuery(); )

Beləliklə, bu sinif hər yerdə mövcuddur. Bu çox yaxşı təcrübə olmaya bilər(?)...
Hər halda, bu yanaşma mənə hər yerdə bunu etməyə imkan verir:

Echo $_SESSION["sqlQuery"]->getAreaName("county",9); // çıxışlar: Aust-Agder (verilənlər bazasında həmin id ilə ilçe adı)

Mənim içimdə sinif mənimkini genişləndirən sqlQuery Sinif connect_pdo , mənim verilənlər bazamdakı sorğunu idarə edən getAreaName ictimai funksiyam var.
Məncə, olduqca səliqəli.

Cazibədar kimi işləyir
Beləliklə, mən bunu əsasən belə edirəm.
Bundan əlavə, nə vaxt bir sinifdən verilənlər bazamdan bir şey götürməliyəm, sadəcə buna bənzər bir şey edirəm:

$id = 123; $sql = "Mənim Cədvəlimdən istədiyinizi SEÇİN HARADA id = :id"; $qry = $con->hazırlamaq($sql); $qry -> bindParam(":id", $id, PDO::PARAM_INT); $qry -> icra et(); $al = $qry->gətir (PDO::FETCH_ASSOC);

Çünki mən əlaqəni içindəki dəyişənə daxil edirəm connect_pdo.php, Mən sadəcə istinad edirəm və getməyə hazıram. Bu işləyir. Gözlənilən nəticəni alıram...

Lakin bundan asılı olmayaraq; Buradan ayrılıb getmədiyimi mənə bildirsəniz çox şad olaram. Bunun əvəzinə yaxşılaşdırmaq üçün dəyişdirə biləcəyim və ya etməli olduğum sahələri dəyişdirməliyəm və s...

Mən həqiqətən oxumaq istəyirəm ...

$dsn = "mysql:host=your_host_name;dbname=your_db_name_burada"; // host adını və verilənlər bazasının adını təyin edin $username = "siz"; // istifadəçi adını təyin edin $pwd="your_password"; // parol cəhdi ( $db = new PDO($dsn, $username, $pwd); ) catch (PDOException $e) ( $error_message = $e->getMessage(); echo "bu, xəta tapıldığı üçün göstərilir. "; exit(); )

Bu yaxınlarda mən özüm oxşar cavab/sualla gəldim. Kimsə maraqlanarsa, mən belə etdim:

args = func_get_args();

) ictimai funksiya __call($method, $args) ( if (empty($this->db)) ( $Ref = new \ReflectionClass("\PDO"); $this->db = $Ref->newInstanceArgs($) this->args); return call_user_func_array(array($this->db, $method), $args) );

Onu çağırmaq üçün yalnız bu xətti dəyişmək lazımdır:

$DB = yeni \Kitabxana\PDO(/* normal arqumentlər */);

Və istifadə etsəniz, bir işarə növü (\Library\PDO$DB).

Bu, həqiqətən də qəbul edilmiş cavaba və sizin cavabınıza bənzəyir; bununla belə, əhəmiyyətli üstünlüyə malikdir. Bu kodu nəzərdən keçirin:

$DB = yeni \Kitabxana\PDO(/* args */); $STH = $DB->hazırlamaq("İstifadəçi HARƏDƏ SEÇ * İstifadəçilərdən =?"); $STH->execute(massiv(25)); $İstifadəçi = $STH->gəlmə();

O, adi PDO kimi görünə bilsə də (o, yalnız \Kitabxana tərəfindən dəyişdirilib), siz hansı metoddan asılı olmayaraq, siz birinci metodu çağırana qədər obyekti işə salmır. Bu, onu daha optimallaşdırır, çünki PDO obyekti yaratmaq bir qədər bahalıdır. Bu şəffaf sinif və ya Ghost adlanan formadır. Siz $DB ilə adi PDO nümunəsi kimi davrana, onu ötürə, eyni əməliyyatları edə və s.

Mən qlobal olaraq DB bağlantınıza daxil olmaq üçün $_SESSION istifadə etməməyi təklif edərdim. Bir neçə şeydən birini edə bilərsiniz (yaxşıən yaxşısı üçün ən pisi

  • praktikant):
  • Funksiyalarınız və siniflərinizdə qlobal $dbh istifadə edərək $dbh-ə daxil olun

    Singleton reyestrindən istifadə edin və ona qlobal olaraq daxil olun, məsələn:

    $registry = MyRegistry::getInstance(); $dbh = $registr->getDbh();

    Verilənlər bazası işləyicisini ehtiyac duyduğu siniflərə əlavə edin:

Bununla belə, bu, bir az daha inkişaf etmiş və çərçivəsiz daha çox "kabel" tələb edir. Beləliklə, əgər asılılıq inyeksiyası sizin üçün çox mürəkkəbdirsə, qlobal dəyişənlər toplusu əvəzinə singleton reyestrindən istifadə edin.

Sizi daha məhsuldar edə biləcək ifadələr hazırlamaq və obyektlərlə işləmək üçün üsullar təqdim edir!

PDO-ya giriş

"PDO - PHP Məlumat Obyektləri müxtəlif verilənlər bazalarına daxil olmaq üçün vahid üsulları təmin edən verilənlər bazası giriş qatıdır."

O, xüsusi verilənlər bazası sintaksisinə etibar etmir və əksər hallarda sadəcə əlaqə sətirini dəyişdirməklə başqa verilənlər bazası növünə və platformasına asanlıqla keçməyə imkan verir.

Bu dərs onunla işləmə prosesinin təsviri deyil SQL. Genişləndirmələrdən istifadə edənlər üçün nəzərdə tutulub mysql və ya mysqli onlara daha güclü və portativ PDO-ya keçməyə kömək etmək.

Verilənlər bazası dəstəyi

Artırma PDO sürücüsü olan hər hansı bir verilənlər bazasını dəstəkləyir. Sürücülər hazırda aşağıdakı verilənlər bazası növləri üçün mövcuddur:

  • 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_4D (4D)

Sistemin işləməsi üçün yalnız həqiqətən lazım olan sürücüləri quraşdırmaq kifayətdir. Sistemdə mövcud olan sürücülərin siyahısını aşağıdakı kimi əldə edə bilərsiniz:

Print_r(PDO::getAvailableDrivers());

Əlaqə

Fərqli verilənlər bazaları bir az fərqli əlaqə üsullarına malik ola bilər. Bir neçə məşhur verilənlər bazasına qoşulma üsulları aşağıda göstərilmişdir. İlk üçünün bir-biri ilə eyni olduğunu və yalnız SQLite-ın xüsusi sintaksisi olduğunu görəcəksiniz.


cəhd edin ( # MS SQL Server və PDO_DBLIB ilə Sybase $DBH = yeni PDO("mssql:host=$host;dbname=$dbname, $user, $pass"); $DBH = yeni PDO("sybase:host=$host" ;dbname=$dbname, $user, $pass"); # PDO_MYSQL ilə MySQL $DBH = yeni PDO("mysql:host=$host;dbname=$dbname", $user, $pass); # SQLite $DBH = new PDO("sqlite:my/database/path/database.db" catch(PDOException $e) ( echo $e->getMessage(); )

Bloka diqqət yetirin cəhd/tutmaq- siz həmişə PDO əməliyyatlarını bloka yığmalısınız cəhd/tutmaq və istisna mexanizmindən istifadə edin. Tipik olaraq yalnız bir əlaqə qurulur, nümunəmiz sintaksisi göstərmək üçün çoxlu əlaqələri göstərir. $DBH verilənlər bazası dəstəyini ehtiva edir və bütün təlimatımızda istifadə olunacaq.

Dəstəyi təyin etməklə istənilən əlaqəni bağlaya bilərsiniz null.

# Bağlantını bağlayın $DBH = null;

Siz PHP.net-dəki sənədlərdən müxtəlif verilənlər bazaları üçün xüsusi seçimlər və əlaqə sətirləri haqqında daha çox öyrənə bilərsiniz.

İstisnalar və PDO

PDO səhvləri idarə etmək üçün istisnalardan istifadə edə bilər. Bu o deməkdir ki, bütün PDO əməliyyatları bloka daxil edilməlidir cəhd/tutmaq. PDO üç səviyyəli səhv ata bilər, səhvə nəzarət səviyyəsi verilənlər bazası deskriptoru üçün səhv nəzarət rejimi atributunu təyin etməklə seçilir:

$DBH->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT); $DBH->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING); $DBH->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

Nəzarət səviyyəsindən asılı olmayaraq, əlaqə xətası həmişə bir istisna yaradır və buna görə də həmişə bloka daxil edilməlidir. cəhd/tutmaq.

PDO::ERRMODE_SILENT

Səhv nəzarət səviyyəsi standart olaraq təyin edilir. Bu səviyyədə səhvlər uzantılarda olduğu kimi eyni prinsipə uyğun olaraq yaradılır mysql və ya mysqli. Səhv nəzarətinin digər iki səviyyəsi DRY (Özünüzü Təkrar Etməyin) proqramlaşdırma tərzi üçün daha uyğundur.

PDO::ERRMODE_WARNING

Səhv nəzarətinin bu səviyyəsində standart PHP xəbərdarlıqları yaradılır və proqram icrasına davam edə bilər. Bu səviyyə ayıklama üçün əlverişlidir.

PDO::ERRMODE_EXCEPTION

Səhv nəzarətinin bu səviyyəsi əksər hallarda istifadə edilməlidir. İstisnalar səhvləri diqqətlə idarə etmək və kiməsə sisteminizi sındırmağa kömək edə biləcək məlumatları gizlətmək üçün yaradılır. Aşağıda istisnaların faydalarını nümayiş etdirən bir nümunə verilmişdir:

# 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) ; # SELECT əvəzinə DELECT yazın. " , $e->getMessage(), FILE_APPEND);

Burada SELECT ifadəsində qəsdən səhv var. Bu, bir istisna yaradacaq. İstisna log faylına xətanın təsvirini göndərəcək və istifadəçiyə mesaj göstərəcək.

Məlumatların daxil edilməsi və yenilənməsi

Yeni verilənlərin daxil edilməsi və ya mövcud verilənlərin yenilənməsi ən çox istifadə olunan verilənlər bazası əməliyyatlarından biridir. PDO istifadə edərkən iki mərhələyə parçalanır. Bu fəsildə təsvir edilən hər şey hər iki əməliyyata aiddir. YENİLƏNİBINSERT.


Ən çox istifadə edilən məlumat daxiletmə növünə bir nümunə:

# STH "dövlət sapıdır" $STH = $DBH->prepare("INSERT INTO folks (first_name) values ​​("Cathy")"); $STH->execute();

Əlbəttə ki, bu əməliyyatı metoddan istifadə edərək həyata keçirə bilərsiniz icra(), və zənglərin sayı bir az olacaq. Ancaq hazırlanmış ifadələrin faydalarını əldə etmək üçün daha uzun bir üsuldan istifadə etmək daha yaxşıdır. Onları yalnız bir dəfə istifadə etmək niyyətində olsanız belə, hazırlanmış ifadələr sisteminizi hücumlardan qorumağa kömək edəcək.

Hazırlanmış ifadələr

Hazırlanmış ifadələr yalnız verilənləri serverə göndərməklə dəfələrlə yerinə yetirilə bilən əvvəlcədən tərtib edilmiş SQL ifadələridir. Onların əlavə üstünlüyü var ki, şablonu avtomatik olaraq SQL kodu əlavələri vasitəsilə hücumlardan qorunma formasında məlumatlarla doldursun.

Şablonları SQL kodunuza daxil etməklə hazırlanmış ifadələrdən istifadə edə bilərsiniz. Aşağıda 3 nümunə verilmişdir: biri şablonsuz, biri adsız şablonlarla, biri isə adlandırılmış şablonlarla.

# şablon yoxdur - SQL inyeksiya hücumlarına açıqdır! $STH = $DBH->("INSERT INTO folks (ad, ünvan, şəhər) dəyərləri ($name, $addr, $city)"); # adsız nümunələr $STH = $DBH->("INSERT INTO folks (ad, adr, city) dəyərləri (?, ?, ?); # adlı nümunələr $STH = $DBH->("INSERT INTO folks (ad) , addr , şəhər) dəyəri (:ad, :addr, :şəhər)");

Birinci üsuldan istifadə etməkdən çəkinməlisiniz. Adlandırılmış və ya adsız nümunələrin seçimi bu ifadələr üçün məlumatları necə təyin etdiyinizə təsir edir.

Adsız şablonlar

# hər şablona 1-dən 3-ə qədər indeksləşdirilmiş dəyişənlər təyin edin $STH->bindParam(1, $name); $STH->bindParam(2, $addr); $STH->bindParam(3, $şəhər); # Bir sətir daxil edin $name = "Dima" $addr = "Lizyukova küç."; $city = "Moskva"; $STH->execute(); # Başqa sətir daxil edin $name = "Senya" $addr = "Kommunist çıxılmaz nöqtə"; $city = "Piter"; $STH->execute();

Əməliyyat iki mərhələdə baş verir. Birinci mərhələdə şablonlara dəyişənlər təyin edilir. Sonra dəyişənlərə qiymətlər təyin edilir və ifadə yerinə yetirilir. Növbəti məlumat parçasını göndərmək üçün dəyişənlərin dəyərlərini dəyişməli və ifadəni yenidən işə salmalısınız.

Çox parametrli ifadələr üçün bir az çətin görünür? Əlbəttə. Bununla belə, məlumatlarınız massivdə saxlanılırsa, onda hər şey çox qısa olacaq:

# Daxil ediləcək verilənlər $data = massiv("Monya", "Unutma prospekti", "Zakutaysk"); $STH = $DBH->("INSERT INTO folks (ad, ünvan, şəhər) dəyərləri (?, ?, ?)"); $STH->icra ($data);

Massivdəki məlumatlar göründükləri ardıcıllıqla şablonlara əvəz olunur. $data birinci şablona, ​​$data ikinci şablona gedir və s. Lakin, əgər massiv fərqli ardıcıllıqla indeksləşdirilibsə, onda belə bir əməliyyat düzgün yerinə yetirilməyəcək. Nümunələrin sırasının massivdəki məlumatların sırasına uyğun olmasını təmin etməlisiniz.

Adlandırılmış Şablonlar

Budur, adlandırılmış şablondan istifadə nümunəsi:

# Funksiya üçün ilk arqument adlandırılmış şablonun adıdır # Adlandırılmış şablon həmişə iki nöqtə ilə başlayır $STH->bindParam(":name", $name);

Siz qısa yollardan istifadə edə bilərsiniz, lakin onlar əlaqəli massivlərlə işləyir. Misal:

# Daxil ediləcək verilənlər $data = array("name" => "Michelle", "addr" => "Kuznechny Lane", "city" => "Cnjkbwf"); # Stenoqrafiya $STH = $DBH->("INSERT INTO folks (ad, adr, city) dəyəri (:name, :addr, :city)"); $STH->icra ($data);

Cədvəl açarlarınız iki nöqtə tələb etmir, lakin yenə də şablon adlarına uyğun olmalıdır. Bir sıra massivdən istifadə edirsinizsə, onu təkrarlaya və sadəcə zəng edə bilərsiniz icra etmək hər bir məlumat dəsti üçün.

Adlandırılmış şablonların başqa bir gözəl xüsusiyyəti, xassələr və sahə adları uyğunlaşdıqda obyektləri birbaşa verilənlər bazanıza daxil etmək imkanıdır. Misal:

# Sadə obyekt sinfi şəxs ( ictimai $name; ictimai $addr; ictimai $city; funksiya __construct($n,$a,$c) ( $this->name = $n; $this->addr = $a; $ this->city = $c; ) # etc. ... ) $cathy = new person("Katya","Lenin prospekti","Mozhaisk"); # İcra: $STH = $DBH->("INSERT INTO folks (ad, adr, city) dəyəri (:name, :addr, :city)"); $STH->execute((massiv)$cathy);

Obyektin növünün çevrilməsi massiv V icra etmək xassələrin massiv açarları kimi qəbul edilməsinə səbəb olur.

Məlumatların qəbulu


Məlumat əldə etmək üçün dövlət identifikatoru üsulundan istifadə olunur -> gətir (). Metod çağırmadan əvvəl gətir() verilənlər bazasından məlumatları necə əldə edəcəyinizi PDO-ya bildirməlisiniz. Aşağıdakı seçimləri seçə bilərsiniz:

  • PDO::FETCH_ASSOC: sütun adları ilə indeksləşdirilmiş massivi qaytarır
  • PDO::FETCH_BOTH (defolt): sütun adları və nömrələri ilə indeksləşdirilmiş massivi qaytarır
  • PDO::FETCH_BOUND: Metoddan istifadə edərək sütunlarınızın dəyərlərini dəyişənlər dəstinə təyin edir -> bindColumn()
  • PDO::FETCH_CLASS: müvafiq xüsusiyyət mövcud deyilsə, adlandırılmış sinifin xüsusiyyətlərinə sütun dəyərləri təyin edir;
  • PDO::FETCH_INTO: adlı sinfin mövcud nümunəsini yeniləyir
  • PDO::FETCH_LAZY: birləşmə PDO::FETCH_BOTH/PDO::FETCH_OBJ, istifadə olunduqca obyekt dəyişənlərinin adlarını yaradır
  • PDO::FETCH_NUM: sütun nömrələri ilə indeksləşdirilmiş massivi qaytarır
  • PDO::FETCH_OBJ: sütun adlarına uyğun xassə adları olan anonim obyekti qaytarır

Əslində, əsas vəziyyətlər üç variantdan istifadə etməklə həll olunur: FETCH_ASSOC, FETCH_CLASSFETCH_OBJ. Məlumat çıxarma metodunu təyin etmək üçün istifadə edin:

$STH->setFetchMode(PDO::FETCH_ASSOC);

Siz həmçinin məlumat axtarış metodunu birbaşa metod çağırışında təyin edə bilərsiniz -> gətir ().

FETCH_ASSOC

Bu tip məlumat axtarışı sütun adları ilə indeksləşdirilmiş assosiativ massiv yaradır. Bu uzantılardan istifadə edənlərə kifayət qədər yaxşı məlum olmalıdır mysql/mysqli. Nümunə məlumat nümunəsi:

$STH = $DBH->query("Ad, ünvan, insanlardan şəhər seçin"); # Məlumat axtarış 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" ;

Velosiped isə tamamlanana qədər nümunə nəticəni bir sıra təkrarlamağa davam edir.

FETCH_OBJ

Bu tip məlumat axtarışı ilə sinif obyekti yaradılır std alınan məlumatların hər bir sırası üçün:

$STH = $DBH->query("Ad, ünvan, insanlardan şəhər seçin"); # Məlumat əldə etmə rejimini təyin edin $STH->setFetchMode(PDO::FETCH_OBJ); # nəticəni göstərərkən ($row = $STH->fetch()) ( echo $row->name . "\n"; echo $row->addr . "\n"; echo $row->city . " \ n";)

FETCH_CLASS

Bu cür çıxarma ilə məlumatlar birbaşa seçdiyiniz sinifə yerləşdirilir. İstifadə edərkən FETCH_CLASS obyektinizin xassələri konstruktoru çağırmadan ƏVVƏL təyin edilir. Bu çox vacibdir. Sütun adına uyğun xüsusiyyət mövcud deyilsə, belə bir xüsusiyyət yaradılacaq (kimi ictimai) sizin üçün.

Bu o deməkdir ki, verilənlər bazasından alındıqdan sonra məlumatın transformasiyası lazımdırsa, o, yaradılan kimi obyektiniz tərəfindən avtomatik olaraq edilə bilər.

Məsələn, hər bir giriş üçün ünvanın qismən gizlədilməli olduğu bir vəziyyəti təsəvvür edin. Konstruktordakı əmlakı manipulyasiya etməklə tapşırığı yerinə yetirə bilərik:

Sinif gizli_şəxs ( ictimai $adı; ictimai $addr; ictimai $şəhər; ictimai $other_data; funksiya __construct($digər = "") ( $this->ünvan = preg_replace("//", "x", $this-> ünvan); $this->digər_məlumatlar = $digər;

Məlumat sinifə çıxarıldıqdan sonra ünvandakı bütün kiçik a-z simvolları x simvolu ilə əvəz olunacaq. İndi sinifdən istifadə edərək və məlumatları əldə edərək, transformasiya tamamilə şəffaf şəkildə baş verir:

$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 ünvan 'Leninsky Prospekt 5' idisə, siz 'Lxxxxxxxxxx xx-x 5' görəcəksiniz. Əlbəttə ki, konstruktorun məlumat təyin edilməzdən əvvəl çağırılmasını istədiyiniz vəziyyətlər var. PDO bunu həyata keçirmək üçün vasitələrə malikdir:

$STH->setFetchMode(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, "gizli_şəxs");

İndi, rejim dəsti ilə əvvəlki nümunəni təkrarladığınız zaman PDO::FETCH_PROPS_LATE konstruktor çağırıldıqdan və xassələr təyin olunduğundan ünvan gizlədilməyəcək.

Lazım gələrsə, məlumatı obyektə çıxararkən konstruktora arqumentlər ötürə bilərsiniz:

$STH->setFetchMode(PDO::FETCH_CLASS, "gizli_şəxs", massiv("material"));

Hər bir obyekt üçün konstruktora fərqli məlumat ötürmək lazımdırsa, metod daxilində məlumat axtarış rejimini təyin edə bilərsiniz. gətirmək:

$i = 0; while($rowObj = $STH->getch(PDO::FETCH_CLASS, "gizli_şəxs", massiv($i))) ( // $i++ işlərini yerinə yetirin )

Bəzi digər faydalı üsullar

PDO-nu qısa bir məqalədə tam təsvir etmək mümkün olmadığı üçün biz əsas əməliyyatları yerinə yetirmək üçün bir neçə faydalı üsul təqdim edəcəyik.

$DBH->lastInsertId();

Metod ->lastInsertId() həmişə verilənlər bazası tutacağı tərəfindən çağırılır (dövlət sapı deyil) və verilmiş əlaqə üçün sonuncu daxil edilmiş sıranın avtomatik artan id-nin dəyərini qaytarır.

$DBH->exec("1-ci YERDƏN SİLİN"); $DBH->exec("SET saat qurşağı = "-8:00"");

Metod ->exec() müxtəlif köməkçi əməliyyatlar üçün istifadə olunur.

$safe = $DBH->quote($təhlükəsiz);

Metod ->quote() sorğularda istifadə oluna bilməsi üçün kvotalar sətirləri. Hazırlanmış ifadələrin istifadə edilməməsi halında bu sizin ehtiyatınızdır.

$sətirlərdən_təsirlənən = $STH->rowCount();

Metod ->rowCount() dəyəri qaytarır tam ədəd, əməliyyat tərəfindən işlənən cərgələrin sayını göstərir. PDO-nun son versiyasında, səhv hesabatına (http://bugs.php.net/40822) görə, bu üsul ifadələrlə işləmir. SEÇİN. Probleminiz varsa və PHP-ni yeniləyə bilmirsinizsə, sətirlərin sayını aşağıdakı şəkildə əldə edə bilərsiniz:

$sql = "İnsanlardan COUNT(*) SEÇİN"; if ($STH = $DBH->query($sql)) ( # Satırların sayını yoxlayın if ($STH->fetchColumn() > 0) ( # Burada SEÇİM kodu olmalıdır) başqa ( echo "Var sorğuya uyğun sətir yoxdur." ; ) )

Ümid edirəm dərsi bəyəndiniz!

  • 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 Data Objects çoxlu 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ə daha güclü və çevik PDO-ya köçməkdə kömək etmək üçün mysql və mysqli istifadə edən insanlar üçün yazılmışdır.

DBMS dəstəyi

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)
Lakin, 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());

Əlaqə

Müxtəlif DBMS-lərə 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 = new 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 səhvlərə istisnalar ata bilər, ona 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 bir səhv həmişə bir istisna atacaq.

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. Növbəti 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əyə 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! "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 edin və Yeniləyin

Yeni məlumatların daxil edilməsi və mövcud məlumatların yenilənməsi ən çox yayılmış verilənlər bazası əməliyyatlarındandır. 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

# 1-dən 3-ə kimi indekslərlə hər bir yertutana dəyişənlər təyin edin $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.

Adlandırılmış yer tutucular

# birinci arqument yer tutanın 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əlumatların seçilməsi



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 (defolt): həm sütun adları, həm də onların seriya nömrələri şəklində indeksləri olan 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 indekslər kimi sütun adları ilə 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 əldə edilməsi 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-> addr); $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ı Metodlar

Bu məqalə PDO ilə işləməyin bütün aspektlərini əhatə edə bilməsə də (və cəhd etməsə də) (bu, böyük moduldur!), Aşağıdakı bir neçə xüsusiyyəti qeyd etmədən qeyd etmək 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ığı bir mesaj çap edin) )

Nəticə

Ümid edirəm ki, bu material sizlərdən bəzilərinə mysql və mysqli uzantılarından köçməyə kömək edəcək.

Verilənlər bazaları ilə işləmək üçün PDO - PHP Data Objects genişləndirilməsinin qurulması və istifadəsi

Test verilənlər bazası və cədvəlinin yaradılması

Əvvəlcə bu dərslik üçün verilənlər bazası yaradaq:

VERİLƏ BAZASI YARADIN günəş_sistemi; solar_system ÜZRƏ BÜTÜN İMTİYAZLARI VERİN.* "testpassword" İLƏ TƏYİD EDİLƏN "testuser"@"localhost"-a;

Giriş test istifadəçisi və parol test parolu olan istifadəçiyə solar_system verilənlər bazasına tam giriş hüququ verildi.

İndi bir cədvəl yaradaq və onu astronomik dəqiqliyi nəzərdə tutulmayan məlumatlar ilə dolduraq:

günəş_sistemindən istifadə edin; CƏDVƏL planetləri YARADIN (id TINYINT(1) İMZALANMAZ DEYİL NULL AUTO_INCREMENT, PRIMARY KEY(id), adı VARCHAR(10) NOT NULL, rəng VARCHAR(10) NOT NULL); INSERT INTO planets(ad, color) DƏYƏRLƏR("yer", "mavi"), ("mars", "qırmızı"), ("yupiter", "qəribə");

Əlaqənin təsviri

İndi verilənlər bazası yaradılmışdır, gəlin DSN () - verilənlər bazasına qoşulmaq üçün sətir kimi təqdim olunan məlumatı müəyyən edək. Təsvir sintaksisi istifadə olunan DBMS-dən asılı olaraq fərqlənir. Nümunədə MySQL/MariaDB ilə işləyirik, ona görə də göstəririk:

  • DBMS-nin yerləşdiyi host adı;
  • port (standart port 3306 istifadə edilərsə, isteğe bağlıdır);
  • verilənlər bazası adı;
  • kodlaşdırma (isteğe bağlı).

Bu vəziyyətdə DSN xətti belə görünür:

$dsn = "mysql:host=localhost;port=3306;dbname=solar_system;charset=utf8";

Əvvəlcə verilənlər bazası prefiksi müəyyən edilir. Nümunədə - mysql. Prefiks xəttin qalan hissəsindən iki nöqtə ilə ayrılır və hər bir sonrakı parametr nöqtəli vergüllə ayrılır.

PDO obyektinin yaradılması

İndi DSN sətri hazırdır, gəlin PDO obyekti yaradaq. Giriş konstruktoru aşağıdakı parametrləri qəbul edir:

  1. DSN sətri.
  2. Verilənlər bazasına girişi olan istifadəçinin adı.
  3. Bu istifadəçinin parolu.
  4. Əlavə parametrləri olan massiv (isteğe bağlı).
$seçimlər = [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC ]; $pdo = yeni PDO($dsn, "test istifadəçisi", "test parolu", $seçimlər);

Əlavə parametrlər SetAttribute metodu ilə obyekt yaradıldıqdan sonra da müəyyən edilə bilər:

$pdo->SetAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

Standart seçmə metodunun müəyyən edilməsi

PDO::DEFAULT_FETCH_MODE standart gətirmə metodunu təyin edən mühüm parametrdir. Göstərilən üsul sorğunun nəticəsini əldə edərkən istifadə olunur.

PDO::FETCH_BOTH

Defolt rejim. Seçmənin nəticəsi həm rəqəmlər (0-dan başlayaraq), həm də sütun adları ilə indekslənir:

$stmt = $pdo->query("Planetlərdən SEÇİN *"); $nəticələr = $stmt->gəlmə(PDO::FETCH_BOTH);

Planetlərin sınaq cədvəlinə qarşı bu rejimlə sorğu yerinə yetirdikdən sonra aşağıdakı nəticəni alırıq:

Massiv ( => 1 => 1 => torpaq => torpaq => mavi => mavi)

PDO::FETCH_ASSOC

Nəticə açarın sütun adı və dəyərin müvafiq sıra dəyəri olduğu assosiativ massivdə saxlanılır:

$stmt = $pdo->query("Planetlərdən SEÇİN *"); $nəticələr = $stmt->gəlmə(PDO::FETCH_ASSOC);

Nəticədə əldə edirik:

Massiv ( => 1 => torpaq => mavi)

PDO::FETCH_NUM

Bu rejimdən istifadə edərkən nəticə sütun nömrələri ilə indeksləşdirilmiş massiv kimi təqdim olunur (0-dan başlayaraq):

Massiv ( => 1 => torpaq => mavi)

PDO::FETCH_COLUMN

Bu seçim, nömrələnməsi 0-dan başlayan bir ölçülü massiv şəklində bir sahə üçün dəyərlərin siyahısını əldə etmək lazım olduqda faydalıdır. Məsələn:

$stmt = $pdo->query("Planetlərdən ad SEÇ");

Nəticədə əldə edirik:

Massiv ( => Earth => Mars => Yupiter)

PDO::FETCH_KEY_PAIR

Assosiativ massiv şəklində iki sahənin dəyərlərinin siyahısını əldə etmək lazımdırsa, bu seçimdən istifadə edirik. Massiv düymələri seçimin birinci sütunundakı məlumatlardır, massiv dəyərləri ikinci sütundakı məlumatlardır. Məsələn:

$stmt = $pdo->query("Planetlərdən ad, rəng SEÇİN"); $nəticə = $stmt->FetchAll(PDO::FETCH_KEY_PAIR);

Nəticədə əldə edirik:

Massiv ( => mavi => qırmızı => qəribə)

PDO::FETCH_OBJECT

PDO::FETCH_OBJECT istifadə edərkən, hər bir gətirilən sıra üçün anonim obyekt yaradılır. Onun ictimai xassələri nümunə sütunlarının adlarıdır və sorğu nəticələri onların dəyərləri kimi istifadə olunur:

$stmt = $pdo->query("Planetlərdən ad, rəng SEÇİN"); $nəticələr = $stmt->gəlmə(PDO::FETCH_OBJ);

Nəticədə əldə edirik:

StdClass Obyekt ( => torpaq => mavi)

PDO::FETCH_CLASS

Bu vəziyyətdə, əvvəlki kimi, sütun dəyərləri obyektin xüsusiyyətlərinə çevrilir. Bununla belə, obyekti yaratmaq üçün istifadə olunacaq mövcud sinfi göstərməlisiniz. Buna bir nümunə ilə baxaq. Əvvəlcə bir sinif yaradaq:

Class Planet ( şəxsi $name; özəl $rəng; ictimai funksiya setName($planet_name) ( $this->name = $planet_name; ) ictimai funksiya setColor($planet_color) ( $this->color = $planet_color; ) ictimai funksiya getName () ( $this->adı qaytarın; ) ictimai funksiya getColor() ( $this->rəngi qaytarın; ) )

Nəzərə alın ki, Planet sinfi özəl xüsusiyyətlərə malikdir və konstruktoru yoxdur. İndi sorğunu yerinə yetirək.

Əgər siz PDO::FETCH_CLASS ilə gətirmə metodundan istifadə edirsinizsə, məlumatı əldə etmək üçün sorğu göndərməzdən əvvəl setFetchMode metodundan istifadə etməlisiniz:

$stmt = $pdo->query("Planetlərdən ad, rəng SEÇİN"); $stmt->setFetchMode(PDO::FETCH_CLASS, "Planet");

setFetchMode metoduna keçdiyimiz ilk parametr PDO::FETCH_CLASS sabitidir. İkinci parametr obyektin yaradılması zamanı istifadə olunacaq sinfin adıdır. İndi edək:

$planet = $stmt->getir(); var_dump($planet);

Nəticədə Planet obyekti alırıq:

Planet obyekti ( => yer => mavi)

Sorğunun qaytardığı dəyərlər obyektin müvafiq xassələrinə, hətta özəl olanlara da təyin edilir.

Konstruktorun icrasından sonra xassələrin müəyyən edilməsi

Planet sinifinin açıq konstruktoru yoxdur, ona görə də xassələrin təyin edilməsində heç bir problem olmayacaq. Əgər sinifdə mülkiyyətin təyin edildiyi və ya dəyişdirildiyi konstruktor varsa, onlar üzərinə yazılacaq.

FETCH_PROPS_LATE sabitindən istifadə edərkən, konstruktor yerinə yetirildikdən sonra xassə dəyərləri təyin ediləcək:

Class Planet ( şəxsi $name; özəl $rəng; ictimai funksiya __construct($name = ay, $rəng = boz) ( $this->name = $name; $this->color = $color; ) ictimai funksiya setName($ planet_adı) ( $this->name = $planet_name; ) ictimai funksiya setColor($planet_color) ( $this->color = $planet_color; ) ictimai funksiya getName() ($this->ad; ) ictimai funksiya getColor() ($this->rəngi qaytarın;))

Planet sinfini giriş kimi iki arqument qəbul edən konstruktor əlavə edərək dəyişdirdik: ad və rəng. Bu sahələr üçün standart dəyərlər müvafiq olaraq ay və bozdur.

FETCH_PROPS_LATE istifadə etməsəniz, obyekt yaradılan zaman xassələr defolt dəyərlərin üzərinə yazılacaq. Gəlin yoxlayaq. Əvvəlcə sorğunu yerinə yetirək:

$stmt = $pdo->query("Ad SEÇİN, rəngi solar_sistemindən HERİ adı = "yer""); $stmt->setFetchMode(PDO::FETCH_CLASS, "Planet"); $planet = $stmt->getir(); var_dump($planet);

Nəticədə əldə edirik:

Object(Planet)#2 (2) ( ["ad":"Planet":private]=> string(4) "ay" ["color":"Planet":private]=> string(4) "boz" )

Gözlənildiyi kimi, verilənlər bazasından alınan dəyərlərin üzərinə yazılır. İndi FETCH_PROPS_LATE (oxşar sorğu) istifadə edərək problemin həllinə baxaq:

$stmt->setFetchMode(PDO::FETCH_CLASS|PDO::FETCH_PROPS_LATE, "Planet"); $planet = $stmt->getir(); var_dump($planet);

Nəticədə ehtiyacımız olanı alırıq:

Object(Planet)#4 (2) ( ["ad":"Planet":private]=> string(5) "yer" ["rəng":"Planet":private]=> string(4) "mavi" )

Sinif konstruktorunun standart dəyərləri yoxdursa, lakin onlar lazımdırsa, konstruktor parametrləri massiv şəklində üçüncü arqumentlə setFetchMode metodunu çağırarkən təyin olunur. Məsələn:

Class Planet ( şəxsi $name; özəl $rəng; ictimai funksiya __construct($name, $color) ( $this->ad = $name; $this->color = $color; ) [...] )

Konstruktor arqumentləri tələb olunur, buna görə də edək:

$stmt->setFetchMode(PDO::FETCH_CLASS|PDO::FETCH_PROPS_LATE, "Planet", ["ay", "boz"]);

Gələn parametrlər başlanğıc üçün lazım olan standart dəyərlər kimi də fəaliyyət göstərir. Gələcəkdə onlar verilənlər bazasındakı dəyərlərin üzərinə yazılacaqlar.

Çoxlu Obyektlərin Alınması

Bir müddət döngə daxilində gətirmə metodundan istifadə edərək bir neçə nəticə obyekt kimi götürülür:

while ($planet = $stmt->fetch()) ( // nəticələrin işlənməsi )

Və ya bütün nəticələri bir anda seçərək. İkinci halda, fetchAll metodundan istifadə olunur və zəng zamanı rejim müəyyən edilir:

$stmt->fetchAll(PDO::FETCH_CLASS|PDO_FETCH_PROPS_LATE, "Planet", ["ay", "boz"]);

PDO::FETCH_INTO

Bu seçim seçimini seçdiyiniz zaman PDO yeni obyekt yaratmır, əksinə mövcud obyektin xüsusiyyətlərini yeniləyir. Bununla belə, bu, yalnız ictimai xüsusiyyətlər üçün və ya obyektdə __set sehrli metodundan istifadə edərkən mümkündür.

Hazırlanmış və birbaşa sorğular

PDO-da sorğuları yerinə yetirməyin iki yolu var:

  • bir addımdan ibarət olan düz;
  • iki mərhələdən ibarət olan hazırlanır.

Birbaşa sorğular

Birbaşa sorğuları yerinə yetirmək üçün iki üsul var:

  • sorğu SELECT kimi dəyişiklik etməyən ifadələr üçün istifadə olunur. Fetch və ya fetchAll metodlarından istifadə etməklə sorğu nəticələrinin alındığı PDOStatemnt obyektini qaytarır;
  • exec INSERT, DELETE və ya UPDATE kimi ifadələr üçün istifadə olunur. Sorğu ilə işlənmiş sətirlərin sayını qaytarır.

Birbaşa operatorlar yalnız sorğuda heç bir dəyişən olmadıqda istifadə olunur və siz sorğunun təhlükəsiz və düzgün şəkildə qaçdığına əminsinizsə.

Hazırlanmış sorğular

PDO proqramın qorunması üçün faydalı olan hazırlanmış ifadələri dəstəkləyir: Hazırlama metodu lazımi qaçışları yerinə yetirir.

Bir nümunəyə baxaq. Planet obyektinin xüsusiyyətlərini Planetlər cədvəlinə daxil etmək istəyirsiniz. Əvvəlcə sorğunu hazırlayaq:

$stmt = $pdo->prepare("Planetlərə daxil edin (adı, rəngi) DƏYƏRLƏRİ(?, ?)");

Pseudo-dəyişənləri (yer tutucuları) olan SQL sorğusunu arqument kimi qəbul edən hazırlamaq metodundan istifadə edirik. Yalançı dəyişənlər iki növ ola bilər: adsız və adlandırılmış.

Adsız psevdo dəyişənlər

Adsız psevdodəyişənlər (mövqe yertutanları) ilə işarələnir? . Nəticədə sorğu yığcamdır, lakin dəyərlərin eyni ardıcıllıqla əvəz edilməsini tələb edir. Onlar icra üsulu ilə massiv kimi ötürülür:

$stmt->execute([$planet->ad, $planet->rəng]);

Pseudo Dəyişənlər adlı

Adlandırılmış yer tutuculardan istifadə edərkən, əvəzetmə üçün dəyərlərin ötürülmə sırası vacib deyil, lakin bu vəziyyətdə kod daha az yığcam olur. Məlumat icra metoduna assosiativ massiv şəklində ötürülür, burada hər bir açar psevdodəyişənin adına, massivin qiyməti isə sorğuda əvəz edilməli olan qiymətə uyğundur. Əvvəlki nümunəni təkrarlayaq:

$stmt = $pdo->prepare("INSERT INTO planets(name, color) VALUES(:name, :color)"); $stmt->execute(["ad" => $planet->ad, "rəng" => $planet->rəng]);

Hazırlama və icra üsulları həm dəyişiklik sorğularını yerinə yetirərkən, həm də gətirərkən istifadə olunur.

Lazım gələrsə, işlənmiş sətirlərin sayı haqqında məlumat rowCount metodu ilə təmin ediləcəkdir.

PDO səhv davranışına nəzarət

Səhv rejimi seçimi parametri PDO::ATTR_ERRMODE səhvlər zamanı PDO-nun necə davranacağını müəyyən etmək üçün istifadə olunur. Üç seçim mövcuddur: PDO::ERRMODE_SILENT , PDO::ERRMODE_EXCEPTION və PDO::ERRMODE_WARNING .

PDO::ERRMODE_SILENT

Defolt seçim. PDO, sadəcə olaraq, errorCode və errorInfo metodlarının əldə etməyə kömək edəcəyi xəta haqqında məlumatı qeyd edəcək.

PDO::ERRMODE_EXCEPTION

Bu, PDO-nun səhv məlumatına əlavə olaraq bir istisna (PDOException) atdığı seçimdir. İstisna skriptin icrasını dayandırır, bu da PDO əməliyyatlarından istifadə edərkən faydalıdır. Nümunə əməliyyatların təsvirində verilmişdir.

PDO::ERRMODE_WARNING

Bu halda PDO səhv məlumatını da qeyd edir. Skript axını kəsilmir, lakin xəbərdarlıqlar verilir.

bindValue və bindParam üsulları

Sorğuda dəyərləri əvəz etmək üçün bindValue və bindParam metodlarından da istifadə edə bilərsiniz. Birincisi, dəyişənin dəyərini sorğu hazırlamaq üçün istifadə olunan psevdo-dəyişənlə əlaqələndirir:

$stmt = $pdo->prepare("INSERT INTO planets(name, color) VALUES(:name, :color)"); $stmt->bindValue("ad", $planet->ad, PDO::PARAM_STR);

$planet->name dəyişəninin dəyərini psevdo dəyişən:name ilə əlaqələndirdi. Nəzərə alın ki, bindValue və bindParam metodlarından istifadə edərkən, dəyişənin növü uyğun PDO sabitlərindən istifadə edərək üçüncü arqument kimi müəyyən edilir. Nümunədə - PDO::PARAM_STR .

bindParam metodu dəyişəni psevdo dəyişənə bağlayır. Bu halda dəyişən psevdodəyişən istinadı ilə əlaqələndirilir və dəyər sorğuya yalnız icra metodu çağırıldıqdan sonra daxil ediləcək. Bir misala baxaq:

$stmt->bindParam("ad", $planet->ad, PDO::PARAM_STR);

PDO-da əməliyyatlar

Qeyri-adi bir nümunə təsəvvür edək. İstifadəçi planetlərin siyahısını seçməlidir və hər dəfə sorğu yerinə yetirildikdə cari məlumatlar verilənlər bazasından silinir, sonra isə yeniləri daxil edilir. Silindikdən sonra xəta baş verərsə, növbəti istifadəçi boş siyahı alacaq. Bunun qarşısını almaq üçün əməliyyatlardan istifadə edirik:

$pdo->beginTransaction(); cəhd edin ( $stmt1 = $pdo->exec("Planetlərdən SİL"); $stmt2 = $pdo->hazırlayın ("INSERT INTO planets(name, color) VALUES (?, ?)"); foreach ($planets as as $planet) ( $stmt2->execute([$planet->getName(), $planet->getColor()]); ) $pdo->commit() ) tutmaq (PDOException $e) ( $pdo-> rollBack ();

beginTransaction metodu sorğuların avtomatik icrasını qeyri-aktiv edir və try-catch konstruksiyasında sorğular istənilən ardıcıllıqla yerinə yetirilir. Heç bir PDOExceptions atılmırsa, sorğular commit metodundan istifadə etməklə tamamlanacaq. Əks halda, onlar geri qaytarma metodu ilə geri qaytarılacaq və sorğuların avtomatik icrası bərpa olunacaq.

Bu, sorğunun icrasında ardıcıllıq yaratdı. Aydındır ki, bunun baş verməsi üçün PDO::ATTR_ERRMODE PDO::ERRMODE_EXCEPTION olaraq təyin edilməlidir.

Nəticə

İndi PDO ilə işləmək təsvir edildikdən sonra onun əsas üstünlüklərini qeyd edək:

  • PDO ilə tətbiqi digər DBMS-lərə köçürmək asandır;
  • Bütün məşhur DBMS-lər dəstəklənir;
  • quraşdırılmış səhv idarəetmə sistemi;
  • nümunə nəticələrini təqdim etmək üçün müxtəlif variantlar;
  • kodu qısaldan və SQL inyeksiyalarına davamlı edən hazırlanmış sorğular dəstəklənir;
  • İstifadəçilər paralel işləyərkən məlumatların bütövlüyünü və sorğu ardıcıllığını qorumağa kömək edən əməliyyatlar dəstəklənir.
Əməliyyat