Pdo náhradní parametry bez provedení dotazu. Jak pracovat s PDO? Kompletní průvodce. Vkládání do databáze, metoda exec().

Připojení k databázi je nastavena při vytvoření instance třídy PDO. Nezáleží na tom, který ovladač se rozhodnete použít; Vždy budete muset použít třídu PDO. Jeho konstruktor přijímá parametry pro specifikaci zdroje databáze (známé jako DSN) a volitelné parametry pro uživatelské jméno a heslo.

Připojení k MySQL:

$dbh = new PDO("mysql:host=localhost;dbname=test", $user, $pass);

Pokud dojde k jakékoli chybě připojení, bude vyvolána výjimka: objekt třídy PDOException. Můžete to zachytit, pokud chcete tuto situaci zvládnout, nebo to můžete nechat na globální obslužnou rutinu výjimek, která se nastavuje pomocí set_exception_handler().

Ošetření chyb připojení:

try ( $dbh = new PDO("mysql:host=localhost;dbname=test", $user, $pass); foreach($dbh->query('SELECT * from FOO') as $row) ( print_r($ row); ) $dbh = null; ) catch (PDOException $e) ( die("Chyba! To je ono. Dorazili jsme... ".$e->getMessage()); )

Pozornost: Pokud nezachytíte výjimku vyvolanou konstruktorem PDO, výchozí akcí, kterou zend engine provede, je zastavení skriptu a zobrazení tracebacku. Tato kravina odhalí všechny vaše intimní detaily komunikace s databází. To znamená zobrazí podrobné údaje o připojení k databázi včetně uživatelského jména a hesla! Je na vás, abyste tuto výjimku zachytili, buď explicitně (prostřednictvím příkazu Zkus chytit), nebo implicitně prostřednictvím set_exception_handler().

Jakmile je připojení k databázi úspěšné, zůstane aktivní po celou dobu životnosti instance objektu PDO. Chcete-li ukončit připojení, musíte objekt zničit a zajistit, aby byly odstraněny všechny zbývající odkazy na něj - to lze provést přiřazením hodnoty NULL proměnné, která obsahuje objekt. Pokud to neuděláte explicitně, PHP po ukončení skriptu automaticky uzavře připojení.

Uzavření spojení:

$dbh = new PDO("mysql:host=localhost;dbname=test", $user, $pass); // Něco tady děláme: ... // A teď pozor: konec spojení! $dbh = null;

Mnoho webových aplikací těží z vytváření trvalých připojení k databázovým serverům. Trvalá připojení nejsou při ukončení skriptu uzavřena, ale jsou uložena do mezipaměti a znovu použita, když jiný skript požaduje připojení pomocí stejných přihlašovacích údajů. Trvalá mezipaměť připojení zabraňuje režii navazování nového připojení pokaždé, když skript potřebuje komunikovat s databází, což má za následek rychlejší běh webových aplikací.

Nastavení trvalého připojení:

$dbh = new PDO("mysql:host=localhost;dbname=test", $user, $pass, array(PDO::ATTR_PERSISTENT => true));

Mějte na paměti: Pokud chcete používat trvalé připojení, musíte nastavit PDO::ATTR_PERSISTENT v poli možností ovladače, které je předáno konstruktoru třídy PDO. Nastavením tohoto atributu pomocí PDO::setAttribute() po vytvoření instance objektu nebude ovladač používat trvalé odkazy. A také v tomto případě nebudete moci rozšířit třídu PDOStament pro některé své potřeby, tzn. nebude možné nainstalovat: PDO::ATTR_STATEMENT_CLASS

Myslím, že je čas rozšířit své zkušenosti a přejít z funkcí mysql_ na PDO při práci s databází. Tato knihovna je výkonným a rychlým doplňkem PHP. Jednou z jeho výhod je, že pracuje s mnoha databázemi (MS SQL, MySQL, PostgreSQL, Oracle atd.). Charakteristickým znakem této knihovny jsou také připravené výrazy, tzv. připravené příkazy, které by měly urychlit práci s databází a hlavně zabezpečit výměnu dat a zapomenout na takové zranitelnosti, jako je sql-injection. Kromě toho existují další velmi užitečné funkce. V tomto článku jsem se pokusil shromáždit často používané příklady prací, ze kterých okamžitě pochopíte podstatu práce s PDO.

V PHP existují tři rozšíření pro práci s databází MySQL: mysql, mysqli a PDO. PHP PDO (PHP Data Objects) je součástí PHP 5.1 a vyšší. Pokud tomu rozumím, v tuto chvíli se funkce pro práci s databází mysql_ nedoporučuje používat, protože vývoj php_mysql se zastavil na podpoře funkčnosti MySQL 4.1.3. a také nepodporuje transakce, rozhraní objektu a podléhá zranitelnostem při nahrazování hodnot do dotazu. Po mysql_ se objevilo rozšíření mysqli (MySQL Improved ve verzi 5), které podporuje nové funkce MySQL a využívá syntaxi OPP i procedurální programování. Všechny tyto knihovny používají standardní klientskou knihovnu MySQL (libmysql). Ve stejné poznámce se podíváme na živé příklady, jak pracovat s mysql pomocí nejnovějšího rozšíření - CHOP.

Připojení databáze PDO

//příklad připojení k MySQL pomocí PDO $db = new PDO("mysql:host=localhost;dbname=test", $user, $pass);

Jakmile je navázáno úspěšné připojení ke konkrétnímu databázovému serveru, bude vrácen objekt PDO. Tento objekt umožňuje provádět širokou škálu databázových úloh.

Pokud se vyskytnou nějaké chyby připojení, spustí se mechanismus výjimek - PDOException. Operace PDO byste měli vždy zabalit do bloku try/catch. Výjimku můžete zachytit, pokud chcete zpracovat chyby, nebo ji můžete ponechat na globálním ovladači výjimek, který jste vytvořili pomocí set_exception_handler(). PDO má speciální funkce pro chyby: errorCode() – vrátí číslo chyby, errorInfo() – vrátí pole s číslem chyby a popisem. Jsou potřeba, protože výchozí režim zpracování chyb je ERRMODE_SILENT. V tomto případě, abyste viděli tyto chyby, musíte je zavolat:

Echo $conn->errorCode(); echo $conn->errorInfo();

Aby se tomu zabránilo, je ve vývojovém režimu snazší okamžitě nastavit požadovaný režim zpracování chyb: ATTR_ERRMODE a ERRMODE_EXCEPTION. Můžete také určit kódování pro práci s databází. V důsledku toho získáme následující kód připojení:

Zkuste ( $db = nové PDO("mysql:host=$host;dbname=$dbname", $user, $heslo); $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $db-> exec("set names utf8"); ) catch(PDOException $e) ( echo $e->getMessage(); )

Po úspěšném připojení k databázi je skriptu vrácena instance třídy PDO. $db obsahuje popisovač databáze. Spojení zůstává aktivní po celou dobu životnosti objektu PDO. Chcete-li ukončit připojení, musíte objekt zničit a zajistit, aby byly odstraněny všechny ostatní odkazy na něj. To lze provést přiřazením proměnné, která obsahuje objekt, na hodnotu NULL. Pokud to neuděláte výslovně, PHP po dokončení skriptu automaticky uzavře připojení.

//Uzavření spojení $db = null;

