Ablakok.  Vírusok.  Jegyzetfüzetek.  Internet.  hivatal.  Segédprogramok.  Drivers

metacímkék (5)

Időnként látok kérdéseket az adatbázishoz való csatlakozással kapcsolatban.
A legtöbb válasz nem az, hogy én hogyan csinálom, vagy egyszerűen nem tudok helyesen válaszolni. Akárhogyan is; Soha nem gondoltam rá, mert ahogy csinálom, az nekem bevált.

De itt van egy őrült gondolat; Lehet, hogy mindent rosszul csinálok, és ha igen; Nagyon szeretném tudni, hogyan kell megfelelően csatlakozni az adatbázishoz MySQL adatok Val vel PHP használatávalés OEM, és tegye elérhetővé.

Így csinálom:

Először is itt az enyém fájlszerkezet (levágni) :

Public_html/ * index.php * inicializálás/ -- load.initialize.php -- configure.php -- sessions.php

index.php
A legtetején igénylem ("initialize/load.initialize.php"); ,

load.initialize.php

# webhelykonfigurációk igényelnek("configure.php"); # csatlakozni az adatbázishoz igényel ("root/somewhere/connect.php"); // ez a fájl a public_html-en kívül van a nagyobb biztonság érdekében. # include classes foreach (glob("assets/classes/*.class.php") mint $class_filename)( include($class_filename); ) # include functions foreach (glob("assets/functions/*.func.php") mint $func_filename)( include($func_filename); ) # handle sessions needs("sessions.php");

Tudom, hogy van jobb vagy helyesebb módja az osztályok felvételének, de nem emlékszem, mi volt az. Még nem volt időm utánanézni, de azt hiszem, valami az automatikus betöltésről szól. valami hasonló...

configure.php
Itt alapvetően csak felülírok néhányat php.ini-tulajdonságokat, és végezzen más globális beállításokat a webhelyen

connect.php
Beállítottam a kapcsolatot egy osztályhoz, hogy más osztályok is megtehessék kiterjed ez...

