Gir metoder for å forberede uttrykk og arbeide med objekter som kan gjøre deg mer produktiv!

Introduksjon til PUD

"PDO - PHP Data Objects er et databasetilgangslag som gir enhetlige metoder for tilgang til forskjellige databaser."

Det er ikke avhengig av spesifikk databasesyntaks og gjør det enkelt å bytte til en annen databasetype og plattform ved å endre tilkoblingsstrengen i de fleste tilfeller.

Denne leksjonen er ikke en beskrivelse av prosessen med å jobbe med SQL. Den er beregnet på de som bruker utvidelser mysql eller mysqli for å hjelpe dem med å gå over til en kraftigere og mer bærbar PUD.

Databasestøtte

Utvidelsen støtter enhver database som det er en PUD-driver for. Drivere er for øyeblikket tilgjengelige for følgende typer databaser:

  • 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 (Oracle Call Interface)
  • PDO_ODBC (ODBC v3 (IBM DB2, unixODBC og win32 ODBC))
  • PDO_PGSQL (PostgreSQL)
  • PDO_SQLITE (SQLite 3 og SQLite 2)
  • PDO_4D (4D)

For at systemet skal fungere, er det nok å installere bare de driverne som virkelig trengs. Du kan få en liste over drivere tilgjengelig på systemet som følger:

Print_r(PDO::getAvailableDrivers());

Forbindelse

Ulike databaser kan ha litt forskjellige tilkoblingsmetoder. Følgende viser metoder for å koble til flere populære databaser. Du kan se at de tre første er identiske med hverandre, og bare SQLite har en bestemt syntaks.


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

Legg merke til blokken prøve/fange- pakk alltid PUD-operasjoner inn i en blokk prøve/fange og bruk unntaksmekanismen. Vanligvis opprettes bare én tilkobling, vårt eksempel viser flere tilkoblinger for å vise syntaksen. $DBH inneholder et håndtak til databasen og vil bli brukt gjennom veiledningen vår.

Du kan lukke enhver tilkobling ved å sette håndtaket til null.

# Lukk tilkoblingen $DBH = null;

Du kan lære mer om spesifikke alternativer og tilkoblingsstrenger for ulike databaser i PHP.net-dokumentene.

Unntak og PUD

PUD kan bruke unntak for å håndtere feil. Dette betyr at alle PUD-operasjoner skal lukkes i en blokk prøve/fange. PDO kan gi tre nivåer av feil, nivået for feilkontroll velges ved å angi feilkontrollmodusattributtet for databasebeskrivelsen:

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

Uavhengig av det innstilte kontrollnivået, gir en tilkoblingsfeil alltid et unntak og må derfor alltid være innesluttet i en blokk prøve/fange.

PDO::ERRMODE_SILENT

Feilkontrollnivå, satt som standard. På dette nivået genereres feil på samme måte som i utvidelser. mysql eller mysqli. De to andre nivåene av feilkontroll er mer egnet til programmeringsstilen DRY (Ikke Gjenta deg selv).

PDO::ERRMODE_WARNING

På dette nivået av feilkontroll genereres standard PHP-advarsler, og programmet kan fortsette å kjøre. Dette nivået er nyttig for feilsøking.

PDO::ERRMODE_EXCEPTION

Dette nivået av feilkontroll bør brukes i de fleste situasjoner. Unntak er kastet som lar deg håndtere feil pent og skjule data som kan hjelpe noen å hacke seg inn i systemet ditt. Følgende er et eksempel som viser fordelene med ekskluderinger:

# Koble til databasen prøv ( $DBH = new PDO("mysql:host=$host;dbname=$dbname", $user, $pass); $DBH->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION) ; # Feiltastet DELECT i stedet for SELECT! $DBH->prepare("DELECT name FROM people"); ) catch(PDOException $e) ( ekko "Beklager. Men operasjonen kan ikke utføres."; file_put_contents("PDOErrors.txt" , $e->getMessage(), FILE_APPEND); )

Det er en tilsiktet feil i SELECT-setningen her. Dette vil gi et unntak. Unntaket vil sende en beskrivelse av feilen til loggfilen og gi en melding til brukeren.

Sette inn og oppdatere data

Å sette inn nye data eller oppdatere eksisterende data er en av de mest brukte databaseoperasjonene. Ved bruk av PUD dekomponeres den i to trinn. Alt som er beskrevet i dette kapittelet gjelder for begge operasjonene. OPPDATER og SETT INN.


Her er et eksempel på den mest brukte typen datainnsetting:

# STH er "tilstandsbeskrivelsen" $STH = $DBH->prepare("INSERT INTO folks (first_name) verdier ("Cathy")"); $STH->execute();

Selvfølgelig kan du utføre denne operasjonen ved å bruke metoden exec(), mens antall anrop blir mindre med ett. Men det er bedre å bruke den lengre metoden for å få fordelene med forberedte uttrykk. Selv om du bare skal bruke dem én gang, vil forberedte uttalelser hjelpe deg med å forsvare deg mot angrep på systemet ditt.

Forberedte uttrykk

Forberedte setninger er forhåndskompilerte SQL-setninger som kan utføres flere ganger ved kun å sende dataene til serveren. De har den ekstra fordelen av å automatisk fylle malen med data i form av et forsvar mot SQL-injeksjonsangrep.

Du kan bruke forberedte utsagn ved å inkludere maler i SQL-koden. Nedenfor er 3 eksempler: én uten maler, én med navngitte maler, én med navngitte maler.

# ingen maler - åpen for SQL-injeksjonsangrep! $STH = $DBH->("INSERT INTO folks (navn, adr, by) verdier ($name, $addr, $city)"); # navngitte mønstre $STH = $DBH->("INSERT INTO folks (navn, adr, by) verdier (?, ?, ?); # navngitte mønstre $STH = $DBH->("INSERT INTO folkens (navn) , addr , city) verdi (:navn, :addr, :by)");

Du bør unngå å bruke den første metoden. Valget av navngitte eller ikke navngitte mønstre påvirker hvordan du angir dataene for disse uttrykkene.

Ikke navngitte maler

# tilordne variabler til hver mal, indeksert fra 1 til 3 $STH->bindParam(1, $navn); $STH->bindParam(2, $addr); $STH->bindParam(3, $by); # Sett inn en linje $name = "Dima" $addr = "Lizyukov street"; $city = "Moskva"; $STH->execute(); # Sett inn en annen linje $name = "Senya" $addr = "Kommunistisk blindvei"; $city = "Peter"; $STH->execute();

Operasjonen foregår i to trinn. I det første trinnet tilordnes variabler til maler. Deretter tildeles variablene verdier og uttrykket utføres. For å sende neste del av data, må du endre verdiene til variablene og utføre uttrykket på nytt.

Ser litt tungvint ut for uttrykk med mange parametere? Sikkert. Men hvis dataene dine er lagret i en matrise, vil alt være veldig kort:

# Data som skal settes inn $data = array("Monya", "Glem-meg-ikke Avenue", "Zakutaysk"); $STH = $DBH->("INSERT INTO folks (navn, adr, by) verdier (?, ?, ?)"); $STH->execute($data);

Dataene i matrisen erstattes i malene i sekvensiell rekkefølge. $data går inn i det første mønsteret, $data inn i det andre, og så videre. Men hvis matrisen er indeksert i en annen rekkefølge, vil ikke denne operasjonen fungere riktig. Du må sørge for at rekkefølgen på malene samsvarer med rekkefølgen på dataene i matrisen.