Mnoho webových aplikací bude mít prospěch z vytváření trvalých připojení k databázovým serverům. Trvalá připojení nejsou na konci skriptu uzavřena, ale jsou ukládána do mezipaměti a znovu použita, když jiný skript požaduje připojení pomocí stejných pověření. Trvalé připojení snižuje režii vytváření nového připojení pokaždé, když skript potřebuje přístup k databázi, což vede k rychlejší webové aplikaci.

//Trvalé připojení $dbh = new PDO("mysql:host=localhost;dbname=test", $user, $pass, array(PDO::ATTR_PERSISTENT => true));

Nyní, když jste viděli, jak otevřít a zavřít připojení, pojďme se podívat na další příklady práce s PDO. V tomto případě vám ukážu, jak se dotazovat na konkrétní databázi. Dotazy lze provádět pomocí 3 funkcí: exec(), query() a Prepare+execute.

Exec()

První - exec vrátí pouze počet zahrnutých řádků nebo FALSE při chybě a používá se tam, kde nejsou vrácena žádná data, například při mazání:

//pomocí metody exec() try( $db = new PDO("mysql:host=localhost;dbname=test","user","password"); $delrows=$db->exec("DELETE FROM users WHERE id>20"); echo "Počet smazaných řádků: ".$delrows; ) catch(PDOException $e)( echo "Chyba: ".$e->getMessage(); exit(); ) //Více $ db- >exec("DELETE FROM people WHERE 1"); //nebo $db->exec("SET time_zone = "-8:00""); //nebo $db->exec("CREATE TABLE `test`(id INT PRIMARY KEY AUTO_INCREMENT, název VARCHAR(20) NOT NULL DEFAULT "", email VARCHAR(50) NOT NULL DEFAULT "")"); //nebo $db->exec("SET CHARACTER SET utf8");

Dotaz()

Za druhé, query() vrátí výsledek v objektu PDOStament. Také vrátí výsledek nebo FALSE při chybě. Můžete mu věřit s jednoduchými požadavky. Můžete použít query() s podmínkou (opravdu nevím, proč by to někdo potřeboval), ale pak stále musíte uniknout data pomocí metody PDO::quote

//Jednoduché dotazy $db->query("SET CHARACTER SET utf8"); $db->query("VYBRAT * Z uživatelů"); //Můžete vypočítat počet řádků $stmt = $db->query("SELECT * FROM table"); $row_count = $stmt->rowCount(); echo $row_count." rows selected"; //Další možnost s množstvím $stmt = $db->query("SELECT * from users"); $rows = $stmt->fetchAll(); $počet = počet($řádky); foreach($rows as $row) ( print_r($row); ) //Dotaz s podmínkou a escapováním $conn->query("SELECT * FROM tabulka WHERE id = " . $conn->quote($id));

lastInsertId() vrátí ID posledního vloženého řádku databáze.

//metoda lastInsertId() vrací id posledního záznamu $db->query("INSERT INTO users SET name="Vasya",address="Here",email=" [e-mail chráněný]""); $insertId=$db->lastInsertId();

Připravené výkazy.

Třetí způsob - připravit+provést - Připravené výrazy, jsou to také připravené instrukce, jsou to také zástupné symboly, jsou připravená prohlášení nebo svázat proměnné, vám umožní definovat výraz jednou a poté jej provést vícekrát s různými parametry. Umožňují také oddělit proměnné od požadavku, což činí kód bezpečnějším a zvyšuje rychlost provádění. Váš kód se již nebude muset pokoušet vyčistit přenášená data. Před provedením databázového dotazu to provedeme pouze jednou. K tomu použijeme funkci Připravit(); Jako parametr bere SQL dotaz, ale v něm se místo proměnných používají štítky ve formě otazníku '?' nebo číslic ':1', případně proměnné, jejíž název začíná dvojtečkou ':' . Pokud jste se zastavili u otazníků (:čísla), musíte do funkce spuštění předat pole hodnot v příslušném pořadí. Pokud je vaší volbou pojmenované proměnné, musíte každé proměnné přiřadit hodnotu pomocí jedné ze dvou funkcí: buď bindValue(), která přiřadí hodnotu pseudoproměnné, nebo bindParam(), která sváže pseudoproměnnou skutečnou proměnnou. Třetí parametr může udávat typ proměnné, například $db->bindParam(':id',$id, PDO::PARAM_INT).

//Nepojmenované štítky zkuste ( $stmt = $db->prepare("INSERT INTO test (label,color) VALUES (?,?)"); $stmt -> execute(array("perfect","green") ) ; ) catch(PDOException $e)( echo "Chyba: ".$e->getMessage(); exit(); ) //stmt je "stavový popisovač" //Pojmenované štítky $stmt = $db->prepare ( "INSERT INTO test (label,color) VALUES (:label,:color)"); $stmt -> execute(array("label"=>"perfect", "color"=>"green")); //Další možnost $stmt = $db->prepare("INSERT INTO users (firstname, lastname, email) VALUES (:firstname, :lastname, :email)"); $stmt->bindParam(":firstname", $firstname); $stmt->bindParam(":prijmeni", $prijmeni); $stmt->bindParam(":email", $email); $firstname = "Jan"; $lastname = "Smith"; $email = " [e-mail chráněný]"; $stmt->execute();

Ještě jednou připomenu, že pokud nepoužíváte připravené výrazy, ale přesto chcete přenášená data zabezpečit, pak to lze provést pomocí funkce PDO:quote.

údaje PDO SELECT

K načtení dat se používají metody fetch() nebo fetchAll(). Před voláním funkce musíte sdělit PDO, jak budete získávat data z databáze. PDO::FETCH_ASSOC vrátí řádky jako asociativní pole s názvy polí jako klíči. PDO::FETCH_NUM vrátí řetězce jako číselné pole. Ve výchozím nastavení se načítání provádí pomocí PDO::FETCH_BOTH, které duplikuje data pomocí číselných i asociativních klíčů, takže se doporučuje zadat jeden způsob, jak se vyhnout duplicitním polím:

$stmt = $db->query("VYBRAT * od uživatelů"); //Nastavení režimu načítání $stmt->setFetchMode(PDO::FETCH_ASSOC); while($row = $stmt->fetch()) ( echo "

" . $row["firstname"] . " " . $row["lastname"] ."

"; echo"

" . $row["e-mail"] ."


"; }

Nebo můžete zadat metodu fetch v samotné metodě ->fetch().

$stmt = $db->query("SELECT * FROM tabulky"); while($row = $stmt->fetch(PDO::FETCH_ASSOC)) ( echo $row["field1"]." ".$row["field2"]; //etc... ) // Pozor, příklad s LIKE nefunguje! $stmt = $db->prepare("VYBRAT pole FROM tabulky WHERE pole LIKE %?%"); $stmt->bindParam(1, $hledat, PDO::PARAM_STR); $stmt->execute(); //Potřebujete toto: $stmt = $db->prepare("SELECT pole FROM tabulky WHERE pole LIKE?"); $stmt->bindValue(1, "%$search%", PDO::PARAM_STR); $stmt->execute(); //Další příklad $stmt = $db->prepare("SELECT * FROM tabulky WHERE id=? AND name=?"); $stmt->bindValue(1, $id, PDO::PARAM_INT); $stmt->bindValue(2, $jméno, PDO::PARAM_STR); $stmt->execute(); $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); //Další možnost $stmt = $db->prepare("SELECT * from users"); $stmt -> vykonat(); while($row = $stmt->fetch()) ( print_r($row); )

AKTUALIZACE dat PDO

Děje se to v podstatě stejným způsobem jako INSERT a SELECT (v tomto případě opět použijeme pojmenované zástupné symboly):

$stmt = $db->prepare("UPDATE uživatelé nastavit email = :email where lastname=:lastname"); $stmt->bindParam(":prijmeni", $prijmeni); $stmt->bindParam(":email", $email); $lastname = "Smith"; $email = " [e-mail chráněný]"; $stmt->execute();

VYMAZAT Odstranění probíhá nejjednodušším způsobem:

$db->exec("SMAZAT Z uživatelů");

Při mazání můžete samozřejmě použít i pojmenované zástupné symboly.

Pokud máte vlastní často používané šablony při práci s rozšířením PHP PDO, budu vděčný, když se o ně podělíte. Odkaz na manuál

Pokud máte chybu Nedefinovaná proměnná: DBH... pak si můžete přečíst, jak ji opravit.

Google mi pomohl najít cheat sheet na PDO, možná se někomu bude hodit:

PDO (PHP Data Objects) je rozšíření PHP, které implementuje interakci s databázemi pomocí objektů. Výhodou je, že neexistuje žádné napojení na konkrétní systém správy databází. PDO podporuje DBMS: MySQL, PostgreSQL, SQLite, Oracle, Microsoft SQL Server a další.

Proč používat CHOP

Funkce mysql v PHP pro práci s databázemi jsou již dávno zastaralé, dnes je vhodné používat mysqli nebo PDO (PHP Data Objects). Kromě toho je mysqli knihovna, která obecně není určena k přímému použití v kódu. Může sloužit jako dobrý stavební materiál pro vytvoření knihovny vyšší úrovně. Při práci s mysqli byste také měli pamatovat na zajištění bezpečnosti vaší aplikace, zejména ochranu proti SQL injections. V případě použití PDO (s jeho připravenými dotazy) taková ochrana vychází z krabice, hlavní je správně aplikovat potřebné metody.

Test databáze s tabulkou

// Z konzole Windows mysql> CREATE DATABASE `pdo-test` CHARACTER SET utf8 COLLATE utf8_general_ci; USE pdo-test; CREATE TABLE kategorie (id INT(11) UNSIGNED NOT NULL AUTO_INCREMENT, PRIMARY KEY(id), název VARCHAR(255) NOT NULL); INSERT INTO `categories` (`name`) VALUES ("Laptopy a tablety"), ("Počítače a periferní zařízení"), ("PC komponenty"), ("Smartphony a chytré hodinky"), ("TV a média") , ("Hry a konzole"), ("Audio zařízení"), ("Foto a video zařízení"), ("Kancelářské zařízení a nábytek"), ("Síťová zařízení"), ("Velké domácí spotřebiče"), ( "Kuchyňské produkty"), ("Krása a zdraví"), ("Domácí výrobky"), ("Nástroje"), ("Autoprodukty");

Instalace PDO

// Instalace na Linuxu sudo apt update sudo apt install php7.2-mysql sudo apt-get install pdo-mysql // V php.ini přidejte extension=pdo.so extension=pdo_mysql.so // V systému Windows zpravidla ovladač je již nainstalován, stačí zkontrolovat, zda je povolen v php.ini extension=php_pdo_mysql.dll

Zkontrolujte dostupné ovladače

print_r(PDO::getAvailableDrivers());

Připojení k databázi

Spojení se navazují automaticky, když je objekt PDO vytvořen z jeho základní třídy.

// Příklad #1. Jednoduché připojení $db = nové PDO("mysql:host=localhost;dbname=pdo", "root", "heslo");

Pokud dojde k chybě připojení, PHP vyvolá chybu:

Závažná chyba: Uncaught PDOException: ... // Příklad #2. Zkuste zpracovat chyby připojení ( $dbh = nové PDO("mysql:host=localhost;dbname=pdo", "root", "heslo"); ) catch (PDOException $e) ( tisk "Chyba!: " . $e- >getMessage(); die(); )

V tomto příkladu připojení používáme konstrukci try...catch. Mnozí argumentují o vhodnosti jeho použití. Osobně používám try...catch , nevadí mi to.

Připravené a přímé požadavky

Existují dva způsoby, jak provádět dotazy v PDO:

  • Přímý - skládá se z jednoho kroku;
  • Připraveno – skládá se ze dvou kroků.

Přímé požadavky

  • query() se používá pro příkazy, které neprovádějí změny, jako je SELECT. Vrátí objekt PDOStatemnt, ze kterého jsou načteny výsledky dotazu pomocí metod fetch() nebo fetchAll. Můžete jej porovnat se zdrojem mysql, který vrátil mysql_query().
  • exec() se používá pro příkazy INSERT, DELETE, UPDATE. Vrátí počet řádků zpracovaných požadavkem.

Přímé dotazy se používají pouze v případě, že v dotazu nejsou žádné proměnné a jste si jisti, že je dotaz bezpečný a správně escapovaný.

$stmt = $db->query("VYBRAT * Z kategorií"); while ($row = $stmt->fetch()) ( echo "

"; print_r($řádek); )

Připravené dotazy

Pokud je požadavku předána alespoň jedna proměnná, musí být tento požadavek proveden pouze prostřednictvím připravených výrazů. Co to znamená? Jedná se o běžný SQL dotaz, ve kterém je místo proměnné umístěna speciální značka – zástupný symbol. PDO podporuje poziční zástupné symboly (?), pro které je důležité pořadí předávaných proměnných, a pojmenované zástupné symboly (:name), pro které pořadí není důležité. Příklady:

$sql = "VYBRAT jméno Z kategorií WHERE id =?"; $sql = "VYBRAT jméno Z kategorií WHERE jméno = :jméno";

Aby bylo možné takový dotaz provést, musí být nejprve připraven pomocí metody Prepare(). Vrátí také příkaz PDO, ale zatím bez jakýchkoliv dat. Abychom je získali, musíme provést tento požadavek poté, co jsme do něj předtím předali naše proměnné. Můžete jej předat dvěma způsoby: Nejčastěji můžete jednoduše spustit metodu execute() a předat jí pole s proměnnými:

$stmt = $pdo->prepare("SELECT `name` FROM category WHERE `id` = ?"); $stmt->execute([$id]); $stmt = $pdo->prepare("SELECT `name` FROM category WHERE `name` = :name"); $stmt->execute(["jméno" => $jméno]);

Jak vidíte, v případě pojmenovaných zástupných symbolů musí být předáno pole, ve kterém se klíče musí shodovat se jmény zástupných symbolů, aby se vykonala(). Poté můžete načíst výsledky dotazu:

$id = 1; $stmt = $db->prepare("SELECT * FROM category WHERE `id` = ?"); $stmt->execute([$id]); $kategorie = $stmt->fetch(PDO::FETCH_LAZY); echo"

"; print_r($kategorie);

DŮLEŽITÉ! Připravené dotazy jsou hlavním důvodem pro použití PDO, protože je to jediný bezpečný způsob provádění SQL dotazů, které zahrnují proměnné.

Přijímání dat. metoda fetch().

S metodou fetch(), která slouží k sekvenčnímu získávání řádků z databáze, jsme se již seznámili. Tato metoda je obdobou funkce mysq_fetch_array() a podobných, ale chová se jinak: místo mnoha funkcí je zde použita jedna, ale její chování je specifikováno předávaným parametrem. Podrobnosti o těchto parametrech budou zapsány a jako krátké doporučení vám doporučuji použít fetch() v režimu FETCH_LAZY

$id = 1; $stmt = $db->prepare("SELECT * FROM category WHERE `id` = ?"); $stmt->execute([$id]); while ($row = $stmt->fetch(PDO::FETCH_LAZY)) ( echo "Název kategorie: ".$row->name; )

V tomto režimu nedochází k plýtvání další pamětí a kromě toho lze ke sloupcům přistupovat kterýmkoli ze tří způsobů – prostřednictvím indexu, názvu nebo vlastnosti (přes ->). Nevýhodou tohoto režimu je, že nefunguje s fetchAll()

Přijímání dat. metoda fetchColumn().

Příkaz PDO má také metodu pro získání hodnoty jednoho sloupce. Je velmi výhodné, pokud požadujeme pouze jedno pole - v tomto případě je množství kódu výrazně sníženo:

$id = 1; $stmt = $db->prepare("SELECT `name` FROM category WHERE `id` = ?"); $stmt->execute([$id]); $name = $stmt->fetchColumn(); echo "Název kategorie: ".$name;

Přijímání dat. metoda fetchAll().

$data = $db->query("SELECT * FROM category")->fetchAll(PDO::FETCH_ASSOC); foreach ($data jako $k => $v)( echo "Název kategorie: ".$v["jméno"]."
"; }

PDO a operátor LIKE

Při práci s připravenými dotazy byste měli pochopit, že zástupný symbol může nahradit pouzeřetězec nebo číslo. Není to klíčové slovo, není identifikátor, není součástí řetězce nebo sady řetězců prostřednictvím zástupného symbolu nemůžete nahradit. Proto pro LIKE musíte nejprve připravit celý hledaný řetězec a poté jej dosadit do dotazu:

$hledat = "komp"; $query = "VYBRAT * Z kategorií WHERE `name` LIKE ?"; $params = ["%$search%"]; $stmt = $db->prepare($dotaz); $stmt->execute($params); $data = $stmt->fetchAll(PDO::FETCH_ASSOC); $i = 1; foreach ($data as $category)( echo $i++ . ". " . $category["name"]."
"; }

Zde může nastat problém! Vyhledávání nemusí fungovat, protože přijímáte data z databáze ve špatném kódování. Musíte přidat kódování do připojení, pokud tam není uvedeno!

$db = nové PDO("mysql:host=localhost;dbname=pdo;charset=utf8", "root", "");

PDO a operátor LIMIT

Důležité! Když PDO běží v režimu emulace, všechna data, která byla předána přímo do execute() jsou formátována jako řetězce. To znamená, že jsou escapovány a orámovány v uvozovkách. Proto LIMIT?,? změní na LIMIT "10", "10" a zjevně způsobí chybu syntaxe a v důsledku toho prázdné pole dat.

Řešení #1: Zakažte režim emulace:

$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);

Řešení #2: Svažte tato čísla pomocí bindValue() , čímž je vynutíte, aby byla typu PDO::PARAM_INT:

$limit = 3; $stm = $db->prepare("VYBRAT * FROM LIMIT kategorií?"); $stm->bindValue(1, $limit, PDO::PARAM_INT); $stm->execute(); $data = $stm->fetchAll(); echo"

"; print_r($data);

Operátor PDO a IN

Při výběru z tabulky je nutné načíst záznamy, které odpovídají všem hodnotám pole.

$arr = ; $in = str_repeat("?,", count($arr) - 1) . "?"; $sql = "VYBRAT * Z kategorií WHERE `id` IN ($in)"; $stm = $db->prepare($sql); $stm->execute($arr); $data = $stm->fetchAll(); echo"

"; print_r($data);

Přidávání záznamů

$name = "Nová kategorie"; $query = "INSERT INTO `categories` (`name`) VALUES (:name)"; $params = [ ":jméno" => $jméno ]; $stmt = $pdo->prepare($dotaz); $stmt->execute($params);

Změna záznamů

$id = 1; $name = "Změněný záznam"; $query = "UPDATE `categories` SET `name` = :name WHERE `id` = :id"; $params = [ ":id" => $id, ":name" => $jméno ]; $stmt = $pdo->prepare($dotaz); $stmt->execute($params);

Mazání záznamů

$id = 1; $query = "DELETE FROM `categories` WHERE `id` = ?"; $params = [$id]; $stmt = $pdo->prepare($dotaz); $stmt->execute($params);

Používání transakcí

try ( // Začátek transakce $pdo->beginTransaction(); // ... kód // Pokud bylo vše úspěšné jako výsledek spuštění našeho kódu, // zaznamenáme tento výsledek $pdo->commit() ; ) catch (Výjimka $e) ( // V opačném případě odvolá transakci. $pdo->rollBack(); echo "Chyba: " . $e->getMessage(); )

Důležité! Transakce v PDO fungují pouze na tabulkách InnoDB

V tomto článku jsme se seznámili se základními pojmy PDO, jeho instalací, připojením k databázi a nejjednoduššími možnostmi výběru, změny a mazání dat. V budoucích příspěvcích se podíváme na několik dalších témat souvisejících s PDO.

Poskytuje metody pro přípravu výrazů a práci s objekty, které vám mohou zvýšit produktivitu!

Úvod do CHOP

"PDO - PHP Data Objects je vrstva pro přístup k databázi, která poskytuje jednotné metody pro přístup k různým databázím."

Nespoléhá se na specifickou syntaxi databáze a umožňuje vám ve většině případů snadno přejít na jiný typ databáze a platformu jednoduše změnou připojovacího řetězce.

Tato lekce není popisem procesu práce s SQL. Je určen pro ty, kteří používají rozšíření mysql nebo mysqli pomoci jim přejít na výkonnější a přenosnější CHOP.

Podpora databáze

Rozšíření podporuje jakoukoli databázi, pro kterou existuje ovladač PDO. V současné době jsou k dispozici ovladače pro následující typy databází:

  • PDO_DBLIB (FreeTDS / Microsoft SQL Server / Sybase)
  • PDO_FIREBIRD (Firebird/Interbase 6)
  • PDO_IBM (IBM DB2)
  • PDO_INFORMIX (IBM Informix Dynamic Server)
  • PDO_MYSQL (MySQL 3.x/4.x/5.x)
  • PDO_OCI (rozhraní volání Oracle)
  • PDO_ODBC (ODBC v3 (IBM DB2, unixODBC a win32 ODBC))
  • PDO_PGSQL (PostgreSQL)
  • PDO_SQLITE (SQLite 3 a SQLite 2)
  • PDO_4D (4D)

Aby systém fungoval, stačí nainstalovat pouze ty ovladače, které jsou skutečně potřeba. Seznam ovladačů dostupných v systému můžete získat takto:

Print_r(PDO::getAvailableDrivers());

Spojení

Různé databáze mohou mít mírně odlišné způsoby připojení. Níže jsou uvedeny způsoby připojení k několika populárním databázím. Všimnete si, že první tři jsou navzájem totožné a pouze SQLite má specifickou syntaxi.


zkuste ( # MS SQL Server a Sybase s PDO_DBLIB $DBH = nové PDO("mssql:host=$host;dbname=$dbname, $user, $pass"); $DBH = nový PDO("sybase:host=$hostitel ;dbname=$dbname, $user, $pass"); # MySQL s PDO_MYSQL $DBH = nové PDO("mysql:host=$host;dbname=$dbname", $user, $pass); # SQLite $DBH = new PDO("sqlite:my/database/path/database.db"); ) catch (PDOException $e) ( echo $e->getMessage(); )

Věnujte pozornost bloku Zkus chytit- operace PDO byste měli vždy zabalit do bloku Zkus chytit a použijte mechanismus výjimek. Obvykle se vytvoří pouze jedno připojení, náš příklad ukazuje více připojení, aby byla ukázána syntaxe. $DBH obsahuje popisovač databáze a bude používán v celém našem tutoriálu.

Jakékoli připojení můžete ukončit nastavením rukojeti na nula.

# Uzavřete spojení $DBH = null;

Více o konkrétních možnostech a připojovacích řetězcích pro různé databáze se můžete dozvědět z dokumentů na PHP.net.

Výjimky a CHOP

PDO může používat výjimky ke zpracování chyb. To znamená, že všechny operace PDO musí být uzavřeny do bloku Zkus chytit. PDO může vyvolat tři úrovně chyb, úroveň kontroly chyb se vybírá nastavením atributu režimu kontroly chyb pro deskriptor databáze:

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

Bez ohledu na nastavenou úroveň řízení chyba připojení vždy vyvolá výjimku, a proto by měla být vždy uzavřena v bloku Zkus chytit.

PDO::ERRMODE_SILENT

Úroveň kontroly chyb je standardně nastavena. Na této úrovni se chyby generují podle stejného principu jako v rozšířeních mysql nebo mysqli. Další dvě úrovně kontroly chyb jsou vhodnější pro programovací styl DRY (Don't Repeat Youself).

PDO::ERRMODE_WARNING

Na této úrovni kontroly chyb jsou generována standardní PHP varování a program může pokračovat ve vykonávání. Tato úroveň je vhodná pro ladění.

PDO::ERRMODE_EXCEPTION

Tato úroveň kontroly chyb by se měla používat ve většině situací. Výjimky jsou generovány za účelem pečlivého zpracování chyb a skrytí dat, která by mohla někomu pomoci hacknout váš systém. Níže je uveden příklad demonstrující výhody výjimek:

# Zkuste se připojit k databázi ( $DBH = nový PDO("mysql:host=$host;dbname=$dbname", $user, $pass); $DBH->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION) ; # Chybné zadání DELECT místo SELECT! $DBH->prepare("DELECT name FROM people"); ) catch(PDOException $e) ( echo "Omlouváme se. Ale operaci nelze provést."; file_put_contents("PDOErrors. txt" , $e->getMessage(), FILE_APPEND); )

Zde je záměrná chyba v příkazu SELECT. To vyvolá výjimku. Výjimka odešle popis chyby do souboru protokolu a zobrazí zprávu uživateli.

Vkládání a aktualizace dat

Vkládání nových dat nebo aktualizace stávajících dat je jednou z nejčastěji používaných běžných databázových operací. Při použití PDO se rozkládá na dvě fáze. Vše popsané v této kapitole platí pro obě operace. AKTUALIZACE A VLOŽIT.


Zde je příklad nejpoužívanějšího typu vkládání dat:

# STH je "stavový ovladač" $STH = $DBH->prepare("INSERT INTO people (first_name) values ​​​​("Cathy")"); $STH->execute();

Tuto operaci můžete samozřejmě provést pomocí metody exec() a počet hovorů bude o jedno méně. Pro získání výhod připravených výrazů je ale lepší použít delší metodu. I když je zamýšlíte použít pouze jednou, připravené výrazy vám pomohou chránit se před útoky na váš systém.

Připravené výrazy

Připravené příkazy jsou předkompilované příkazy SQL, které lze provést mnohokrát odesláním pouze dat na server. Další výhodou je automatické naplnění šablony daty v podobě ochrany před útoky prostřednictvím příloh SQL kódu.

Připravené výrazy můžete použít zahrnutím šablon do kódu SQL. Níže jsou uvedeny 3 příklady: jeden bez šablon, jeden s nepojmenovanými šablonami, jeden s pojmenovanými šablonami.

# žádné šablony – otevřené útokům SQL injection! $STH = $DBH->("INSERT INTO people (name, addr, city) values ​​​​($name, $addr, $city)"); # nepojmenovaných šablon $STH = $DBH->("INSERT INTO lidí (jméno, adresa, město) hodnoty ​​(?, ?, ?); # pojmenovaných šablon $STH = $DBH->("INSERT INTO lidí (jméno , addr , city) value (:name, :addr, :city)");

Měli byste se vyhnout použití první metody. Výběr pojmenovaných nebo nepojmenovaných vzorů ovlivňuje, jak nastavíte data pro tyto výrazy.

Nepojmenované šablony

# ke každé šabloně přiřaďte proměnné, indexované od 1 do 3 $STH->bindParam(1, $name); $STH->bindParam(2, $addr); $STH->bindParam(3, $město); # Vložte jeden řádek $name = "Dima" $addr = "Lizyukova St."; $city = "Moskva"; $STH->execute(); # Vložit další řádek $name = "Senya" $addr = "Komunistická slepá ulička"; $city = "Petr"; $STH->execute();

Operace probíhá ve dvou fázích. V prvním kroku jsou šablonám přiřazeny proměnné. Poté jsou proměnným přiřazeny hodnoty a výraz je proveden. Chcete-li odeslat další část dat, musíte změnit hodnoty proměnných a znovu spustit výraz.

Vypadá to trochu těžkopádně pro výrazy se spoustou parametrů? Rozhodně. Pokud jsou však vaše data uložena v poli, bude vše velmi krátké:

# Data k vložení $data = array("Monya", "Forget-Me-Not Avenue", "Zakutajsk"); $STH = $DBH->("INSERT INTO people (jméno, adresa, město) hodnoty ​​(?, ?, ?)"); $STH->execute($data);

Data v poli jsou nahrazena do šablon v pořadí, v jakém se objevují. $data jde do první šablony, $data do druhé a tak dále. Pokud je však pole indexováno v jiném pořadí, nebude taková operace provedena správně. Musíte zajistit, aby pořadí vzorů odpovídalo pořadí dat v poli.

Pojmenované šablony

Zde je příklad použití pojmenované šablony:

# První argument funkce je název pojmenované šablony # Pojmenovaná šablona vždy začíná dvojtečkou $STH->bindParam(":name", $name);

Můžete použít zkratky, ale fungují s přidruženými poli. Příklad:

# Data k vložení $data = array("name" => "Michelle", "addr" => "Kuznechny Lane", "city" => "Cnjkbwf"); # Zkratka $STH = $DBH->("INSERT INTO people (name, addr, city) value (:name, :addr, :city)"); $STH->execute($data);

Klíče vaší tabulky nevyžadují dvojtečku, ale přesto musí odpovídat názvům šablon. Pokud používáte pole polí, můžete je iterovat a jednoduše zavolat vykonat pro každý soubor dat.

Další příjemnou vlastností pojmenovaných šablon je možnost vkládat objekty přímo do databáze, když se vlastnosti a názvy polí shodují. Příklad:

# Simple object class person ( public $name; public $addr; public $city; function __construct($n,$a,$c) ( $this->name = $n; $this->addr = $a; $ this->city = $c; ) # atd... ) $cathy = new person("Katya","Lenin Avenue","Mozhaisk"); # Proveďte: $STH = $DBH->("INSERT INTO people (name, addr, city) value (:name, :addr, :city)"); $STH->execute((pole)$cathy);

Převod typu objektu na pole PROTI vykonat způsobí, že vlastnosti budou považovány za klíče pole.

Přijímání dat


K získávání dat se používá metoda identifikátoru stavu ->fetch(). Před voláním metody vynést() musíte PDO sdělit, jak budete získávat data z databáze. Můžete vybrat následující možnosti:

  • PDO::FETCH_ASSOC: vrátí pole indexované podle názvů sloupců
  • PDO::FETCH_BOTH (výchozí): vrátí pole indexované podle názvů sloupců a čísel
  • PDO::FETCH_BOUND: Přiřadí hodnoty vašich sloupců sadě proměnných pomocí metody ->bindColumn()
  • PDO::FETCH_CLASS: přiřadí hodnoty sloupců vlastnostem pojmenované třídy; pokud odpovídající vlastnost neexistuje, je vytvořena
  • PDO::FETCH_INTO: aktualizuje existující instanci pojmenované třídy
  • PDO::FETCH_LAZY: kombinace PDO::FETCH_BOTH/PDO::FETCH_OBJ, vytváří názvy proměnných objektů tak, jak jsou používány
  • PDO::FETCH_NUM: vrátí pole indexované podle čísel sloupců
  • PDO::FETCH_OBJ: vrací anonymní objekt s názvy vlastností odpovídajícími názvům sloupců

Ve skutečnosti se základní situace řeší pomocí tří možností: FETCH_ASSOC, FETCH_CLASS A FETCH_OBJ. Postup nastavení metody extrakce dat:

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

Přímo ve volání metody můžete také nastavit metodu načítání dat ->fetch().

FETCH_ASSOC

Tento typ načítání dat vytváří asociativní pole indexované podle názvů sloupců. Mělo by to být poměrně dobře známé těm, kteří používají rozšíření mysql/mysqli. Ukázka dat:

$STH = $DBH->query("VYBRAT jméno, adr, město od lidí"); # Nastavte režim získávání dat $STH->setFetchMode(PDO::FETCH_ASSOC); while($row = $STH->fetch()) ( echo $row["name"] . "\n"; echo $row["addr"] . "\n"; echo $row["city"] . "\n" ;)

Cyklus zatímco pokračuje v iteraci výsledku vzorku jeden řádek po druhém, dokud nebude dokončen.

FETCH_OBJ

S tímto typem načítání dat je vytvořen objekt třídy std pro každý řádek přijatých dat:

$STH = $DBH->query("VYBRAT jméno, adr, město od lidí"); # Nastavte režim načítání dat $STH->setFetchMode(PDO::FETCH_OBJ); # zobrazit výsledek while($row = $STH->fetch()) ( echo $row->name . "\n"; echo $row->addr. "\n"; echo $row->city ." \ n" ;)

FETCH_CLASS

Při tomto typu extrakce jsou data umístěna přímo do třídy, kterou si vyberete. Použitím FETCH_CLASS vlastnosti vašeho objektu jsou nastaveny PŘED voláním konstruktoru. Je to velmi důležité. Pokud vlastnost odpovídající názvu sloupce neexistuje, bude taková vlastnost vytvořena (jako veřejnost) pro tebe.

To znamená, že pokud data potřebují transformaci po načtení z databáze, může to být provedeno automaticky vaším objektem, jakmile je vytvořeno.

Představte si například situaci, kdy musí být adresa u každého záznamu částečně skryta. Úkol můžeme splnit manipulací s vlastností v konstruktoru:

Tajná_osoba třídy ( public $name; public $addr; public $city; public $other_data; function __construct($other = "") ( $this->address = preg_replace("//", "x", $this-> adresa); $this->other_data = $other; ))

Jakmile jsou data extrahována do třídy, všechna malá písmena a–z v adrese budou nahrazena znakem x. Nyní, pomocí třídy a načítání dat, transformace probíhá zcela transparentně:

$STH = $DBH->query("VYBRAT jméno, adr, město od lidí"); $STH->setFetchMode(PDO::FETCH_CLASS, "tajná_osoba"); while($obj = $STH->fetch()) ( echo $obj->addr; )

Pokud byla adresa 'Leninsky Prospekt 5', uvidíte 'Lxxxxxxxxxx xx-x 5'. Samozřejmě existují situace, kdy chcete, aby byl konstruktor zavolán před přiřazením dat. PDO má prostředky k realizaci:

$STH->setFetchMode(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, "tajná_osoba");

Nyní, když zopakujete předchozí příklad s nastaveným režimem PDO::FETCH_PROPS_LATE adresa nebude skryta, protože byl zavolán konstruktor a byly přiřazeny vlastnosti.

Pokud potřebujete, můžete při extrahování dat do objektu předat konstruktoru argumenty:

$STH->setFetchMode(PDO::FETCH_CLASS, "tajná_osoba", array("stuff"));

Pokud potřebujete pro každý objekt předat konstruktoru jiná data, můžete uvnitř metody nastavit režim načítání dat vynést:

$i = 0; while($rowObj = $STH->fetch(PDO::FETCH_CLASS, "secret_person", array($i))) ( // dělat věci $i++ )

Některé další užitečné metody

Protože PDO nelze v krátkém článku plně popsat, představíme několik užitečných metod pro provádění základních operací.

$DBH->lastInsertId();

Metoda ->lastInsertId() je vždy volána popisovačem databáze (nikoli popisovačem stavu) a vrací hodnotu automaticky inkrementovaného id posledního vloženého řádku pro dané připojení.

$DBH->exec("SMAZAT OD lidí, KDE 1"); $DBH->exec("SET time_zone = "-8:00"");

Metoda ->exec() používá se pro různé pomocné operace.

$safe = $DBH->quote($unsafe);

Metoda ->citovat() kvóty řetězce, takže je lze použít v dotazech. Toto je vaše rezerva pro případ, že nebudou použity připravené výrazy.

$rows_affected = $STH->rowCount();

Metoda ->rowCount() vrací hodnotu celé číslo, udávající počet řádků, které jsou zpracovány operací. V nejnovější verzi PDO podle zprávy o chybě (http://bugs.php.net/40822) tato metoda nefunguje s výrazy VYBRAT. Pokud máte problémy a nemůžete aktualizovat PHP, můžete získat počet řádků následujícím způsobem:

$sql = "VYBRAT POČET(*) OD lidí"; if ($STH = $DBH->query($sql)) ( # Zkontrolujte počet řádků if ($STH->fetchColumn() > 0) ( # Zde by měl být kód SELECT) else ( echo "Existují žádné řádky neodpovídají dotazu." ;))

Doufám, že se vám lekce líbila!

  • Překlad

Mnoho vývojářů PHP je zvyklých používat pro práci s databázemi rozšíření mysql a mysqli. Ale od verze 5.1 v PHP existuje pohodlnější způsob - PHP Data Objects. Tato třída, zkráceně nazývaná PDO, poskytuje metody pro práci s objekty a připravenými příkazy, které výrazně zlepší vaši produktivitu!

Úvod do CHOP

"PDO – PHP Data Objects je vrstva, která nabízí univerzální způsob práce s více databázemi."

Ponechává starost o syntaktické funkce různých DBMS na vývojáři, ale proces přepínání mezi platformami je mnohem méně bolestivý. Často to vyžaduje pouze změnu připojovacího řetězce databáze.


Tento článek je napsán pro lidi, kteří používají mysql a mysqli, aby jim pomohl přejít na výkonnější a flexibilnější PDO.

podpora DBMS

Toto rozšíření může podporovat jakýkoli systém správy databází, pro který existuje ovladač PDO. V době psaní tohoto článku jsou k dispozici následující ovladače:
  • PDO_CUBRID (CUBRID)
  • PDO_DBLIB (FreeTDS / Microsoft SQL Server / Sybase)
  • PDO_FIREBIRD (Firebird/Interbase 6)
  • PDO_IBM (IBM DB2)
  • PDO_INFORMIX (IBM Informix Dynamic Server)
  • PDO_MYSQL (MySQL 3.x/4.x/5.x)
  • PDO_OCI (rozhraní volání Oracle)
  • PDO_ODBC (ODBC v3 (IBM DB2, unixODBC a win32 ODBC))
  • PDO_PGSQL (PostgreSQL)
  • PDO_SQLITE (SQLite 3 a SQLite 2)
  • PDO_SQLSRV (Microsoft SQL Server)
  • PDO_4D (4D)
Ne všechny jsou však na vašem serveru. Seznam dostupných ovladačů můžete vidět takto:
print_r(PDO::getAvailableDrivers());

Spojení

Způsoby připojení k různým DBMS se mohou mírně lišit. Níže jsou uvedeny příklady připojení k těm nejoblíbenějším. Všimnete si, že první tři mají na rozdíl od SQLite identickou syntaxi.
zkuste ( # MS SQL Server a Sybase přes PDO_DBLIB $DBH = nový PDO("mssql:host=$host;dbname=$dbname", $user, $pass); $DBH = nový PDO("sybase:host=$hostitel ;dbname=$dbname", $user, $pass); # MySQL přes PDO_MYSQL $DBH = nové PDO("mysql:host=$host;dbname=$dbname", $user, $pass); # SQLite $DBH = new PDO("sqlite:my/database/path/database.db"); ) catch (PDOException $e) ( echo $e->getMessage(); )
Věnujte prosím pozornost bloku try/catch – vždy se do něj vyplatí zabalit všechny vaše operace s PDO a použít mechanismus výjimek (o tom později).

$DBH znamená „database handle“ a bude používán v celém článku.

Jakékoli připojení můžete ukončit předefinováním jeho proměnné na hodnotu null.
# zavře spojení $DBH = null;
Více informací na téma výrazné možnosti různých DBMS a způsoby připojení k nim naleznete na php.net.

Výjimky a CHOP

PDO může vyvolat výjimky na chyby, takže vše by mělo být v bloku try/catch. Ihned po vytvoření připojení lze PDO uvést do kteréhokoli ze tří chybových režimů:
$DBH->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT); $DBH->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING); $DBH->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
Ale stojí za zmínku, že chyba při pokusu o připojení vždy vyvolá výjimku.

PDO::ERRMODE_SILENT

Toto je výchozí režim. Pravděpodobně použijete zhruba totéž k zachycení chyb v rozšířeních mysql a mysqli. Následující dva režimy jsou vhodnější pro programování DRY.

PDO::ERRMODE_WARNING

Tento režim způsobí standardní varování a umožní skriptu pokračovat ve vykonávání. Vhodné pro ladění.

PDO::ERRMODE_EXCEPTION

Ve většině situací je tento typ kontroly provádění skriptu vhodnější. Vyvolá výjimku, která vám umožní chytře ošetřit chyby a skrýt citlivé informace. Jako například zde:
# pokus o připojení k databázi ( $DBH = nový PDO("mysql:host=$host;dbname=$dbname", $user, $pass); $DBH->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION) ; # Sakra! Napsal jsem DELECT místo SELECT! $DBH->prepare("DELECT name FROM people")->execute(); ) catch(PDOException $e) ( echo "Houstone, máme problém."; file_put_contents ("PDOErrors .txt", $e->getMessage(), FILE_APPEND); )
Ve výrazu SQL je chyba syntaxe, která vyvolá výjimku. Můžeme zaznamenat podrobnosti o chybě do souboru protokolu a naznačit uživateli lidskou řečí, že se něco stalo.

Vložit a aktualizovat

Vkládání nových dat a aktualizace stávajících dat jsou některé z nejběžnějších databázových operací. V případě CHOP se tento proces obvykle skládá ze dvou kroků. (Další část je o AKTUALIZACI i VLOŽENÍ)


Triviální příklad vkládání nových dat:
# STH znamená "Popis prohlášení" $STH = $DBH->prepare("INSERT INTO people (first_name) values ​​​​("Cathy")"); $STH->execute();
Ve skutečnosti můžete totéž udělat s jednou metodou exec(), ale dvoukroková metoda poskytuje všechny výhody připravených příkazů. Pomáhají chránit před injekcemi SQL, takže má smysl je používat i pro jednorázový dotaz.

Připravené výpisy

Použití připravených příkazů posiluje ochranu proti injekcím SQL.

Připravený příkaz je předkompilovaný příkaz SQL, který lze opakovaně provádět odesláním pouze různých sad dat na server. Další výhodou je, že není možné provádět vkládání SQL přes data použitá v zástupných symbolech.

Níže jsou uvedeny tři příklady připravených prohlášení.
# bez zástupných symbolů - dveře k SQL injekcím jsou otevřené! $STH = $DBH->prepare("INSERT INTO people (name, addr, city) values ​​​​($name, $addr, $city)"); # nepojmenované zástupné symboly $STH = $DBH->prepare("INSERT INTO people (jméno, adresa, město) hodnoty ​​(?, ?, ?)"); # pojmenované zástupné symboly $STH = $DBH->prepare("INSERT INTO people (name, addr, city) values ​​​​(:name, :addr, :city)");
První příklad je zde pouze pro srovnání a je třeba se mu vyhnout. Rozdíl mezi bezejmennými a pojmenovanými zástupnými symboly je v tom, jak předáváte data připraveným příkazům.

Nepojmenované zástupné symboly

# každému zástupnému symbolu přiřaďte proměnné s indexy od 1 do 3 $STH->bindParam(1, $name); $STH->bindParam(2, $addr); $STH->bindParam(3, $město); # vložte jeden řádek $name = "Daniel" $addr = "1 zlá cesta"; $city = "Arlington Heights"; $STH->execute(); # vložte další řádek s jinými údaji $name = "Steve" $addr = "5 Circle Drive"; $city = "Schaumburg"; $STH->execute();
Jsou zde dva kroky. Na prvním z nich přiřadíme proměnné všem zástupným symbolům (řádky 2-4). Poté těmto proměnným přiřadíme hodnoty a provedeme dotaz. Chcete-li odeslat novou sadu dat, jednoduše změňte hodnoty proměnných a spusťte požadavek znovu.

Pokud má váš výraz SQL mnoho parametrů, pak je přiřazení proměnné každému velmi nepohodlné. V takových případech můžete data uložit do pole a předat je:
# sada dat, kterou vložíme $data = array("Cathy", "9 Dark and Twisty Road", "Cardiff"); $STH = $DBH->prepare("INSERT INTO people (jméno, adresa, město) hodnoty ​​(?, ?, ?)"); $STH->execute($data);
$data budou vložena na místo prvního zástupného symbolu, $data na místo druhého atd. Ale buďte opatrní: pokud jsou vaše indexy zmatené, nebude to fungovat.

Pojmenované zástupné symboly

# první argument je název zástupného symbolu # obvykle začíná dvojtečkou # ačkoliv to funguje i bez nich $STH->bindParam(":name", $name);
Zde můžete také předat pole, ale musí být asociativní. Klíče by měly být, jak asi tušíte, názvy zástupných symbolů.
# data, která vložíme $data = array("name" => "Cathy", "addr" => "9 Dark and Twisty", "city" => "Cardiff"); $STH = $DBH->prepare("INSERT INTO people (name, addr, city) values ​​​​(:name, :addr, :city)"); $STH->execute($data);
Jednou z výhod používání pojmenovaných zástupných symbolů je možnost vkládat objekty přímo do databáze, pokud se názvy vlastností shodují s názvy parametrů. Data můžete vložit například takto:
# třída pro osobu s jednoduchým objektem ( public $name; public $addr; public $city; function __construct($n,$a,$c) ( $this->name = $n; $this->addr = $ a ; $this->city = $c; ) # tak dále... ) $cathy = nová osoba("Cathy","9 Dark and Twisty","Cardiff"); # a tady je zajímavá část $STH = $DBH->prepare("INSERT INTO people (name, addr, city) values ​​​​(:name, :addr, :city)"); $STH->execute((pole)$cathy);
Převedení objektu na pole během execute() způsobí, že vlastnosti budou považovány za klíče pole.

Vzorkování dat



Data lze načíst pomocí metody ->fetch(). Před jejím zavoláním je vhodné výslovně uvést, v jaké formě je požadujete. Existuje několik možností:
  • PDO::FETCH_ASSOC: vrátí pole s názvy sloupců jako klíče
  • PDO::FETCH_BOTH (výchozí): vrací pole s indexy jak ve formě názvů sloupců, tak jejich sériových čísel
  • PDO::FETCH_BOUND: přiřadí hodnoty sloupců odpovídajícím proměnným zadaným pomocí metody ->bindColumn().
  • PDO::FETCH_CLASS: přiřadí hodnoty sloupců odpovídajícím vlastnostem zadané třídy. Pokud pro některý sloupec neexistuje žádná vlastnost, bude vytvořen
  • PDO::FETCH_INTO: aktualizuje existující instanci zadané třídy
  • PDO::FETCH_LAZY: kombinuje PDO::FETCH_BOTH a PDO::FETCH_OBJ
  • PDO::FETCH_NUM: vrátí pole s klíči jako čísly sloupců
  • PDO::FETCH_OBJ: vrátí anonymní objekt s vlastnostmi odpovídajícími názvům sloupců
V praxi budete obvykle potřebovat tři: FETCH_ASSOC, FETCH_CLASS a FETCH_OBJ. Chcete-li zadat formát dat, použijte následující syntaxi:
$STH->setFetchMode(PDO::FETCH_ASSOC);
Můžete jej také nastavit přímo při volání metody ->fetch().

FETCH_ASSOC

Tento formát vytváří asociativní pole s názvy sloupců jako indexy. Mělo by to být známé těm, kteří používají rozšíření mysql/mysqli.
# protože se jedná o běžný dotaz bez zástupných symbolů, # můžete okamžitě použít metodu query() $STH = $DBH->query("SELECT jméno, adr, město od lidí"); # nastavit režim načítání $STH->setFetchMode(PDO::FETCH_ASSOC); while($row = $STH->fetch()) ( echo $row["name"] . "\n"; echo $row["addr"] . "\n"; echo $row["city"] . "\n" ;)
Cyklus while() bude iterovat celý výsledek dotazu.

FETCH_OBJ

Tento typ získávání dat vytváří instanci třídy std pro každý řádek.
# vytvořit dotaz $STH = $DBH->query("VYBRAT jméno, adr, město od lidí"); # vyberte režim načítání $STH->setFetchMode(PDO::FETCH_OBJ); # vytiskni výsledek while($row = $STH->fetch()) ( echo $row->name . "\n"; echo $row->addr. "\n"; echo $row->city ." \ n" ;)

FETCH_CLASS

Při použití třídy fetch_class se data zapisují do instancí zadané třídy. V tomto případě jsou hodnoty přiřazeny vlastnostem objektu PŘED voláním konstruktoru. Pokud vlastnosti s názvy odpovídajícími názvy sloupců neexistují, budou vytvořeny automaticky (s rozsahem public).

Pokud vaše data vyžadují povinné zpracování ihned po jejich přijetí z databáze, lze je implementovat v konstruktoru třídy.

Vezměme si například situaci, kdy potřebujete skrýt část adresy bydliště osoby.
třída tajná_osoba ( public $name; public $addr; public $city; public $other_data; function __construct($other = "") ( $this->addr = preg_replace("//", "x", $this-> addr); $this->other_data = $other; ))
Při vytváření objektu musí být všechna malá písmena latinky nahrazena x. Pojďme zkontrolovat:
$STH = $DBH->query("VYBRAT jméno, adr, město od lidí"); $STH->setFetchMode(PDO::FETCH_CLASS, "tajná_osoba"); while($obj = $STH->fetch()) ( echo $obj->addr; )
Pokud adresa v databázi vypadá jako „5 Rosebud“, výstup bude „5 Rxxxxxx“.

Samozřejmě někdy budete chtít, aby byl konstruktor zavolán PŘED přiřazením hodnot. PDO to také umožňuje.
$STH->setFetchMode(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, "tajná_osoba");
Nyní, když jste předchozí příklad doplnili o další možnost (PDO::FETCH_PROPS_LATE), adresa se nezmění, protože po zapsání hodnot se nic neděje.

Nakonec, pokud je to nutné, můžete předat argumenty konstruktoru přímo při vytváření objektu:
$STH->setFetchMode(PDO::FETCH_CLASS, "tajná_osoba", array("stuff"));
Každému objektu můžete dokonce předat různé argumenty:
$i = 0; while($rowObj = $STH->fetch(PDO::FETCH_CLASS, "tajná_osoba", pole($i))) ( // udělejte něco $i++; )

Další užitečné metody

I když tento článek nemůže (a ani se nesnaží) pokrýt všechny aspekty práce s PDO (je to obrovský modul!), nelze bez zmínky vynechat několik následujících funkcí.
$DBH->lastInsertId();
Metoda ->lastInsertId() vrací id posledního vloženého záznamu. Stojí za zmínku, že se vždy volá na databázový objekt (v tomto článku nazývaný $DBH), a nikoli na objekt s výrazem ($STH).
$DBH->exec("SMAZAT OD lidí, KDE 1"); $DBH->exec("SET time_zone = "-8:00"");
Metoda ->exec() se používá pro operace, které nevrací žádná data kromě počtu jimi ovlivněných záznamů.
$safe = $DBH->quote($unsafe);
Metoda ->quote() umísťuje uvozovky do dat řetězce, aby bylo bezpečné je používat v dotazech. Užitečné, pokud nepoužíváte připravené výpisy.
$rows_affected = $STH->rowCount();
Metoda ->rowCount() vrací počet záznamů, které se účastnily operace. Bohužel tato funkce nefungovala s SELECT dotazy až do PHP 5.1.6. Pokud není možné aktualizovat verzi PHP, lze počet záznamů získat takto:
$sql = "VYBRAT POČET(*) OD lidí"; if ($STH = $DBH->query($sql)) ( # zkontrolujte počet záznamů if ($STH->fetchColumn() > 0) ( # zde proveďte úplný výběr, protože data byla nalezena! ) else ( # vytisknout zprávu, že nebyla nalezena žádná data vyhovující požadavku) )

Závěr

Doufám, že tento materiál pomůže některým z vás migrovat z rozšíření mysql a mysqli.