Osztály connect_pdo ( védett $dbh; nyilvános függvény __construct() ( try ( $db_host = " "; // gazdagépnév $db_name = " "; // adatbázisnév $db_user = " "; // felhasználónév $user_pw = " "; // jelszó $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"); // minden sql kérés visszaadása UTF-8 formátumban ) catch (PDOException $err) ( echo "ártalmatlan hibaüzenet, ha a kapcsolat meghiúsul"; $err->getMessage() ."
"; file_put_contents("PDOErrors.txt",$err, FILE_APPEND); // írjon néhány részletet egy hibanaplóba a public_html die()-n kívül; // kapcsolat megszakítása ) ) public function dbh() ( return $this->dbh ; ) ) # helyezze az adatbáziskezelőt egy var-ba a könnyebb hozzáférés érdekében $con = new connect_pdo(); $con = $con->dbh(); //

Ez az a hely, ahol valóban úgy gondolom, hogy van hová fejlődni, mivel nemrég kezdtem el tanulni az OOP-t, és a mysql helyett PDO-t használtam.
Így csak követtem néhány kezdő oktatóanyagot, és különféle dolgokat próbáltam ki...

sessions.php
A normál munkamenetek kezelésén kívül néhány osztályt is inicializálok a munkamenetben, így:

If (!isset($_SESSION["sqlQuery"]))( session_start(); $_SESSION["sqlQuery"] = new sqlQuery(); )

Így ez az osztály mindenhol elérhető. Lehet, hogy nem jó gyakorlat(?)...
Egyébként ez az, amit ez a megközelítés lehetővé tesz számomra mindenhol:

Echo $_SESSION["sqlQuery"]->getAreaName("megye",9); // kimenetek: Aust-Agder (a megye neve ezzel az azonosítóval az adatbázisban)

bennem osztály sqlQuery, amely kiterjeszti az enyémet Osztály connect_pdo , van egy nyilvános getAreaName függvényem, amely kezeli a kérést az adatbázisomban.
Elég ügyes szerintem.

Úgy működik, mint a karikacsapás
Szóval alapvetően így csinálom.
Valahányszor le kell kérnem valamit a DB-mből egy osztályból, valami ehhez hasonlót csinálok:

$id = 123; $sql = "Válasszon ki bármit FROM MyTable WHERE id = :id"; $qry = $con->prepare($sql); $qry -> bindParam(":id", $id, PDO::PARAM_INT); $qry -> execute(); $get = $qry->fetch(PDO::FETCH_ASSOC);

Mivel a kapcsolatot beszúrom egy változóba belül connect_pdo.php, csak utalok rá, és már megy is. Működik. A várt eredményeket kapom...

De ettől függetlenül; Nagyon hálás lennék, ha megmondanák, hogy elmegyek innen. Ehelyett változtatnom kellene azon területeken, amelyeken változtathatnék vagy kellene javítanom stb.

nagyon szeretnék tanulni...

Válaszok

$dsn = "mysql:host=sajat_hoszt_neve;dbname=sajat_db_neve_itt"; // hosztnév és adatbázisnév meghatározása $username = "te"; // a felhasználónév meghatározása $pwd="a_jelszó"; // jelszó try ( $db = new PDO($dsn, $username, $pwd); ) catch (PDOException $e) ( $error_message = $e->getMessage(); echo "ez jelenik meg, mert hibát találtunk "; kilépés(); )

Nemrég magamtól is eljutottam egy hasonló válaszhoz/kérdéshez. Ezt csináltam, hátha valakit érdekel:

args = func_get_args(); ) nyilvános függvény __call($method, $args) ( if (üres($this->db)) ( $Ref = new \ReflectionClass("\PDO"); $this->db = $Ref->newInstanceArgs($ this->args); ) return call_user_func_array(array($this->db, $method), $args); ) )

A híváshoz csak ezt a sort kell módosítania:

$DB = new \Library\PDO(/* normál argumentumok */);

És írja be a tippet, ha használja (\Library\PDO$DB).

Ez valóban hasonló az elfogadott válaszhoz és a tiédhez; azonban jelentős előnye van. Fontolja meg ezt a kódot:

$DB = new \Library\PDO(/* args */); $STH = $DB->prepare("SELECT * FROM felhasználók WHERE user =?"); $STH->végrehajtás(tömb(25)); $Felhasználó = $STH->fetch();

Bár normál PDO-nak tűnhet (csak a \Library\ módosítja), valójában nem inicializálja az objektumot, amíg meg nem hívja az első metódust, bármelyik is az. Ez leegyszerűsíti, mivel egy PDO objektum létrehozása kissé költséges. Ez egy átlátszó osztály, vagy mi a neve Ghost, egy űrlap. A $DB-t úgy kezelheti, mint egy normál PDO-példányt, átadhatja, elvégezheti ugyanazokat a műveleteket stb.

Azt javaslom, hogy ne használja a $_SESSION-t a db-kapcsolat globális eléréséhez.

Több dolog közül egyet tehet (sorrendben legrosszabb a legjobbnak gyakorló):

  • A $dbh elérése a globális $dbh használatával a függvényeken és osztályokon belül
  • Használjon singleton registry-t, és érje el globálisan, például:

    $registry = MyRegistry::getInstance(); $dbh = $nyilvántartás->getDbh();

    Mutassa be az adatbáziskezelőt a számára szükséges osztályokba:

    Class MyClass ( nyilvános függvény __construct($dbh) ( /* ... */ ) )

Ez azonban egy kicsit fejlettebb, és több "kábelezést" igényel előlap nélkül. Ezért, ha a függőségi befecskendezés túl nehéz az Ön számára, használjon egyszemélyes nyilvántartást a globális változók gyűjteménye helyett.

Cél

Ahogy látom, ebben az esetben kettős a célod:

  • adatbázisonként egyetlen/több kapcsolat létrehozása és karbantartása
  • győződjön meg arról, hogy a kapcsolat megfelelően van beállítva

Megoldás

$szolgáltató = function() ( $példány = new PDO("mysql:......;charset=utf8", "username", "password"); $példány->setAttribute(PDO::ATTR_ERRMODE, PDO: :ERRMODE_EXCEPTION); $példány->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); return $példány; ); $gyári = new StructureFactory($szolgáltató);

Majd egy másik fájlban vagy lent ugyanabban a fájlban:

$valami = $gyári->create("Valami"); $foobar = $gyári->létrehozás("Foobar");

Maga a gyár valahogy így néz ki:

Class StructureFactory ( védett $szolgáltató = null; védett $kapcsolat = null; nyilvános függvény __construct(hívható $szolgáltató) ( $this->provider = $szolgáltató; ) public function create($name) ( if ($this->connection = == null) ( $this->connection = call_user_func($this->provider); ) return new $name($this->connection); ) )