Navngitte maler

Her er et eksempel på bruk av en navngitt mal:

# Det første funksjonsargumentet er navnet på den navngitte malen # En navngitt mal starter alltid med et kolon $STH->bindParam(":navn", $navn);

Du kan bruke forkortelser, men de fungerer på tilhørende arrays. Eksempel:

# Data som skal settes inn $data = array("name" => "Michelle", "addr" => "Kuznechny Lane", "city" => "Cnjkbwf"); # Stenografi $STH = $DBH->("INSERT INTO folks (navn, adr, by) verdi (:navn, :addr, :by)"); $STH->execute($data);

Tabellnøklene dine trenger ikke et kolon, men må fortsatt samsvare med malnavnene. Hvis du bruker en rekke matriser, kan du iterere over den og bare ringe henrette for hvert datasett.

En annen fin funksjon med navngitte maler er muligheten til å sette inn objekter direkte i databasen ved å matche egenskaper og feltnavn. Eksempel:

# En enkel objektklasseperson ( offentlig $navn; offentlig $addr; offentlig $by; funksjon __construct($n,$a,$c) ( $this->name = $n; $this->addr = $a; $ this->city = $c; ) # etc... ) $cathy = new person("Katya","Lenin Avenue","Mozhaysk"); # Kjør: $STH = $DBH->("INSERT INTO folks (navn, adr, by) verdi (:navn, :addr, :by)"); $STH->execute((array)$cathy);

Konverter objekttype til array v henrette fører til at egenskaper behandles som matrisenøkler.

Henter data


Tilstandsidentifikatoren brukes for å hente dataene ->hent(). Før du kaller en metode hente() du må fortelle PUD hvordan du får dataene fra databasen. Du kan velge mellom følgende alternativer:

  • PDO::FETCH_ASSOC: returnerer en matrise indeksert etter kolonnenavn
  • PDO::FETCH_BOTH (standard): returnerer en matrise indeksert etter kolonnenavn og tall
  • PDO::FETCH_BOUND: tildeler verdiene til kolonnene dine til et sett med variabler ved hjelp av metoden ->bindColumn()
  • PDO::FETCH_CLASS: tildeler kolonneverdier til egenskapene til den navngitte klassen, hvis den tilsvarende egenskapen ikke eksisterer, blir den opprettet
  • PDO::FETCH_INTO: oppdaterer en eksisterende forekomst av den navngitte klassen
  • PDO::FETCH_LAZY: kombinasjon PDO::FETCH_BOTH/PDO::FETCH_OBJ, oppretter objektvariabelnavn etter hvert som de brukes
  • PDO::FETCH_NUM: returnerer en matrise indeksert med kolonnetall
  • PDO::FETCH_OBJ: returnerer et anonymt objekt med egenskapsnavn som tilsvarer kolonnenavn

Faktisk løses hovedsituasjonene ved å bruke tre alternativer: FETCH_ASSOC, FETCH_CLASS og FETCH_OBJ. For å angi dataekstraksjonsmetoden, bruk:

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

Du kan også angi datainnhentingsmetoden direkte i metodekallet ->hent().

FETCH_ASSOC

Denne typen datautvinning oppretter en assosiativ matrise indeksert av kolonnenavn. Det burde være ganske godt kjent for de som bruker utvidelser. mysql/mysqli. Eksempel på datasampling:

$STH = $DBH->query("VELG navn, adr, by fra folk"); # Angi hentemodus $STH->setFetchMode(PDO::FETCH_ASSOC); while($row = $STH->fetch()) ( echo $row["navn"] . "\n"; echo $row["addr"] . "\n"; echo $row["by"] . "\n"; )

Syklus samtidig som fortsetter å iterere over resultatet av valget én rad om gangen til den er fullført.

FETCH_OBJ

Med denne typen datautvinning opprettes et objekt av klassen std for hver linje med mottatte data:

$STH = $DBH->query("VELG navn, adr, by fra folk"); # Angi hentemodus $STH->setFetchMode(PDO::FETCH_OBJ); # vis resultat while($row = $STH->fetch()) ( echo $row->name . "\n"; echo $row->addr . "\n"; echo $row->city . "\ n";)

FETCH_CLASS

Ved denne typen henting plasseres dataene direkte inn i klassen du velger. Ved hjelp av FETCH_CLASS objektets egenskaper er satt FØR konstruktøren kalles. Det er veldig viktig. Hvis en egenskap for det tilsvarende kolonnenavnet ikke eksisterer, vil en slik egenskap bli opprettet (som offentlig) For deg.

Dette betyr at hvis dataene må transformeres etter å ha blitt hentet fra databasen, så kan det gjøres automatisk av objektet ditt så snart et er opprettet.

Tenk deg for eksempel en situasjon der en adresse må være delvis skjult for hver oppføring. Vi kan utføre oppgaven ved å operere på en eiendom i konstruktøren:

Class secret_person ( offentlig $navn; offentlig $addr; offentlig $by; offentlig $other_data; funksjon __construct($other = "") ( $this->address = preg_replace("//", "x", $this-> adresse); $this->other_data = $other; ) )

Når dataene er trukket ut i klassen, vil alle små bokstaver a-z i adressen erstattes med x. Når du bruker klassen og henter dataene, er transformasjonen helt gjennomsiktig:

$STH = $DBH->query("VELG navn, adr, by fra folk"); $STH->setFetchMode(PDO::FETCH_CLASS, "hemmelig_person"); while($obj = $STH->fetch()) (ekko $obj->addr;)

Hvis adressen var 'Leninsky Prospekt 5' vil du se 'Lhhhhhhh xx-x 5'. Selvfølgelig er det situasjoner der du vil at konstruktøren skal kalles opp før dataene tildeles. PUD har midler til å implementere dette:

$STH->setFetchMode(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, "hemmelig_person");

Nå når du gjentar forrige eksempel med modusen satt PDO::FETCH_PROPS_LATE adressen vil ikke skjules siden konstruktøren har blitt kalt og egenskaper er tildelt.

Hvis du trenger det, kan du sende argumenter til konstruktøren når du trekker ut data til et objekt:

$STH->setFetchMode(PDO::FETCH_CLASS, "secret_person", array("stuff"));

Hvis du trenger å sende forskjellige data til konstruktøren for hvert objekt, kan du angi datainnhentingsmodus i metoden hente:

$i = 0; while($rowObj = $STH->fetch(PDO::FETCH_CLASS, "secret_person", array($i))) ( // gjør ting $i++)

Noen andre nyttige metoder

Siden PUD ikke kan beskrives fullstendig i en kort artikkel, vil vi presentere flere nyttige metoder for å utføre grunnleggende operasjoner.

$DBH->lastInsertId();

Metode ->lastInsertId() kalles alltid opp av et databasehåndtak (ikke et statushåndtak) og returnerer verdien til den auto-inkrementerende IDen til den sist innsatte raden for denne tilkoblingen.

$DBH->exec("DELETE FROM folks WHERE 1"); $DBH->exec("SET time_zone = "-8:00"");

Metode ->exec() brukes til ulike hjelpeoperasjoner.

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

Metode ->sitat() siterer rader slik at de kan brukes i spørringer. Dette er din reserve i tilfelle forberedte uttrykk ikke brukes.

$rows_affected = $STH->rowCount();

Metode ->rowCount() returnerer en verdi heltall En som indikerer antall rader som behandles av operasjonen. I den nyeste versjonen av PUD, ifølge feilrapporten (http://bugs.php.net/40822) fungerer ikke denne metoden med uttrykk PLUKKE UT. Hvis du har problemer og ikke kan oppdatere PHP, kan du få antall rader på følgende måte:

$sql = "VELG ANTALL(*) FRA folkens"; if ($STH = $DBH->query($sql)) ( # Sjekk antall rader if ($STH->fetchColumn() > 0) ( # SELECT-kode skal være her ) else ( ekko "Det er ingen rader samsvarer med søket." ; ) )

Håper du likte leksjonen!

Her om dagen bestemte jeg meg for å forholde meg til php PUD. Det er interessant og det er nødvendig å studere nye teknologier. Jeg fant ikke russisk dokumentasjon noe sted, så jeg bestemte meg for å legge den ut. Jeg håper denne artikkelen vil være av interesse for deg.

Introduksjon

La oss starte først PHP Data Objects (PDO) er et lett grensesnitt for tilgang til databaser på PHP-språket. Det kan fungere med de fleste databaser som MS SQL, Firebird, MySQL, Oracle, PostgreSQL, SQLite og mer. Men her er det nødvendig å være oppmerksom på at PDO gir den nødvendige funksjonaliteten for å jobbe med databaser, men for hver type database må en egen databasetilgangsdriver installeres i form av en PHP-utvidelse.

Ved hjelp av PDO kan du lage applikasjoner som er helt uavhengige av type database, samtidig som det er mulig å bruke det meste av funksjonaliteten til databaser, som for eksempel å lage forberedte uttalelser eller transaksjoner. I tilfelle denne funksjonaliteten ikke støttes av databasen, emulerer PDO denne funksjonen på egen hånd, og bryter dermed ikke programlogikken på noen måte.

Koblingen er ganske enkel, bortsett fra at du nå på én linje må spesifisere umiddelbart hvilken type database du kobler til, vertsnavnet og også navnet på databasen.

Formatet er slik:

databasetype:vert=vertsnavn;db=navn

La oss se på et eksempel, bare kompliserer eksempelet litt ved å bruke unntak fra PDO-biblioteket (PDOException). Slik at i tilfelle en mislykket tilkobling til databasen får vi klar beskjed om dette, og ikke en haug med jambs med kode som kom fra ingensteds.

prøv ( $db = ny PUD( "mysql:host=localhost;dbname=test", "root" , "" ); $rows = $db -> exec( "CREATE TABLE `testing`(id INT PRIMARY KEY AUTO_INCREMENT, fname VARCHAR(20) NOT NULL DEFAULT "", e-post VARCHAR(50) NOT NULL DEFAULT "")") ; ) catch(PDOException $e ) ( die ("Feil: " . $e -> getMessage () ) ; )

Hvis du gjør en feil i SQL-setningen, har PDO spesielle funksjoner:

errorCode() - returnerer feilnummeret, og

errorInfo() - returnerer en matrise som inneholder både feilnummeret og beskrivelsesteksten

Forespørsler kan gjøres direkte med to funksjoner:

exec() og query()

Forskjellen deres ligger i typen av det returnerte resultatet, exec returnerer antall rader som er påvirket av spørringen, og den andre returnerer resultatet av spørringen i PDOStatement-objektet, vi snakker om det litt lavere.

La oss nå legge til disse funksjonene i koden og gjøre eksemplet litt mer komplekst:

// i begynnelsen av konfigurasjonen define("DB_DRIVER" , "mysql" ); define("DB_HOST" , "localhost" ); define("DB_NAME" , "test" ); define("DB_USER" , "root" ); define("DB_PASS" , "" ) ; prøve( // koble til databasen$connect_str = DB_DRIVER . ":vert=" . DB_HOST . ";dbname=" . DB_NAME; $db = ny PDO($connect_str , DB_USER, DB_PASS) ; // sett inn flere rader i tabellen fra forrige eksempel$rows = $db -> exec( "INSERT INTO `testing` VALUES (null, "Ivan", " [e-postbeskyttet]"), (null, "Peter", " [e-postbeskyttet]"), (null, "Vasily", " [e-postbeskyttet]") " ) ; $error_array = $db -> errorInfo(); if ($db ->
" ; // hvis forespørselen var vellykket, // vis deretter antall berørte rader hvis ($rows) ekko "Antall berørte rader: ". $rader. "
" ; // velg nå noen rader fra databasen$result = $db -> spørring( "VELG * FRA `testing` LIMIT 2") ; // i tilfelle feil i SQL-uttrykket, skriv ut feilmeldingen$error_array = $db -> errorInfo(); if ($db -> errorCode () != 0000) ekko "SQL error: " . $error_array [2]. "

" ; // nå får vi data fra PDOStatement-klassen while ($row = $result -> fetch()) ( // som et resultat får vi en assosiativ matrise print_r($rad); ) ) catch(PDOException $e ) ( die ("Feil: " . $e -> getMessage () ) ; )

Forberedte uttrykk

Forberedte uttrykk ligner veldig på vanlige SQL-spørringer, men har noen fordeler. For det første har de en høy utførelseshastighet, og for det andre er de mer pålitelige når det gjelder sikkerhet, siden alle parametere som sendes til dem, automatisk skjermes fra alle slags injeksjoner.

De har en betydelig hastighetsfordel når du utfører flere identiske spørringer enn hvis du gjenoppretter spørringen hver gang. Det sparer også trafikk mellom applikasjonen og databasen.

PUD gir praktiske funksjoner for arbeid med utarbeidede erklæringer. Hvis den valgte databasetypen ikke støtter forberedte setninger, vil PDO ganske enkelt emulere arbeidet deres med sine egne metoder.

Og så, til å begynne med, vil vi lage et forberedt uttrykk, dette gjøres av Prepare () funksjonen

Det tar en SQL-spørring som en parameter, men i den, i stedet for verdier som må endres, settes pseudovariabler, som kan være i form av et spørsmålstegn (?), eller et pseudovariabelnavn som starter med kolon (:)

$sth1 = $db->prepare("SELECT * FROM `testing` WHERE id=:id");

$sth2 = $db->prepare("SELECT * FROM `testing` WHERE id=?");

Avhengig av hvordan du definerer variabelen, vil ditt videre arbeid avhenge.

Hvis du har definert variabler med et spørsmålstegn, send deretter en rekke verdier til execute-funksjonen, i den rekkefølgen som variablene er.

Hvis du utpekte variabler ved navn, må du tilordne en verdi til hver variabel ved å bruke funksjoner:

bindValue() - tildeler en verdi til en pseudovariabel

bindParam() - binder en pseudovariabel til en reell variabel, og når du endrer en reell variabel, trenger du ikke kalle noen tilleggsfunksjoner lenger, du kan umiddelbart utføre()

Her er et eksempel med det første alternativet:


Vær oppmerksom på at etter at PDO-objektet oppretter et forberedt uttrykk i PDOStatement-klassen, bruker vi kun det, henholdsvis, det har sine egne funksjoner errorCode, errorInfo, samt resultatet av spørringsutførelsen, lagres også umiddelbart i den.

Og nå den andre veien.

For å tilordne en verdi til en pseudovariabel, bruk bindValue()-funksjonen

Denne koden kan skrives enda enklere ved å assosiere en pseudovariabel med en reell:

Det er umiddelbart nødvendig å legge til at det er veldig ønskelig (for ikke å forårsake unødvendige feil) å angi variabeltypen som den tredje parameteren. Jeg personlig, i fravær av en variabeltype, hadde feil i WHERE-setningen, siden den anså variabelen for å være tekst, ikke et tall.

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

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

En annen veldig fin fordel med å bruke slike forberedte uttrykk er variabel escape. Før substitusjon i prosedyren, er alle variabler escaped og ingen SQL-injeksjoner er forferdelige.

Transaksjoner

En transaksjon er et sett med databasespørringer som må fullføres av alle. Hvis en forespørsel ikke blir utført eller utført med en feil, kanselleres transaksjonen og ingen dataendringer i databasen skjer.

Dette er for å sikre at dataintegriteten opprettholdes på tvers av flere forespørsler. For eksempel når du overfører penger fra en konto til en annen.

For å utføre en transaksjon i PUD, må du bytte til manuell forespørselsbekreftelsesmodus.

Transaksjoner brukes forresten hele tiden, men vanligvis fungerer PDO i auto-commit-modus, så alle transaksjoner består av en enkelt forespørsel.

For å slå av autocommit-modus, kjør kommandoen:

$db->beginTransaction();

Deretter utfører vi så mange spørringer til databasen som det er nødvendig å gjøre i denne transaksjonen.

Og først etter at alle forespørsler er fullført, kan du bekrefte transaksjonen med funksjonen

$db->forplikte();

eller kansellere transaksjonen

$db->rollback();

Her er et lite eksempel på transaksjoner:

prøv ( $connect_str = DB_DRIVER . ": host=" . DB_HOST . ";dbname=" . DB_NAME; $db = new PDO($connect_str , DB_USER, DB_PASS) ; $rows = $db -> exec ( "CREATE TABLE `testing`(id INT PRIMARY KEY AUTO_INCREMENT, fname VARCHAR(20) NOT NULL DEFAULT "", e-post VARCHAR(50) NOT NULL DEFAULT "", money INT NOT NULL DEFAULT 0) ENGINE=InnoDB;") ; $rows = $db -> exec( "INSERT INTO `testing` VALUES (null, "Ivan", " [e-postbeskyttet]", 15000), (null, "Petr", " [e-postbeskyttet]", 411000), (null, "Vasiliy", " [e-postbeskyttet]", 1500000) " ) ; // La oss prøve å overføre beløpet 50 000 fra Ivan// Peter $summ = 50000 ; $transaction = sant ; $db -> beginTransaction(); $sth1 = $db -> spørring( "VELG penger FRA testing WHERE fname="Ivan"") ; $sth2 = $db -> spørring ( "VELG penger FRA testing WHERE fname="Petr"") ; $row1 = $sth1 -> hente() ; $row2 = $sth2 -> hente() ; if (! $rad1 || ! $rad2 ) $transaksjon = usann ; $total2 = $summ + $row2 [ "penger" ] ; $total1 = $row1 [ "penger" ] - $summ ; if ($total1< 0 || $total2 < 0) $transaction = false ; $num_rows1 = $db ->exec ( . $total1 . "" WHERE fname="Ivan"" ); $num_rows2 = $db -> exec ( "OPPDATERING `testing` SET money="". $total2 . "" WHERE fname="Petr"" ); if ($transaction ) ( ekko "Transaksjonen er fullført"; $db -> commit() ; ) annet (ekko "Transaksjonen mislyktes"; $db -> rollback() ; ) ) catch(PDOException $e ) ( die ("Feil: " . $e -> getMessage () ) ; )

Det skal også bemerkes her at ikke alle typer tabeller støtter transaksjoner, så i dette eksemplet brukte jeg en InnoDb-tabell i stedet for standard MyISAM.

Avslutningsvis vil jeg si at dette er langt fra en komplett manual om PUD. Du kan alltid få all den nyeste og fullstendige informasjonen her: http://www.php.net/manual/en/book.pdo.php

Lær og skap.

Bootstrap Framework: Rask responsiv layout

Et trinn-for-trinn videokurs om det grunnleggende om responsiv layout i Bootstrap-rammeverket.

Lær å sette enkelt, raskt og effektivt ved å bruke et kraftig og praktisk verktøy.

Gjør opp for å bestille og få penger.

Gratis kurs "Nettsted på WordPress"

Vil du mestre WordPress CMS?

Få leksjoner om nettsteddesign og layout på WordPress.

Lær å jobbe med temaer og del oppsettet.

Gratis videokurs om tegning av nettsidedesign, layout og installasjon på CMS WordPress!

* Hold musepekeren over for å pause rullingen.

Tilbake fremover

Grunnleggende om arbeid med PUD-utvidelsen

I dag vil vi analysere et veldig interessant emne - det grunnleggende om å jobbe med utvidelsen PUD for PHP.

PUD (PHP-dataobjekter) er bare et grensesnitt som lar deg jobbe med ulike databaser uten å ta hensyn til deres spesifikke egenskaper. Med PUD kan vi enkelt bytte mellom ulike databaser og administrere dem. For å gjøre det klarere, la oss se på et eksempel.

Hvordan vi skulle ha koblet til basen før MySQL?

mysql_connect($vert, $bruker, $passord); mysql_select_db($db);

For å koble til SQLite vi burde ha skrevet slik:

sqlite_open($db);

Hvis vi trenger en database PostgreSQL, så bør du skrive det slik:

pg_connect("vert=$vert, dbnavn=$db, bruker=$bruker, passord=$passord");

Ikke veldig praktisk, ikke sant? Det viser seg at hvis vi vil endre databasen, må vi gjøre om mye kode. Og for å fikse dette dukket det opp en spesiell PHP-utvidelse - PUD.

La oss se hvordan vi nå kan koble til databasen:

$db = new PDO("mysql:host=$host;dbname=$db", $user, $password);

$db = ny PUD("sqlite:$db);

PostgreSQL:

$db = new PDO("pgsql:host=$host;dbname=$db", $user, $password);

Som du kan se, er alt det samme, bortsett fra tilkoblingsstrengen. Dette er den eneste forskjellen.


La oss nå se på hvordan vi pleide å utføre spørringer:

$sql = "INSERT INTO(navn, e-post) VERDIER($navn, $e-post)"; // MySQL mysql_query($sql); // SQLite sqlite_query($sql); // PostgreSQL pg_query($sql);

Nå kan vi abstrahere fra dette:

// PUD $result = $db->exec($sql);

Alt! Vår spørringen vil bli utført uansett hvilken DB vi bruker, og inn i en variabel resultat vil få antall berørte rader.

Vi vil imidlertid ikke kunne velge noe fra databasen på denne måten. For prøvetaking må vi bruke ikke exec, a spørsmål.

$sql = "VELG navn FRA brukere"; $result = $db->query($sql);

La oss nå husk om sikkerhet fordi alle dataene må verifiseres. Hvordan gjorde vi det før?

$sql = "VELG * FRA brukere WHERE navn = $navn"; $navn = $_POST["navn"]; // MySQL $navn = mysql_real_escape_string($navn); // SQLite $navn = sqlite_escape_string($navn); // PostgreSQL $navn = pg_escape_string($navn);

Nå trenger vi ikke gjøre det. PUD vil gjøre alt for oss.

$navn = $db->quote($navn); $result = $db->query($sql);

PUD vil selv sjekke alt og behandle de overførte dataene. Kul? :) Ytterligere enda kulere! La oss fortsette.

Hvordan konverterte vi resultatet til en matrise før? Tenk på eksemplet med en base MySQL.

$result = mysql_query($sql); // Så $row = mysql_fetch_assoc($result); // Eller som dette... $row = mysql_fetch_array($result, FETCH_ASSOC);

I tillegg til en assosiativ kan vi få en nummerert matrise. La oss nå se hvordan det er gjort PUD:

$stmt = $db->query($sql); // Assosiativ $result = $stmt->FETCH(PDO::FETCH_ASSOC); // Nummerert $result = $stmt->FETCH(PDO::FETCH_NUM); // Begge matrisetyper samtidig $result = $stmt->FETCH(PDO::FETCH_BOTH); // Objekt $result = $stmt->FETCH(PDO::FETCH_OBJ);

Det er også veldig enkelt å bruke:

// Assosiativt ekko $result["navn"]; // Nummerert ekko $result; // Objektekko $result->navn;

For de "late" er det denne tingen:

$stmt = $db->query($sql); $result = $stmt->FETCH(PDO::FETCH_LAZY);

Den returnerer alle 3 typene samtidig. De. den FETCH_BOTH og FETCH_OBJ sammen. Som du kanskje har gjettet, kan dataene nås på en av tre måter:

echo $result->navn; echo $result["navn"]; ekko $resultat;

men Hent returnerer bare én post, så hvis vi ønsker å få alle postene, må vi bruke Hent Alle.

$stmt = $db->query("VELG * FRA brukere"); $result = $stmt->FetchAll(PDO::FETCH_ASSOC); foreach($result as $user) ( echo $user["navn"]."
"; }

Men det er en annen kul ting knyttet til Hent. Med dens hjelp kan vi fylle klassen vår med data fra databasen automatisk.

Klassebruker ( offentlig $login; offentlig $id; offentlig funksjon showInfo() ( echo " ".$this->id.""." : ".$this->pålogging."
"; ) ) $db = new PUD("mysql:host=localhost;dbname=test", "root", ""); $stmt = $db->query("VELG * FRA `brukere`"); $ result = $stmt->fetchAll(PDO::FETCH_CLASS, "Bruker"); foreach($result as $user) ( $user->showInfo(); )

Som du kan se, er alt veldig enkelt. Vi trenger bare å spesifisere en konstant FETCH_CLASS og atskilt med et komma i anførselstegn navnet på klassen der dataene skal settes inn.

Deretter går vi gjennom objektet og viser informasjonen vi trenger.
Merk følgende! Navnene på egenskapene i klassen må samsvare med navnene på feltene i databasen.

Vi kan blant annet lage såkalte forberedte spørsmål. Hva er fordelene deres?

1. Vi kan forberede en spørring én gang og deretter kjøre den så mange ganger vi trenger. Og både med de samme og med andre parametere.

Når en spørring er forberedt, analyserer DBMS den, kompilerer og optimerer utførelsesplanen. Ved komplekse spørringer vil utførelsestiden være merkbar hvis vi kjører den med forskjellige parametere. Ved forberedte spørringer gjøres dette én gang og tar derfor kortere tid.

2. Forberedte spørringsparametere trenger ikke å escapes med anførselstegn, driveren gjør dette automatisk. Hvis bare forberedte spørringer brukes i en applikasjon, er SQL-injeksjoner nesten umulige.

PUD kan etterligne utarbeidede uttalelser hvis de ikke støttes av sjåføren. La oss nå se på hvordan du bruker dem?

$stmt = $db->prepare("INSERT INTO brukere (navn, pålogging) VERDIER (:navn, :pålogging)"); $stmt->bindParam(":navn", $navn); $stmt->bindParam(":login", $login); // Sett inn en linje med disse verdiene $name = "vasya"; $login = "vasya123"; $stmt->execute(); // Nå en annen streng med forskjellige verdier $name = "petya"; $login = "petya123"; $stmt->execute();

Metode bindParam lar oss angi alternativer. Jeg tror alt er klart her. Først, der vi vil at dataene skal settes inn, skriver vi følgende linje " :Navn". Og så spesifiserer vi hvor de skal hentes fra. I dette tilfellet vil de bli hentet fra variabler Navn og Logg Inn.

Nå kan vi bruke denne spørringen med forskjellige parametere så mange ganger vi vil, og for å utføre den må vi kalle metoden henrette. Disse var navngitt parametere. Det er også ikke navngitt.

$stmt = $db->prepare("INSERT INTO brukere (navn, pålogging) VERDIER (?, ?)"); // Dataene fra navnevariabelen vil bli satt inn i stedet for det første spørsmålstegnet $stmt->bindParam(1, $navn); // Dataene fra påloggingsvariabelen vil bli satt inn i stedet for det andre spørsmålstegnet $stmt->bindParam(2, $login); // Sett inn en linje med disse verdiene $name = "vasya"; $login = "vasya123"; $stmt->execute(); // Nå en annen streng med forskjellige verdier $name = "petya"; $login = "petya123"; $stmt->execute();

Neste øyeblikk - hvordan fanger vi opp feil?

Det er en klasse for dette PDO-unntak. Jeg anbefaler å skrive alle forespørslene dine i en blokk prøv å fange.

Prøv ( $db = new PDO("myql:host=localhost;dbname=test", "root", ""); $stmt = $db->query("SELECT * FROM users"); $result = $stmt ->fetch(PDO::FETCH_ASSOC); echo $result["login"]; ) catch(PDOException $e) (ekko "Feil: ".$e->getMessage()."
"; echo "On line: ".$e->getLine(); )

Her tok vi feil og skrev mysql i stedet for mysql. Og klasse PDO-unntak skriv til oss om det.

Den har flere metoder, men de mest brukte er getMessage(), som returnerer oss feilteksten og getLine(), som returnerer linjenummeret der feilen oppsto.

Og til slutt, la oss snakke om transaksjoner. Jeg gir deg koden først.

Prøv ( $db = new PDO("mysql:host=localhost;dbname=test", "root", ""); $db->beginTransaction(); $stmt = $db->exec("INSERT INTO `users `(`login`) VALUES("login1")"); $stmt = $db->exec("INSERT INTO `users`(`login`) VALUES("login2")"); $stmt = $db- >exec("INSERT INTO `users`(`login`) VALUES("login3")"); $db->commit(); ) catch(PDOException $e) ( $db->rollBack(); )

Her starter vi en transaksjon med metoden beginTransaction(). Deretter kommer litt forespørselskode. Vi kaller da metoden begå() for å bekrefte endringene våre. Hvis noe gikk galt, så i blokka å fange vi kaller metoden rollBack(), som vil returnere alle våre data til den forrige tilstanden.

"Hvorfor trenger vi egentlig disse transaksjonene?" - du spør. For å svare på dette spørsmålet, vurder eksempelet jeg ga ovenfor. Der setter du inn verdien i feltet "pålogging". login1, login2, login3.

Tenk deg det etter innsetting pålogging1 og pålogging 2, det har oppstått en feil. Det viser seg at disse dataene er satt inn, og pålogging3- Nei. I mange tilfeller er dette uakseptabelt og vil bryte søknaden i fremtiden.

Det er for å forhindre slike situasjoner at det er behov for transaksjoner. Hvis skriptet vårt mislykkes, så metoden rollBack() vil returnere alt til sin opprinnelige tilstand. De. pålogging1 og pålogging 2 vil heller ikke bli satt inn. La oss simulere denne feilen.

Prøv ( $db = new PDO("mysql:host=localhost;dbname=test", "root", ""); $db->beginTransaction(); $stmt = $db->exec("INSERT INTO `users `(`login`) VALUES("login1")"); $stmt = $db->exec("INSERT INTO `users`(`login`) VALUES("login2")"); exit("feil") ; $stmt = $db->exec("INSERT INTO `users`(`login`) VALUES("login3")"); $db->commit(); ) catch(PDOException $e) ( $db-> rollBack(); )

Etter liming pålogging1 og pålogging 2 vi avslutter skriptet med funksjonen exit(). Vi kaster et unntak, vi kommer inn i blokka å fange, og der returnerer vi alt til sin opprinnelige form. Nå, hvis vi ser inn i databasen, vil vi ikke se det pålogging1 og pålogging 2.

På dette tidspunktet vil vi avslutte. Her har vi selvsagt ikke dekket alt som PUD gir oss, men vi lærte det grunnleggende om å jobbe med det. Du kan alltid finne mer informasjon om denne utvidelsen på det offisielle PHP-nettstedet.

Materialet ble utarbeidet av Vladislav Andreev spesielt for nettstedet

P.S. Vil du komme videre i å mestre PHP og OOP? Ta en titt på førsteklasses opplæringsprogrammer om ulike aspekter av nettstedbygging, inkludert PHP-programmering, samt et gratis kurs om å bygge PHP CMS-systemet fra bunnen av ved hjelp av OOP:

Likte materialet og vil du takke?
Bare del med dine venner og kolleger!


PDO (PHP Data Objects) er en PHP-utvidelse som gir et enkelt grensesnitt for tilgang til ulike databaser. For å si det veldig enkelt og kort, ved hjelp av PDO i PHP kobler de seg til databaser av ulike typer.

I denne opplæringen vil vi koble til MySQL-databasen, siden det er den vanligste databasen.

Databasetilkobling

Du må vite at databaseserveren har et navn, brukere kan også koble til den, det vil si at en pålogging og et passord må brukes for å koble til.

Et eksempel på hvordan vi kan koble til en database:

$db = new PDO("mysql:host=$host;dbname=$db", $user, $pass);

Jeg tror at hvis du er interessert i PUD, så er kunnskapen din nok og du trenger ikke forklare denne syntaksen.

Så vi har et tilkoblingsobjekt for å få tilgang til databasen.

Avvikshåndtering

Når du bruker PDO, anbefaler jeg deg å fange opp tilkoblingsfeil ved å bruke try(...)catch(...)-konstruksjonen. Her er et eksempel på slik kode:

Prøv ( $db = new PDO("myql:host=$host;dbname=$dbname", $user, $pass); ) catch(PDOException $e) ( ekko "Du har en feil: ".$e-> getMessage()."
"; echo "Online: ".$e->getLine(); )

Det er ulike meninger om feilhåndtering, for eksempel anbefaler ikke alle å alltid bruke try(...)catch(...)-konstruksjonen. Poenget er at PHP vil vise en feilmelding uansett, så denne koden er overflødig. Selv om du vil tilbakestille en transaksjon, for eksempel, så vil denne konstruksjonen komme godt med, men mer om det nedenfor.

Hente data fra databasen ved hjelp av PDO, spørringsmetoden

For å hente fra databasen brukes spørringsmetoden, som vi sender SQL spørrestrengen til.

$db->query("VELG * FRA brukere");

Husk at denne syntaksen vil fungere for alle databasetyper.

Ikke glem sikkerheten til data som overføres i SQL-spørringer. I PDO er det en analog av mysql_real_escape_string()-funksjonen - sitatmetoden.

$login = $db->quote($_POST["pålogging"]); $sql = "VELG * FRA brukere WHERE login = $login"; $result = $db->query($sql);

Resultatbehandling, FETCH og FETCHALL metoder.

Nå må vi konvertere resultatet fra $res-variabelen til en matrise. Dette gjøres ved hjelp av FETCH-metoden, som sendes en konstant.

$res = $db->query($sql); $result = $res->FETCH(PDO::FETCH_NUM); // nummerert $result = $res->FETCH(PDO::FETCH_ASSOC); // assosiativ $result = $res->FETCH(PDO::FETCH_BOTH); // assosiativ og nummerert sammen $result = $res->FETCH(PDO::FETCH_OBJ); // objekttype $result = $res->FETCH(PDO::FETCH_LAZY); // alle typer samtidig

Det er klart at FETCH_LAZY-konstanten bremser skriptet, så det anbefales å ikke bruke det.

FETCH-metoden returnerer én post fra resultatet. Hvis du ønsker å få alle poster, må du bruke FETCHALL-metoden. Videre blir resultatet oppnådd som et resultat av bruk av FETCHALL behandlet i hver løkke, som vist i eksemplet:

$query = $db->query("VELG * FRA brukere"); $result = $query->FETCHALL(PDO::FETCH_ASSOC); foreach($result as $arry) ( echo $arry["navn"] . "
"; }

FETCH_CLASS konstant

FETCH_CLASS-konstanten krever en spesiell forklaring; den lar deg fylle en forhåndsopprettet klasse med data fra resultatet av en databasespørring.

La oss se på et eksempel som bruker FETCH_CLASS-konstanten:

Klassebruker ( offentlig $login; offentlig $pass; offentlig funksjon showInfo() ( echo "
".$this->pass."
" . " : " . $this->logg inn . "
"; ) ) $result = $stmt->FETCHALL(PDO::FETCH_CLASS, "Bruker"); foreach($result as $user) ( $user->showInfo(); )

Ikke glem en viktig regel - navnene på egenskapene i den opprettede klassen må være de samme som navnene på feltene i databasen.

Forberedte uttrykk

Forberedte uttrykk må brukes hvis SQL-spørringen inneholder variabler.

Forberedte PDO-uttrykk er hovedgrunnen til å bruke PHP-dataobjekter, da det er den eneste sikre måten å utføre SQL-spørringer som har brukerlagde variabler.

Forberedte uttrykk i PDO er en vanlig SQL-spørring der en variabel erstattes av en spesiell markør - en plassholder.

Navngitte plassholdere

La oss først se på en navngitt plassholder, dens syntaks er for eksempel: :email .

La oss se på et eksempel på en INSERT-spørring som bruker plassholdere.

$stmt = $db->prepare("INSERT INTO meldinger (e-post, melding) VERDIER (:email, :melding)");

I dette eksemplet, i stedet for variabler i forespørselen, brukte vi to plassholdere (:email, :melding)") .

$stmt = $db->prepare("INSERT INTO meldinger (e-post, melding) VERDIER (:email, :melding)"); $stmt->bindParam(":email", $email); $stmt->bindParam(":melding", melding); $email = "E-post #1"; $message = "Noen meldingstekst"; $stmt->execute(); $email = "E-post #2"; $message = "Noen meldingstekst"; $stmt->execute();

Vær oppmerksom på at for å forberede en SQL-spørring, skriver vi den i prepare()-metoden. Deretter, for å spesifisere hvilken plassholder hvilken variabel som skal bindes, bruker vi bindParam()-metoden. For å utføre en SQL-spørring kaller vi execute()-metoden.

Så, nok en gang, sekvensen for å jobbe med forberedte uttrykk trinn for trinn:

  1. Vi tilordner resultatet av å utføre prepare()-metoden til $stmt-variabelen.
  2. Ved å bruke bindParam()-metoden binder vi variabler og plassholdere.
  3. Tilordne verdier til variabler.
  4. Ved å bruke execute()-metoden kjører vi en spørring mot databasen.

Denne syntaksen kan skrives

$stmt = prepare("VELG navn FRA brukere WHERE email = :email"); $stmt->execute(array("email" => $email));

Det kan sees at en matrise må sendes til execute()-metoden, der nøklene må samsvare med navnene på plassholderne.

Forresten, bindParam()-metoden har et synonym for bindValue() .

Ikke navngitte plassholdere

Vurder nå å jobbe med ikke navngitte plassholdere.

$stmt = prepare("VELG navn FRA brukere WHERE email = ?") $stmt->execute(array($email));

I denne syntaksen, i stedet for å skrive en plassholder: navn, er en annen form for opptaket angitt - et spørsmålstegn:? .

Her vil verdiene til $email-matrisen bli tildelt plassholderne én etter én:? , men i vårt eksempel er det bare én plassholder.

Her er et annet eksempel på bruk av navnløse plassholdere ved å bruke bindParam()-metoden:

$stmt = $db->prepare("INSERT INTO artikler (tittel, tekst) VERDIER (?, ?)"); $stmt->bindParam(1, $email); $stmt->bindParam(2, $melding); $email = "E-post #1"; $message = "Noen meldingstekst"; $stmt->execute(); $email = "E-post #2"; $message = "Noen meldingstekst"; $stmt->execute();

Sett inn i databasen, exec()-metoden

Hvis vi vil skrive noe til databasen, kan vi også bruke PDO::exec()-metoden.

$sql = "INSERT I (pålogging, passord) VERDIER ($login, $password)"; $result = $db->exec($sql);

Hvis denne spørringen utføres, vil $result-variabelen inneholde antall berørte rader i tabellen.

PDO::exec() utfører INSERT-spørringer, men kan ikke hente data fra databasen, dette gjøres med PDO::query()-metoden. PDO::exec() starter bare SQL-spørringen og returnerer antall rader som er involvert i dens utførelse, den returnerer ikke resultatet av utvalget av SELECT-setningen.

PUD fungerer med databaser. Hvis det er umulig å jobbe med en type database, gå til php.ini og se etter linjer som starter med extension=php_pdo_(databasenavn), og fjern kommentarer.

Php for nybegynnere: Tilbakeringingsfunksjoner Leksjon 34! https://www.youtube.com/watch?v=2NwLHXUoXcw https://www.youtube.com/watch?v=GMzI6jR_bE4 https://www.youtube.com/watch?v=gFJsBQIqpto PHP Leksjon 9 Rekursjon https://www.youtube.com/watch?v=gFJsBQIqpto ://www.youtube.com/watch?v=gLAeJcKkd6c http://php.net/manual/ru/mysqli-result.fetch-array.php /* slett henteresultater */ mysqli_free_result($result); /* nær tilkobling */ mysqli_close($link); http://myrusakov.ru/sql-osnovy.html God artikkel: https://ru.wikipedia.org/wiki/Join_(SQL) OOP PHP. Extenders Kapittel "Extensors" fra Mat Zandstras PHP. Objekter, mønstre og programmeringsteknikker. https://www.youtube.com/watch?v=6L2bxtTBCRo

http://phpfaq.ru/pdo#intro - her er en god artikkel. Det er viktig informasjon om unntak.

Mer enkelt beskrevet: http://myrusakov.ru/php-data-objects.html

Video: https://www.youtube.com/watch?v=ACUiBH5qV0U&list=PLr_acfJGVcirEijJXmKxj8QGkWkKb-Tj-&nohtml5=False

Introduksjon

Eventuelt --with-mysql-sock[=DIR] setter til plassering til MySQL unix socket-pekeren for alle MySQL-utvidelser, inkludert PDO_MYSQL. Hvis det ikke er spesifisert, søkes standardplasseringene.

Eventuelt --with-zlib-dir[=DIR] brukes til å angi banen til libz-installasjonsprefikset.

$ ./configure --with-pdo-mysql --with-mysql-sock=/var/mysql/mysql.sock

endringslogg
versjon Beskrivelse
5.4.0 mysqlnd ble standard MySQL-bibliotek ved kompilering av PDO_MYSQL. Tidligere var libmysqlclient standard MySQL-bibliotek.
5.4.0 MySQL-klientbiblioteker 4.1 og nedenfor støttes ikke lenger.
5.3.9 Lagt til SSL-støtte med mysqlnd og OpenSSL.
5.3.7 Lagt til SSL-støtte med libmysqlclient og OpenSSL.

Forhåndsdefinerte konstanter

Konstantene nedenfor er definert av denne driveren, og vil bare være tilgjengelig når utvidelsen enten er kompilert til PHP eller dynamisk lastet under kjøretid. I tillegg bør disse driverspesifikke konstantene bare brukes hvis du bruker denne driveren. Bruk av driverspesifikke attributter med en annen driver kan føre til uventet oppførsel. PDO::getAttribute() kan brukes til å skaffe PDO::ATTR_DRIVER_NAME attributt for å sjekke driveren, hvis koden din kan kjøre mot flere drivere.

PDO::MYSQL_ATTR_USE_BUFFERED_QUERY (heltall) Hvis dette attributtet er satt til EKTE på en PDOStatement vil MySQL-driveren bruke de bufrede versjonene av MySQL API. Hvis du skriver bærbar kode, bør du bruke PDOStatement::fetchAll() i stedet.

Eksempel #1 Tvinge spørringer til å bli bufret i mysql

if ($db -> getAttribute (PDO :: ATTR_DRIVER_NAME ) == "mysql" ) (
$stmt = $db -> prepare("velg * fra foo" ,
array(PDO :: MYSQL_ATTR_USE_BUFFERED_QUERY => sant ));
) annet (
dø( "applikasjonen min fungerer bare med mysql; jeg bør bruke \$stmt->fetchAll() i stedet");
}
?>

PDO::MYSQL_ATTR_LOCAL_INFILE (heltall)

muliggjøre LAST LOKAL INFIL.

PDO::MYSQL_ATTR_INIT_COMMAND (heltall)

Kommando som skal utføres når du kobler til MySQL-serveren. Utføres automatisk på nytt når du kobler til igjen.

Merk at denne konstanten bare kan brukes i driver_options-matrisen når du konstruerer et nytt databasehåndtak.

PDO::MYSQL_ATTR_READ_DEFAULT_FILE (heltall)

Les alternativer fra den navngitte alternativfilen i stedet for fra my.cnf . Dette alternativet er ikke tilgjengelig hvis mysqlnd brukes, fordi mysqlnd ikke leser mysql-konfigurasjonsfilene.

PDO::MYSQL_ATTR_READ_DEFAULT_GROUP (heltall)

Les alternativer fra den navngitte gruppen fra my.cnf eller filen spesifisert med MYSQL_READ_DEFAULT_FILE. Dette alternativet er ikke tilgjengelig hvis mysqlnd brukes, fordi mysqlnd ikke leser mysql-konfigurasjonsfilene.

PUD::MYSQL_ATTR_MAX_BUFFER_SIZE (heltall)

maksimal bufferstørrelse. Standard er 1 MiB. Denne konstanten støttes ikke når den kompileres mot mysqlnd.

PDO::MYSQL_ATTR_DIRECT_QUERY (heltall)

Utfør direkte forespørsler, ikke bruk forberedte utsagn.

PDO::MYSQL_ATTR_FOUND_ROWS (heltall)

Returner antall funnet (samsvarende) rader, ikke antall endrede rader.

PDO::MYSQL_ATTR_IGNORE_SPACE (heltall)

Tillat mellomrom etter funksjonsnavn. Gjør alle funksjonsnavn til reserverte ord.

PDO::MYSQL_ATTR_COMPRESS (heltall)

Aktivering. Dette støttes også når det kompileres mot mysqlnd fra og med PHP 5.3.11.

PDO::MYSQL_ATTR_SSL_CA (heltall)

Filbanen til SSL-sertifikatmyndigheten.

Dette eksisterer fra og med PHP 5.3.7.

PDO::MYSQL_ATTR_SSL_CAPATH (heltall)

Filbanen til katalogen som inneholder de klarerte SSL CA-sertifikatene, som er lagret i PEM-format.

Dette eksisterer fra og med PHP 5.3.7.

PDO::MYSQL_ATTR_SSL_CERT (heltall)

Filbanen til SSL-sertifikatet.

Dette eksisterer fra og med PHP 5.3.7.

PDO::MYSQL_ATTR_SSL_CIPHER (heltall)

En liste over en eller flere tillatte chiffere som skal brukes for SSL-kryptering, i et format som forstås av OpenSSL. For eksempel: DHE-RSA-AES256-SHA:AES128-SHA

Dette eksisterer fra og med PHP 5.3.7.

PDO::MYSQL_ATTR_SSL_KEY (heltall)

Filbanen til SSL-nøkkelen.

Dette eksisterer fra og med PHP 5.3.7.

PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT (heltall)

Gir en måte å deaktivere verifisering av serverens SSL-sertifikat.

Dette eksisterer fra og med PHP 7.0.18 og PHP 7.1.4.

PDO::MYSQL_ATTR_MULTI_STATEMENTS (heltall)

Deaktiverer kjøring av flere spørringer i begge PUD::prepare() og PDO::query() når satt til FALSK.

Merk at denne konstanten bare kan brukes i driver_options-matrisen når du konstruerer et nytt databasehåndtak.

Dette eksisterer fra og med PHP 5.5.21 og PHP 5.6.5.

Kjøretidskonfigurasjon

Oppførselen til disse funksjonene påvirkes av innstillingene i php.ini.

PDO_MYSQL konfigurasjonsalternativer
Navn Misligholde foranderlig
pdo_mysql.default_socket "/tmp/mysql.sock" PHP_INI_SYSTEM
pdo_mysql.debug NULL PHP_INI_SYSTEM
For ytterligere detaljer og definisjoner av PHP_INI_*-modusene, se .

Her er en kort forklaring av konfigurasjonsdirektivene.

Angir en Unix-domenekontakt. Denne verdien kan enten settes på kompileringstidspunktet hvis en domenekontakt blir funnet ved konfigurering. Denne ini-innstillingen er kun for Unix.

pdo_mysql.debug boolsk

Aktiverer feilsøking for PDO_MYSQL. Denne innstillingen er bare tilgjengelig når PDO_MYSQL er kompilert mot mysqlnd og i PDO-feilsøkingsmodus.

Innholdsfortegnelse

  • PDO_MYSQL DSN - Koble til MySQL-databaser

Installer dem

rpm -Uvh remi-release-26.rpm
rpm -Uvh epel-release-6-8.noarch.rpm

Vet at du kan bruke remi repository til å gest php-pdo og php-mysql.

yum --enablerepo=remi installer php-pdo
yum --enablerepo=remi installer php-mysql

Start Apache på nytt

systemctl stopp httpd
systemctl start httpd

Klar til å gå!

For 10 år siden

SQLSTATE: Generell feil: 2014 Kan ikke utføre spørringer mens andre ubuffrede spørringer er aktive. ...

Denne kan være en kongelig smerte å håndtere. Stable aldri uttalelser som skal utføres på én gang. Ingen nevner noen gang denne muligheten i alle innleggene jeg har sett som omhandler denne feilen.

Dette eksemplet er et Zend Framework-eksempel, men teorien er den samme.

$sql =<<<____SQL

`tid` int(11) IKKE NULL,

`tgen` datetime IKKE NULL,
`tterm` datetime,

`rqid` int(11) IKKE NULL,
`rqtid` int(11) NOT NULL,
`rqsid` int(11) IKKE NULL,
`rqdate` datetime IKKE NULL,
`rssid` int(11) NOT NULL,
`rsdate` datetime,
`rscode` tinyint(1)

`rqid` int(5) IKKE NULL,

`sid` int(11) IKKE NULL,
`rlsid` int(11) IKKE NULL,
`dcode` varchar(5) IKKE NULL

____SQL;
$result = $this -> db -> getConnection()-> exec($sql );
?>
Dette vil gå bra, men PDO vil svikte med "unbuffered"-feilen hvis du følger denne med en annen spørring.

$sql =<<<____SQL
LAG TABELL HVIS IKKE FINNES `ticket_hist` (
`tid` int(11) IKKE NULL,
`trqform` varchar(40) NOT NULL,
`trsform` varchar(40) NOT NULL,
`tgen` datetime IKKE NULL,
`tterm` datetime,
`tstatus` tinyint(1) IKKE NULL
) ENGINE=ARKIVKOMMENTAR="billettarkiv";
____SQL;
$result = $this -> db -> getConnection()-> exec($sql );

$sql =<<<____SQL
LAG TABELL HVIS IKKE FINNES `request_hist` (
`rqid` int(11) IKKE NULL,
`rqtid` int(11) NOT NULL,
`rqsid` int(11) IKKE NULL,
`rqdate` datetime IKKE NULL,
`rqcode` tinyint(1) IKKE NULL,
`rssid` int(11) NOT NULL,
`rsdate` datetime,
`rscode` tinyint(1)
) ENGINE=ARKIV KOMMENTAR="be om arkiv";
____SQL;
$result = $this -> db -> getConnection()-> exec($sql );

$sql =<<<____SQL
LAG TABELL HVIS IKKE FINNES `relay_hist` (
`rqid` int(5) IKKE NULL,
`sdesc` varchar(40) IKKE NULL,
`rqemail` varchar(40) NOT NULL,
`sid` int(11) IKKE NULL,
`rlsid` int(11) IKKE NULL,
`dcode` varchar(5) IKKE NULL
) ENGINE=ARKIVKOMMENTAR="reléarkiv";
____SQL;
$result = $this -> db -> getConnection()-> exec($sql );
?>
Å kutte den i individuelle søk løser problemet.