Így lehet egy olyan központosított struktúra, amely biztosítja, hogy a kapcsolat csak szükség esetén jön létre. Ezenkívül megkönnyítené a PHP egységtesztjét és karbantartását, és ez a kód fordított perjeleket adna a következő karakterekhez: \x00 , \n , \r , \ , " , " és \x1a . Adja meg a bemeneti értékeket paraméterként, hogy minimalizálja az SQL injekció lehetőségét.

  • A legfejlettebb módszer az OEM használata.
  • Remélem, ez segít.

    Fontolja meg a következő lekérdezést:

    $iId = mysql_real_escape_string("1 VAGY 1=1"); $sSql = "SELECT * FROM table WHERE id = $iId";

    A mysql_real_escape_string() itt nem véd. Ha szimpla idézőjeleket ("") használ a változók körül a lekérdezésben, ez védi meg ettől. Íme az alábbi megoldás:

    $iId = (int) mysql_real_escape_string("1 VAGY 1=1"); $sSql = "SELECT * FROM table WHERE id = $iId";

    Erre a kérdésre jó válaszok vannak.

    Azt javaslom, hogy az OEM használata a legjobb megoldás.

    Szerkesztés:

    A mysql_real_escape_string() a PHP 5.5.0-s verziója óta elavult. Használjon mysqli-t vagy PDO-t.

    A mysql_real_escape_string() alternatívája az

    Karakterlánc mysqli_real_escape_string (mysqli $link , string $escapestr)

    Példa:

    $iId = $mysqli->real_escape_string("1 VAGY 1=1"); $mysqli->query("SELECT * FROM tábla WHERE id = $iId");

    Adatbázis kapcsolatállítsa be az OEM osztály példányának létrehozásakor. Nem számít, melyik illesztőprogramot szeretné használni; Mindig az OEM osztályt kell használnia. Konstruktora paramétereket vesz fel az adatbázis-forrás megadásához (más néven DSN), valamint opcionális paramétereket a felhasználónévhez és a jelszóhoz.

    MySQL kapcsolat:

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

    Ha bármilyen kapcsolódási hiba történik, kivételt dob ​​a rendszer: egy PDOException osztályú objektum. Megkaphatja, ha kezelni akarja ezt a helyzetet, vagy hagyhatja a globális kivételkezelőre, amely a set_exception_handler() segítségével van beállítva.

    Csatlakozási hibakezelés:

    try ( $dbh = new PDO("mysql:host=localhost;dbname=test", $user, $pass); foreach($dbh->query('SELECT * from FOO') as $row) ( print_r($ sor); ) $dbh = null; ) catch (PDOException $e) ( die("Hiba! Ez az. Megérkeztünk... ".$e->getMessage()); )

    Figyelem: Ha nem észleli a PDO konstruktor által kiadott kivételt, a zend motor alapértelmezett művelete a szkript leállítása és a visszakövetés megjelenítése. Ez a szar kiadja az adatbázissal való kommunikáció minden intim részletét. Azaz részletes adatbázis-kapcsolati adatokat jelenít meg, beleértve a felhasználónevet és a jelszót!Önön múlik, hogy ezt a kivételt vagy kifejezetten (egy nyilatkozaton keresztül) elkapja-e próbáld elkapni), vagy implicit módon a set_exception_handler() segítségével.

    Sikeres adatbázis-csatlakozás után a PDO objektumpéldány élettartama alatt aktív marad. A kapcsolat bezárásához meg kell semmisíteni az objektumot, ügyelve arra, hogy a rá vonatkozó fennmaradó hivatkozásokat eltávolítsák – ezt úgy teheti meg, hogy az objektumot tartalmazó változóhoz NULL értéket rendel. Ha ezt kifejezetten nem teszi meg, akkor a PHP automatikusan lezárja a kapcsolatot, amikor a szkript befejeződik.

    A kapcsolat lezárása:

    $dbh = new PDO("mysql:host=localhost;dbname=test", $user, $pass); // Itt teszünk valamit: ... // És most figyelem: vége a kapcsolatnak! $dbh = null;

    Sok webalkalmazás számára előnyös, ha állandó kapcsolatot létesít az adatbázis-kiszolgálókkal. Az állandó kapcsolatok nem záródnak be, amikor a szkript kilép, hanem a gyorsítótárban tárolódnak, és újra felhasználhatók, amikor egy másik szkript ugyanazokat a kapcsolati hitelesítő adatokat használó kapcsolatokat kér. Az állandó kapcsolat gyorsítótárának köszönhetően elkerülhető az új kapcsolat létrehozása minden alkalommal, amikor a szkriptnek beszélnie kell az adatbázissal, ami gyorsabb webalkalmazásokat eredményez.

    Állandó kapcsolat beállítása:

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

    Tartsd észben: Ha állandó kapcsolatot szeretne használni, be kell állítania PDO::ATTR_PERSISTENT az illesztőprogram-beállítások tömbjében, amely átadásra kerül a PDO osztály konstruktorának. Ha ezt az attribútumot a PDO::setAttribute() segítségével állítja be az objektum példányosítása után, az illesztőprogram nem fog állandó társításokat használni. Ezenkívül ebben az esetben nem tudja kiterjeszteni a PDOStatement osztályt bizonyos igényeire, pl. nem telepíthető: PDO::ATTR_STATEMENT_CLASS

    Ma egy cikksorozatot indítok erről OEM, amelyben elemezzük mi az OEM miért van szükségünk rá és hogyan használjuk.

    Bizonyára sokan hallották már a rövidítést OEM, de kevesen tudják, mi az. Beszéljünk erről ma.

    Mi az az OEM?

    PDO (PHP adatobjektumok)- ez egyszerű felület, amely lehetővé teszi számunkra, hogy elvonatkoztassunk egy adott adatbázistól. A legjobb, ha példával mutatjuk be.

    mysql_connect($host, $felhasználó, $pass); // MySQL
    mysql_select_db($db);

    sqlite_open($db); // sqlite

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

    A fenti kód három különböző adatbázishoz való csatlakozás módját mutatja be: MySQL, sqliteÉs PostgreSQL. Mint látható, az egyes adatbázisok funkciói eltérőek.

    Ugyanez vonatkozik más műveletekre is. Például adatok lekérése adatbázisból.

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

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

    Miért van szükség OEM?

    Képzeld el, hogy hatalmas adatbázisunk van PostgreSQL, és úgy döntöttünk, hogy ezt megváltoztatjuk MySQL. Nagyon sok kódot kell átírnunk, és valószínűleg ez sem megy hibák nélkül. Megoldani ezt a problémát, és van OEM, ami lehetővé teszi, hogy ne függjünk egy adott alaptól.

    Nézzük meg, hogyan tudunk most kapcsolódni.

    $db = new PDO("mysql:host=$host;dbname=$db", $felhasználó, $pass); // MySQL
    $db = new PDO("sqlite:host=$host;dbname=$db", $felhasználó, $pass); // sqlite
    $db = new PDO("pgsql:host=$host;dbname=$db", $felhasználó, $pass); // PostgreSQL

    Ahogy a fenti kódból is látszik, ebben a három kapcsolatban csak az adatbázis nevét tartalmazó sor változik, a többi ugyanaz.

    Valaminek kiválasztásához ezt írhatjuk:

    $db->exec($sql);

    Minden! A lekérdezés attól függetlenül megtörténik, hogy milyen adatbázisunk van.

    Támogatás

    OEM elérhető ekkortól PHP 5.1. Hogy "elfelejtsük", melyik adatbázist használjuk, mindent megtesznek helyettünk járművezetők. Aktiválásukhoz lépjen a fájlhoz php.iniés keresse meg a következővel kezdődő sorokat extension=php_pdo_írja be az adatbázis nevét, és törölje a megjegyzéseket.

    Ennyi a bevezető cikkhez, és a következőben kezdjük megérteni, hogyan kell használni az OEM.


    2018. június 3 Andrej Csernisov Fordítási oktatóanyag 1737 0

    A PDO a PHP Data Objects rövidítése: ez egy PHP kiterjesztése az objektumokat használó adatbázisokkal való munkavégzéshez. Egyik előnye abban rejlik, hogy nincs közvetlenül egy adott adatbázishoz kötve: felülete több különböző környezet elérését teszi lehetővé, többek között: MySQL, SQLite, PostgreSQL, Microsoft SQL Server.

    Ennek az útmutatónak az a célja, hogy teljes áttekintést nyújtson az OEM-ről, és lépésről lépésre elvezesse az olvasót az adatbázis létrehozásától és csatlakozásától a legmegfelelőbb lekérési módszerek kiválasztásáig, bemutatva az előkészített lekérdezések létrehozásának módját és a lehetséges hibamódok leírását.

    Hozzon létre egy teszt adatbázist és táblázatot

    Először is létrehozunk egy adatbázist:

    ADATBÁZIS LÉTREHOZÁSA szoláris_rendszer; MINDEN KIVÁLTSÁGOT BEADNI A solar_system.* A "testuser"@"localhost" SZÁMÁRA "tesztjelszó" AZONOSÍTJA;

    A testuser felhasználónak minden jogosultságot megadtunk a solar_system adatbázisban a testpassword jelszó használatával. Most hozzunk létre egy táblázatot, és töltsük fel néhány információval:

    naprendszer HASZNÁLATA; TÁBLÁZAT-bolygók LÉTREHOZÁSA (id TINYINT(1) ELŐJELZÉS NEM NULL AUTO_INCREMENT, ELSŐDLEGES KULCS(id), név VARCHAR(10) NOT NULL, szín VARCHAR(10) NOT NULL); INSERT INTO bolygók(név, szín) ÉRTÉKEK("föld", "kék"), ("mars", "piros"), ("jupiter", "furcsa");

    A DSN-kapcsolat leírása (adatforrás neve)

    Most, hogy van adatbázisunk, be kell állítanunk a DSN-t. A DSN az adatforrás neve rövidítése, és az adatbázishoz való kapcsolódáshoz szükséges információk halmaza, a DSN karakterlánc formájú. A szintaxis attól függ, hogy melyik adatbázishoz szeretnénk csatlakozni, de mivel MySQL/MariaDB-t használunk, a következőket kell megadnunk:

    • A csatlakozáshoz használt illesztőprogram típusa;
    • Annak a gazdagépnek a neve, amelyen az adatbázis fut;
    • Csatlakozási port (opcionális);
    • Adatbázis név;
    • Kódolás (opcionális).

    A karakterlánc formátum esetünkben a következő lesz (a $dsn változóban tároljuk):

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

    Először is beállítjuk az adatbázis előtagot vagy adatbázis előtagot. Ebben az esetben, mivel egy olyan adatbázishoz csatlakozunk, mint a MySQL/MariaDB, mysql-t használunk. Ezután kettősponttal választottuk el az előtagot a sor többi részétől, és minden következő szakaszt pontosvessző választ el a többitől.

    A következő két részben beállítjuk a gazdagép nevét, amelyen az adatbázis fut, és a csatlakozáshoz használt portot. Ha nincs megadva port, akkor a rendszer az alapértelmezett portot használja, jelen esetben a 3306-ot. Közvetlenül az adatbázis nevének karakterkészlete után.

    PDO objektum létrehozása

    Most, hogy a DSN-ünk készen áll, megkezdjük a PDO objektum létrehozását. A PDO konstruktor a DSN karakterláncot használja első paraméterként, az adatbázis felhasználónevet második paraméterként, a jelszót harmadikként, és egy opcionális beállítási tömböt negyedikként.

    $options = [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC ]; $pdo = new PDO($dsn, "testuser", "testpassword", $options);

    A beállítások az objektum létrehozása után is megadhatók a SetAttribute() metódussal:

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

    PDO hibaviselkedés konfigurálása

    Nézzünk meg néhány lehetőséget a PDO::ATTR_ERRMODE számára. Ezek az opciók rendkívül fontosak, mert meghatározzák az OEM viselkedését hiba esetén. Lehetséges opciók:

    PDO::ERRMODE_SILENT

    Alapértelmezett beállítás. Az OEM csak egy hibakódot és egy hibaüzenetet ad. Ezeket az errorCode() és errorInfo() metódusokkal lehet beszerezni.

    PDO::ERRMODE_EXCEPTION

    Ezt az opciót véleményem szerint ajánlott használni. Segítségével a PDO a hibakód és információ kiadása mellett egy PDOException-t is dob, ami megszakítja a szkript végrehajtását, illetve PDO tranzakcióknál is hasznos (ezeket kicsit később megnézzük).

    PDO::ERRMODE_WARNING

    Ezzel az opcióval a PDO a PDO::ERRMODE_SILENT-hez hasonlóan hibakódot és üzenetet ad ki, de megjelenik egy FIGYELMEZTETÉS figyelmeztetés is, amely nem zárja le a szkriptet.

    Az alapértelmezett mintavételi módszer beállítása

    Egy másik fontos beállítást a PDO::DEFAULT_FETCH_MODE konstans vezérel. Lehetővé teszi a lekérdezés eredményeinek lekéréséhez használt fetch() metódus alapértelmezett viselkedésének konfigurálását. Íme a leggyakrabban használt lehetőségek:

    PDO::FETCH_BOTH

    Használatakor az eredmények egész számokkal és oszlopnevekkel is indexelve lesznek. Ha egy módszerben használjuk, hogy sorokat kapjunk a bolygótáblázatból, akkor a következő eredményeket kapjuk:

    $stmt = $pdo->query("SELECT * FROM bolygók"); $eredmények = $stmt->fetch(PDO::FETCH_BOTH); Tömb ( => 1 => 1 => föld => föld => kék => kék)

    PDO::FETCH_ASSOC

    Ezzel az állandóval az eredmények egy asszociatív tömbbe íródnak, ahol minden kulcs egy oszlop neve lesz, és minden érték egy adott értéket jelöl a sorban:

    $stmt = $pdo->query("SELECT * FROM bolygók"); $eredmények = $stmt->fetch(PDO::FETCH_ASSOC); Tömb ( => 1 => föld => kék)

    PDO::FETCH_NUM

    A PDO::FETCH_NUM konstans használatával egy 0-indexelt tömböt kapunk:

    Tömb ( => 1 => föld => kék)

    PDO::FETCH_COLUMN

    Ez az állandó akkor hasznos, ha csak az értékeket kapja meg egy oszlopból, és a módszer az összes eredményt egy egyszerű egydimenziós tömbben adja vissza. Például itt van egy lekérdezés:

    $stmt = $pdo->query("SELECT név bolygókból");

    Ennek eredményeként:

    Tömb ( => föld => mars => Jupiter)

    PDO::FETCH_KEY_PAIR

    Ez az állandó akkor hasznos, ha két oszlopból kell értékeket kapnia. A fetchAll() metódus asszociatív tömbként adja vissza az eredményeket. Ebben a tömbben az első oszlopból származó adatok kulcsként, a második oszlopból pedig értékekként lesznek megadva:

    $stmt = $pdo->query("SELECT név, szín FROM bolygókról"); $eredmény = $stmt->fetchAll(PDO::FETCH_KEY_PAIR);

    Ennek eredményeként:

    Array ( => kék => piros => furcsa)

    PDO::FETCH_OBJECT

    A PDO::FETCH_OBJECT konstans használatakor egy névtelen objektum jön létre minden egyes lekért sorhoz. A (nyilvános) tulajdonságai megegyeznek az oszlopok elnevezésével, és a lekérdezés eredményei értékként kerülnek felhasználásra. Ha ezt a módszert használja ugyanarra a lekérdezésre, mint fent, a következő eredményt kapja:

    $eredmények = $stmt->fetch(PDO::FETCH_OBJ); stdClass Object ( => föld => kék)

    PDO::FETCH_CLASS

    Az előző konstanshoz hasonlóan hozzárendeli az oszlopértékeket az objektum tulajdonságaihoz, de ebben az esetben be kell állítani egy meglévő osztályt, amelyet az objektum létrehozásához használunk. A bemutatáshoz először létrehozunk egy osztályt:

    Class Planet ( privát $név; privát $szín; nyilvános függvény setName($bolygó_neve) ( $this->name = $bolygó_neve; ) nyilvános függvény setColor($planet_color) ( $this->color = $planet_color; ) nyilvános függvény getName () ($this->name; ) nyilvános függvény getColor() ($this->color; ) )

    Hagyjuk figyelmen kívül a kód egyszerűségét, vessünk egy pillantást az általunk létrehozott Planet osztályra: tulajdonságaiban van privát, és az osztálynak nincs konstruktora. Most próbáljuk meg az eredményeket.

    Ha a fetch()-et PDO::FETCH_CLASS-szal használja, a setFetchMode() metódust kell használnia az objektumon, mielőtt megpróbálna lekérni adatokat, például:

    $stmt = $pdo->query("SELECT név, szín FROM bolygókról"); $stmt->setFetchMode(PDO::FETCH_CLASS, "Planet");

    A PDO::FETCH_CLASS állandót a setFetchMode() metódus első argumentumaként, második argumentumként pedig az objektum létrehozásához használt osztály nevét (esetünkben "Planet") állítjuk be. Most futtassuk le a kódot:

    $bolygó = $stmt->fetch();

    Be kell szereznie egy Planet objektumot:

    Var_dump($bolygó); Bolygóobjektum ( => föld => kék)

    Figyelje meg, hogy a lekérdezésből leolvasott értékek hogyan lettek hozzárendelve az objektum megfelelő jellemzőihez, még akkor is, ha azok privátak.

    Jellemzők hozzárendelése az objektum létrehozása után

    A "Planet" osztálynak nem volt konkrét konstruktora, így nem volt probléma a jellemzők hozzárendelésével; de mi van akkor, ha az osztálynak van egy konstruktora, ahol beállítják és módosítják a karakterisztikákat? Mivel az értékek a konstruktor futása előtt vannak hozzárendelve, felülíródnak.

    A PDO segít megadni a FETCH_PROPS_LATE állandót: használatkor az értékeket az objektum létrehozása után rendeli hozzá a rendszer. Példa:

    Class Planet ( privát $név; privát $szín; nyilvános függvény __construct($name = hold, $color = szürke) ( $this->name = $name; $this->color = $color; ) nyilvános függvény setName($ bolygó_neve) ( $ez->név = $bolygó_neve; ) nyilvános függvény setColor($bolygó_szín) ( $ez->szín = $bolygó_szín; ) nyilvános függvény getName() ($ez->név visszaadása; ) nyilvános függvény getColor() ($ez->szín visszaküldése; ) )

    Módosítottuk Planet osztályunkat egy olyan konstruktor létrehozásával, amely két argumentumot vesz fel: név név és szín . Ezek az argumentumok alapértékekkel rendelkeznek: hold és szürke, ami azt jelenti, hogy ha nem adnak meg más értékeket, akkor ezek lesznek beállítva.

    Ebben az esetben, ha nem használjuk a FETCH_PROPS_LATE -t, akkor függetlenül attól, hogy milyen értékek kerülnek lekérésre az adatbázisból, minden tulajdonság alap marad, mert az objektum létrehozása során felülíródnak. Ennek teszteléséhez futtassa a következő lekérdezést:

    $stmt = $pdo->query("SELECT név, szín FROM szoláris_rendszer WHERE név = "föld"); $stmt->setFetchMode(PDO::FETCH_CLASS, "Planet"); $bolygó = $stmt->fetch();

    Most fontolja meg a Planet objektumot, és ellenőrizze, hogy mely értékek egyeznek a jellemzőivel:

    Var_dump($bolygó); object(Planet)#2 (2) ( ["név":"Bolygó":privát]=> string(4) "hold" ["szín":"Bolygó":privát]=> string(4) "szürke" )

    Ahogy az várható volt, az adatbázisból lekért értékeket felülírták az alapértelmezett értékekkel. Most bemutatjuk a problémamegoldást a FETCH_PROPS_LATE konstans használatával (és ugyanazzal a lekérdezéssel, mint az előző):

    $stmt->setFetchMode(PDO::FETCH_CLASS|PDO::FETCH_PROPS_LATE, "Planet"); $bolygó = $stmt->fetch(); var_dump($bolygó); object(Planet)#4 (2) ( ["név":"Bolygó":privát]=> string(5) "föld" ["szín":"Bolygó":privát]=> string(4) "kék" )

    Végül a kívánt eredményt kapjuk. De mi van akkor, ha az osztálykonstruktornak nincsenek alapértékei, és ezeket be kell állítani? Most már egyszerűbb: a setFetchMode() metódussal az osztálynév után harmadik argumentumként beállíthatjuk a konstruktor paramétereit tömb formában. Például változtassuk meg a konstruktort:

    Class Planet ( privát $név; privát $szín; nyilvános függvény __construct($name, $color) ( $ez->név = $név; $ez->szín = $szín; ) [...] )

    A konstruktor argumentumok megadása most kötelező, ezért futtatjuk:

    $stmt->setFetchMode(PDO::FETCH_CLASS|PDO::FETCH_PROPS_LATE, "Bolygó", ["hold", "szürke"]);

    Ebben az esetben az általunk megadott paraméterek csak az objektum hibamentes működéséhez szükséges alapértékek: felülíródnak az adatbázisból származó értékekkel.

    Több objektum lekérése

    Természetesen egyszerre több eredményt is kaphatunk objektumok formájában, akár a fetch() metódussal, akár hurkolással:

    While ($planet = $stmt->fetch()) ( // Csinálj valamit az eredményekkel )

    Vagy az összes eredményt egyszerre. Ebben az esetben, ahogy korábban említettük, a fetchAll() metódus használatakor nem a metódus futtatása előtt kell megadnia a lekérési módot, hanem a futás pillanatában:

    $stmt->fetchAll(PDO::FETCH_CLASS|PDO_FETCH_PROPS_LATE, "Bolygó", ["hold", "szürke"]);

    PDO::FETCH_INTO

    Ennek az állandónak a használatakor a PDO nem hoz létre új objektumot, hanem egy meglévő jellemzőit frissíti, de csak akkor, ha az nyilvános, vagy ha az objektumon belül a __set() metódust használjuk.

    Közvetlen kérésre készült

    A PDO-nak két módja van a lekérdezések kezelésére: közvetlen lekérdezések és robusztusabb – előkészített lekérdezések.

    Közvetlen kérések

    A közvetlen lekérdezések használatának két fő módja van: query() és exec() . Az első egy PDOStatemnt objektumot hoz létre, amely a fetch() vagy fetchAll() metódusokon keresztül érhető el: ha olyan esetekben használjuk őket, amikor a tábla nem változik, például SELECT .

    A második metódus ehelyett a lekérdezés által módosított sor számát adja vissza: sorokat cserélő esetekben használjuk, például INSERT , DELETE vagy UPDATE . A közvetlen lekérdezéseket csak olyan esetekben szabad használni, amikor a lekérdezésekben nincsenek változók, és nem fér kétség a metódus biztonságosságához.

    Előkészített lekérdezések

    A PDO támogatja a kétlépéses előkészített lekérdezéseket is: hasznosak, ha változók vannak a lekérdezésekben, és általában biztonságosabbak, mert a előkészítés() metódus elvégzi helyettünk az összes szükséges műveletet. Vessünk egy pillantást a változók használatára. Képzeljük el, hogy egy bolygó jellemzőit szeretnénk beilleszteni a Bolygók táblázatba. Először készítsünk egy lekérdezést:

    $stmt = $pdo->prepare("INSERT INTO planets(name, color) VALUES(?, ?)");

    Mint korábban említettük, a preparat() metódust használjuk, amely egy SQL-lekérdezést vesz fel argumentumként, a változók ideiglenes értékeit használva. Az ideiglenes értékek kétféleek lehetnek: pozíciós és névleges.

    Helyzeti

    Használata? pozíciós ideiglenes értékek, a kód tömörebb, de az execute() metódus argumentumaként megadott tömbben az oszlopnevekkel megegyező sorrendben kell megadnunk a beszúrandó adatokat:

    $stmt->execute([$bolygó->név, $bolygó->szín]);

    Névleges

    A megnevezett helyőrzők ideiglenes értékeinek használatával nincs szükségünk konkrét sorrendre, de ennek eredményeként több kódot kapunk. Az execute() metódus futtatásakor az adatokat egy asszociatív tömb formájában kell megadnunk, ahol minden kulcs a használt ideiglenes érték neve, és a hozzá tartozó érték lesz az, amelyik bekerül a lekérdezésbe. Például az előző lekérdezés a következő lesz:

    $stmt = $pdo->prepare("INSERT INTO bolygók(név, szín) VALUES(:név, :szín)"); $stmt->execute(["név" => $bolygó->név, "szín" => $bolygó->szín]);

    Az előkészítés() és az execute() metódus egyaránt használható olyan lekérdezésekhez, amelyek módosítanak vagy egyszerűen lekérnek információkat az adatbázisból. Az első esetben a fent felsorolt ​​fetch metódusokat használjuk az információk megszerzéséhez, a másodikban pedig a rowCount() metódust.

    bindValue() és bindParam() metódusok

    A bindValue() és bindParam() metódusok is használhatók a kérésbe beszúrandó értékek megadására. Az első az adott változó értékét a lekérdezés elkészítésekor használt pozíciós vagy megnevezett ideiglenes értékhez köti. Példaként az előző esetet vesszük:

    $stmt->bindValue("név", $bolygó->név, PDO::PARAM_STR);

    A $planet->name értékét egy ideiglenes értékhez kötjük:név . Vegye figyelembe, hogy a bindValue() és a bindParam() metódusokkal is megadhatjuk a változó típusát harmadik argumentumként egy megfelelő PDO konstans segítségével, ebben az esetben a PDO::PARAM_STR .

    Ehelyett a bindParam() használatával a változót egy megfelelő ideiglenes értékhez köthetjük, amelyet a kérés előkészítése során használunk. Vegye figyelembe, hogy ebben az esetben a változó hivatkozáshoz van kötve, és értéke csak ideiglenes értékre változik az execute() metódus futtatásakor. A szintaxis ugyanaz, mint legutóbb:

    $stmt->bindParam("név", $bolygó->név, PDO::PARAM_STR)

    A változót, nem pedig a $planet->name értékét a:névhez kötöttük! Ahogy fentebb említettük, a csere csak az execute() metódus futtatásakor fog megtörténni, így az ideiglenes értéket a változó akkori értékére cseréljük.

    OEM-tranzakciók

    A tranzakciók lehetővé teszik a konzisztencia fenntartását több lekérdezés futtatásakor. Minden lekérdezés "kötegelt" végrehajtásra kerül, és csak akkor releváns az adatbázis szempontjából, ha mindegyik sikeres. A tranzakciók nem működnek minden adatbázissal, és nem minden sql-konstrukcióval, mert némelyikük problémát okoz.

    Extrém és furcsa példaként képzeljük el, hogy a felhasználónak ki kell választania a bolygók listáját, és minden alkalommal, amikor új kiválasztást végez, el kell távolítania az előzőt az adatbázisból, mielőtt beilleszti az újat. Mi van, ha a törlés megtörténik, de a beillesztés nem? Lesz egy felhasználónk bolygók nélkül! A tranzakciókat alapvetően a következőképpen alkalmazzák:

    $pdo->beginTransaction(); try ( $stmt1 = $pdo->exec("TÖRLÉS A bolygókról"); $stmt2 = $pdo->prepare("INSERT INTO planets(name, color) VALUES (?, ?)"); foreach ($bolygók mint $bolygó) ( $stmt2->execute([$planet->getName(), $planet->getColor()]); ) $pdo->commit(); ) catch (PDOException $e) ( $pdo-> visszagörgetés();)

    Először is, a PDO objektumon lévő beginTransaction() metódus letiltja a kérés automatikus véglegesítését, majd a kérések a kívánt sorrendben elindulnak. Ebben a pillanatban, ha PDOException nem történik, a kérések automatikusan átadódnak a commit() metóduson, ellenkező esetben a tranzakciókat a rollBack() metóduson keresztül törlik, és az automatikus véglegesítés visszaáll.

    Így több kérés esetén mindig lesz sorozat. Ez elég nyilvánvaló, de a PDO-tranzakciók csak akkor használhatók, ha a PDO::ATTR_ERRMODE értéke PDO::ERRMODE_EXCEPTION.

    Ha hibát észlel, jelöljön ki egy szövegrészt, és nyomja meg a Ctrl + Enter billentyűket
    OSSZA MEG: