Ετοιμάστηκαν ερωτήματα pdo. Πρόσθετες δυνατότητες MySQL. Λειτουργίες απόκτησης δεδομένων

Οι περισσότερες βάσεις δεδομένων υποστηρίζουν την έννοια των προετοιμασμένων ερωτημάτων. Τι είναι? Αυτό μπορεί να περιγραφεί ως κάποιο είδος μεταγλωττισμένου προτύπου ερωτήματος SQL που θα εκτελεστεί από την εφαρμογή και θα διαμορφωθεί με παραμέτρους εισόδου. Τα προετοιμασμένα ερωτήματα έχουν δύο βασικά πλεονεκτήματα:

  • Το ερώτημα πρέπει να προετοιμαστεί μία φορά και μετά μπορεί να εκτελεστεί όσες φορές χρειάζεται, τόσο με τις ίδιες όσο και με διαφορετικές παραμέτρους. Όταν προετοιμάζεται ένα ερώτημα, το DBMS το αναλύει, συντάσσει και βελτιστοποιεί το σχέδιο εκτέλεσής του. Στην περίπτωση πολύπλοκων ερωτημάτων, αυτή η διαδικασία μπορεί να διαρκέσει σημαντικό χρόνο και να επιβραδύνει αισθητά την εφαρμογή εάν είναι απαραίτητο να εκτελεστεί το ερώτημα πολλές φορές με διαφορετικές παραμέτρους. Όταν χρησιμοποιείται ένα έτοιμο ερώτημα, το DBMS αναλύει/μεταγλωττίζει/βελτιστοποιεί ένα ερώτημα οποιασδήποτε πολυπλοκότητας μόνο μία φορά και η εφαρμογή εκκινεί το ήδη προετοιμασμένο πρότυπο για εκτέλεση. Τα προετοιμασμένα ερωτήματα με αυτόν τον τρόπο καταναλώνουν λιγότερους πόρους και εκτελούνται πιο γρήγορα.
  • Οι προετοιμασμένες παράμετροι ερωτήματος δεν χρειάζεται να διαφεύγουν με εισαγωγικά. ο οδηγός το κάνει αυτόματα. Εάν η εφαρμογή χρησιμοποιεί αποκλειστικά προετοιμασμένα ερωτήματα, ο προγραμματιστής μπορεί να είναι σίγουρος ότι δεν μπορούν να γίνουν εγχύσεις SQL (ωστόσο, εάν άλλα μέρη του κειμένου ερωτήματος είναι γραμμένα με χαρακτήρες χωρίς διαφυγή, οι ενέσεις SQL εξακολουθούν να είναι δυνατές· εδώ μιλαμεσχετικά με τις παραμέτρους).

Τα προετοιμασμένα ερωτήματα είναι επίσης χρήσιμα στο ότι το PDO μπορεί να τα μιμηθεί εάν το πρόγραμμα οδήγησης της βάσης δεδομένων δεν διαθέτει αυτήν τη λειτουργία. Αυτό σημαίνει ότι μια εφαρμογή μπορεί να χρησιμοποιήσει την ίδια τεχνική πρόσβασης δεδομένων ανεξάρτητα από τις δυνατότητες του DBMS.

Beispiel #1 Επαναλαμβανόμενα ένθετα βάσης δεδομένων χρησιμοποιώντας προετοιμασμένα ερωτήματα

όνομαΚαι αξία, οι οποίες αντικαθιστούν τις αντίστοιχες ψευδομεταβλητές:

$stmt = $dbh -> προετοιμασία( "ΕΙΣΑΓΩΓΗ ΣΤΟ ΜΗΤΡΩΟ (όνομα, τιμή) ΤΙΜΕΣ (:name, :value)");
$stmt -> bindParam(":name" , $name );
$stmt -> bindParam(":value" , $value );

// εισαγωγή μιας γραμμής
$name = "ένα" ;
$value = 1 ;
$stmt -> execute();

$name = " δύο " ;
$value = 2 ;
$stmt -> execute();
?>

Beispiel #2 Επαναλαμβανόμενα ένθετα βάσης δεδομένων χρησιμοποιώντας προετοιμασμένα ερωτήματα

Σε αυτό το παράδειγμα, ένα ερώτημα INSERT εκτελείται 2 φορές με διαφορετικές αξίες όνομαΚαι αξίαπου αντικαθιστούν ψευδο-μεταβλητές ? .

$stmt = $dbh -> προετοιμασία( "ΕΙΣΑΓΩΓΗ ΣΤΟ ΜΗΤΡΩΟ (όνομα, τιμή) ΤΙΜΕΣ (?, ?)");
$stmt -> bindParam(1 , $name );
$stmt -> bindParam(2 , $value );

// εισαγωγή μιας γραμμής
$name = "ένα" ;
$value = 1 ;
$stmt -> execute();

// τώρα μια άλλη συμβολοσειρά με διαφορετικές τιμές
$name = " δύο " ;
$value = 2 ;
$stmt -> execute();
?>

Beispiel #3 Ανάκτηση δεδομένων χρησιμοποιώντας προετοιμασμένα ερωτήματα

Σε αυτό το παράδειγμα, γίνεται μια επιλογή από τη βάση δεδομένων με το κλειδί που εισάγει ο χρήστης μέσω της φόρμας. Η εισαγωγή του χρήστη αναφέρεται αυτόματα, επομένως δεν υπάρχει κίνδυνος εισαγωγής SQL.

Εάν το DBMS υποστηρίζει παραμέτρους εξόδου, η εφαρμογή μπορεί να τις χρησιμοποιήσει καθώς και παραμέτρους εισόδου. Οι παράμετροι εξόδου χρησιμοποιούνται συνήθως για την ανάκτηση δεδομένων από αποθηκευμένες διαδικασίες. Η χρήση παραμέτρων εξόδου είναι κάπως πιο περίπλοκη, καθώς ο προγραμματιστής πρέπει να γνωρίζει το μέγιστο μέγεθος των εξαγόμενων τιμών στο στάδιο της ρύθμισης αυτών των παραμέτρων. Εάν η τιμή που ανακτήθηκε είναι μεγαλύτερη από την αναμενόμενη, θα εμφανιστεί σφάλμα.

Beispiel #4 Κλήση αποθηκευμένης διαδικασίας χωρίς παραμέτρους

$stmt = $dbh -> προετοιμασία("CALL sp_returns_string(?)" );
$stmt -> bindParam(1 , $return_value , PDO :: PARAM_STR , 4000 );

// κλήση μιας αποθηκευμένης διαδικασίας
$stmt -> execute();

Τυπώνω «Η διαδικασία επέστρεψε$return_value\n" ;
?>

Μπορείτε να ορίσετε την παράμετρο ταυτόχρονα είσοδο και έξοδο. η σύνταξη είναι ίδια με τις παραμέτρους εξόδου. Στο ακόλουθο παράδειγμα, η συμβολοσειρά "hello" μεταβιβάζεται σε μια αποθηκευμένη διαδικασία και, στη συνέχεια, αυτή η συμβολοσειρά θα αντικατασταθεί από την τιμή επιστροφής.

Παράδειγμα #5 Κλήση αποθηκευμένης διαδικασίας με παράμετρο εισόδου/εξόδου

$stmt = $dbh -> προετοιμασία( "ΚΛΗΣΗ sp_takes_string_returns_string(?)");
$value = "γεια" ;!}
$stmt -> bindParam(1 , $value , PDO :: PARAM_STR | PDO :: PARAM_INPUT_OUTPUT , 4000 );

// κλήση μιας αποθηκευμένης διαδικασίας
$stmt -> execute();

Τυπώνω «Η διαδικασία επέστρεψε$value\n" ;
?>

(πίνακας("% $_GET [ όνομα ] %" ));
?>










Το PDO έχει τη δική του επινοημένη μέθοδο σύνδεσης που ονομάζεται . Επιπλέον, κατά τη διάρκεια της σύνδεσης, μπορείτε να ορίσετε ένα σκοτεινό σύννεφο επιλογών, μερικές από τις οποίες είναι εξαιρετικά χρήσιμες. Μπορείτε να βρείτε μια πλήρη λίστα, αλλά μόνο μερικά είναι σημαντικά.

Παράδειγμα σωστής σύνδεσης:

$host = "127.0.0.1" ;
$db = "τεστ" ;
$user = "root" ;
$pass = " " ;
$charset = "utf8" ;

$dsn = "mysql:host= $host ;dbname= $db ;charset= $charset " ;
$opt = [
ΠΟΠ :: ATTR_ERRMODE => ΠΟΠ :: ERRMODE_EXCEPTION ,
ΠΟΠ :: ATTR_DEFAULT_FETCH_MODE => ΠΟΠ :: FETCH_ASSOC ,
PDO::ATTR_EMULATE_PREPARES => false,
];
$pdo = νέο ΠΟΠ ($dsn , $user , $pass , $opt );

Τι συμβαίνει εδώ?

Το $dsn καθορίζει τον τύπο της βάσης δεδομένων που θα εργαστεί (mysql), τον κεντρικό υπολογιστή, το όνομα της βάσης δεδομένων και το σύνολο χαρακτήρων.
- ακολουθούμενο από όνομα χρήστη και κωδικό πρόσβασης
- μετά την οποία καθορίζεται μια σειρά επιλογών, η οποία δεν αναφέρεται σε κανένα από τα εγχειρίδια.

Παρά το γεγονός ότι αυτός ο πίνακας είναι ένα εξαιρετικά χρήσιμο πράγμα, όπως αναφέρθηκε παραπάνω. Το πιο σημαντικό είναι ότι ο τρόπος έκδοσης σφαλμάτων θα πρέπει να ορίζεται μόνο με τη μορφή εξαιρέσεων.
- Πρώτον, επειδή σε όλες τις άλλες λειτουργίες PDO δεν αναφέρει τίποτα κατανοητό σχετικά με το σφάλμα,
- δεύτερον, επειδή μια εξαίρεση περιέχει πάντα ένα αναντικατάστατο ίχνος στοίβας,
- Τρίτον - οι εξαιρέσεις είναι εξαιρετικά βολικές στον χειρισμό.

Επιπλέον, είναι πολύ βολικό να ρυθμίσετε το FETCH_MODE από προεπιλογή, ώστε να μην το γράφετε σε ΚΑΘΕ αίτημα, όπως αρέσει πολύ στα επιμελή χάμστερ.
Επίσης εδώ μπορείτε να ρυθμίσετε τη λειτουργία pconnect, εξομοίωση προετοιμασμένων εκφράσεων και πολλές άλλες τρομακτικές λέξεις.

Ως αποτέλεσμα, παίρνουμε τη μεταβλητή $pdo, με την οποία εργαζόμαστε περαιτέρω σε ολόκληρο το σενάριο.

Μπορείτε να χρησιμοποιήσετε δύο μεθόδους για να εκτελέσετε ερωτήματα.
Εάν δεν περάσουν μεταβλητές στο ερώτημα, τότε μπορείτε να χρησιμοποιήσετε τη συνάρτηση query(). Θα εκτελέσει το αίτημα και θα επιστρέψει ένα ειδικό αντικείμενο - δήλωση ΠΟΠ. Μπορεί να συγκριθεί πολύ κατά προσέγγιση με τον πόρο mysql που επιστρέφεται από την mysql_query(). Μπορείτε να λάβετε δεδομένα από αυτό το αντικείμενο τόσο με τον παραδοσιακό τρόπο, μέσω while και μέσω foreach (). Μπορείτε επίσης να ζητήσετε να επιστρέψετε τα ληφθέντα δεδομένα σε ειδική μορφή, όπως περιγράφεται παρακάτω.
$stmt = $pdo -> query("SELECT name FROM users" );
ενώ ($row = $stmt -> fetch())
{
}

Εάν τουλάχιστον μία μεταβλητή μεταβιβαστεί στο αίτημα, τότε αυτό το αίτημα πρέπει να εκτελεστεί χωρίς αποτυχία μόνο μέσω προετοιμασμένες εκφράσεις. Τι είναι? Αυτό είναι ένα κανονικό ερώτημα SQL, στο οποίο τοποθετείται ένας ειδικός δείκτης αντί για μια μεταβλητή - ένα σύμβολο κράτησης θέσης. Το PDO υποστηρίζει θέσεις κράτησης θέσης (?), για τις οποίες είναι σημαντική η σειρά των μεταβλητών που έχουν περάσει, και ονομασμένα κράτη μέλη θέσης (:name), για τα οποία η σειρά δεν είναι σημαντική. Παραδείγματα:
$sql = ;
$sql = ;

Για να εκτελεστεί ένα τέτοιο ερώτημα, πρέπει πρώτα να προετοιμαστεί χρησιμοποιώντας τη συνάρτηση προετοιμασία(). Επιστρέφει επίσης μια δήλωση ΠΟΠ, αλλά χωρίς δεδομένα ακόμα. Για να τις λάβετε, πρέπει να εκτελέσετε αυτό το αίτημα, αφού περάσετε μεταβλητές σε αυτό. Μπορείτε να το στείλετε με δύο τρόπους:
Τις περισσότερες φορές, μπορείτε απλά να εκτελέσετε τη μέθοδο execute(), περνώντας της έναν πίνακα με μεταβλητές:
$stmt = $pdo -> προετοιμασία( "ΕΠΙΛΕΞΤΕ όνομα ΑΠΟ χρήστες ΠΟΥ email = ?");
$stmt -> execute(array($email ));

$stmt = $pdo -> προετοιμασία( "ΕΠΙΛΕΞΤΕ όνομα ΑΠΟ χρήστες WHERE email = :email");
$stmt -> execute (array("email" => $email ));
Όπως μπορείτε να δείτε, στην περίπτωση των ονομασμένων θέσεων κράτησης θέσης, πρέπει να περάσει ένας πίνακας για να execute(), στον οποίο τα κλειδιά πρέπει να ταιριάζουν με τα ονόματα των θέσεων κράτησης θέσης.

Μερικές φορές, πολύ σπάνια, μπορεί να απαιτείται ο δεύτερος τρόπος, όταν οι μεταβλητές δεσμεύονται πρώτα στο αίτημα μία κάθε φορά, χρησιμοποιώντας bindValue() / bindParam(), και μετά εκτελούνται μόνο. Σε αυτήν την περίπτωση, τίποτα δεν περνά για εκτέλεση (). Ένα παράδειγμα μπορεί να βρεθεί στο εγχειρίδιο.
Χρησιμοποιώντας αυτήν τη μέθοδο, πρέπει πάντα να προτιμάται η bindValue(); επειδή η συμπεριφορά της bindParam() δεν είναι προφανής στους αρχάριους και θα οδηγήσει σε προβλήματα.

Μετά από αυτό, μπορείτε να χρησιμοποιήσετε τη δήλωση ΠΟΠ με τους ίδιους τρόπους όπως παραπάνω. Για παράδειγμα, μέσω foreach:
$stmt = $pdo -> προετοιμασία( "ΕΠΙΛΕΞΤΕ όνομα ΑΠΟ χρήστες ΠΟΥ email = ?");
$stmt ->
foreach ($stmt ως $σειρά)
{
echo $row [ "όνομα" ] . "\n" ;
}

ΣΠΟΥΔΑΙΟΣ:Οι προετοιμασμένες εκφράσεις είναι ο κύριος λόγος για τη χρήση ΠΟΠ ως έχει ο μοναδικός ασφαλή τρόπο εκτέλεση ερωτημάτων SQL που περιλαμβάνουν μεταβλητές.

Επίσης, η προετοιμασία() / execute() μπορεί να χρησιμοποιηθεί για την επανειλημμένη εκτέλεση ενός ερωτήματος που μόλις προετοιμαστεί με διαφορετικά σύνολα δεδομένων. Στην πράξη, αυτό είναι εξαιρετικά σπάνια απαραίτητο και δεν επιφέρει ιδιαίτερη αύξηση της ταχύτητας. Αλλά σε περίπτωση που χρειαστεί να υποβάλετε πολλά από τον ίδιο τύπο αιτημάτων, μπορείτε να γράψετε ως εξής:

$data = πίνακας(
1 => 1000,
5 => 300,
9 => 200,
);

$stmt = $pdo -> προετοιμασία( "UPDATE users SET bonus = bonus + ? WHERE id = ?");
foreach ($data ως $id => $bonus )
{
$stmt -> execute([ $bonus , $id ]);
}

Εδώ προετοιμάζουμε το ερώτημα μία φορά και μετά το εκτελούμε πολλές φορές.

Έχουμε ήδη γνωρίσει τη μέθοδο fetch() παραπάνω, η οποία χρησιμεύει για τη διαδοχική ανάκτηση σειρών από τη βάση δεδομένων. Αυτή η μέθοδος είναι ανάλογη με τη συνάρτηση mysq_fetch_array() και παρόμοιες, αλλά λειτουργεί διαφορετικά: αντί για πολλές συναρτήσεις, χρησιμοποιείται μία εδώ, αλλά η συμπεριφορά της ορίζεται από την παράμετρο που πέρασε. Θα γράψω περισσότερα για αυτές τις επιλογές αργότερα, αλλά ως γρήγορη συμβουλή, θα συνιστούσα να χρησιμοποιήσετε το fetch() σε λειτουργία FETCH_LAZY:
$stmt = $pdo -> προετοιμασία( "ΕΠΙΛΕΞΤΕ όνομα ΑΠΟ χρήστες ΠΟΥ email = ?");
$stmt -> execute([ $_GET [ "email" ]]);
ενώ ($row = $stmt -> fetch (PDO::FETCH_LAZY ))
{
echo $σειρά [ 0 ] . "\n" ;
echo $row [ "όνομα" ] . "\n" ;
echo $row -> name . "\n" ;
}

Σε αυτήν τη λειτουργία, δεν χάνεται επιπλέον μνήμη και, επιπλέον, η πρόσβαση στις στήλες είναι δυνατή με οποιονδήποτε από τους τρεις τρόπους - μέσω ενός ευρετηρίου, ενός ονόματος ή μιας ιδιότητας.

Επίσης, η δήλωση PDO έχει μια βοηθητική συνάρτηση για να πάρει την τιμή μιας στήλης. Είναι πολύ βολικό εάν ζητήσουμε μόνο ένα πεδίο - σε αυτήν την περίπτωση, ο όγκος της γραφής μειώνεται σημαντικά:
$stmt = $pdo -> προετοιμασία( "ΕΠΙΛΟΓΗ ονόματος ΑΠΟ τον πίνακα WHERE id=?");
$stmt -> execute(array($id ));
$name = $stmt -> fetchColumn();

Αλλά η πιο ενδιαφέρουσα συνάρτηση, με τη μεγαλύτερη λειτουργικότητα, είναι η fetchAll(). Είναι αυτή που κάνει την PDO μια βιβλιοθήκη υψηλού επιπέδου για εργασία με τη βάση δεδομένων, και όχι απλώς ένα πρόγραμμα οδήγησης χαμηλού επιπέδου.

Η FetchAll() επιστρέφει έναν πίνακα που περιέχει όλες τις σειρές που επιστρέφονται από το ερώτημα. Από το οποίο μπορούν να εξαχθούν δύο συμπεράσματα:
1. Αυτή η συνάρτηση δεν πρέπει να χρησιμοποιείται όταν το ερώτημα επιστρέφει πολλά δεδομένα. Σε αυτήν την περίπτωση, είναι καλύτερο να χρησιμοποιήσετε έναν παραδοσιακό βρόχο με fetch()
2. Δεδομένου ότι στις σύγχρονες εφαρμογές PHP τα δεδομένα δεν εμφανίζονται ποτέ αμέσως μετά την παραλαβή, αλλά μεταβιβάζονται στο πρότυπο για αυτό, το fetchAll () γίνεται απλά απαραίτητο, επιτρέποντάς σας να μην γράφετε κύκλους με μη αυτόματο τρόπο και έτσι να μειώνετε την ποσότητα του κώδικα.

Λήψη ενός απλού πίνακα.
Αυτή η συνάρτηση που καλείται χωρίς παραμέτρους, επιστρέφει έναν κανονικό πίνακα ευρετηρίου που περιέχει σειρές από τη βάση δεδομένων στη μορφή που καθορίζεται στο FETCH_MODE από προεπιλογή. Οι σταθερές PDO::FETCH_NUM, PDO::FETCH_ASSOC, PDO::FETCH_OBJ μπορούν να αλλάξουν τη μορφή αμέσως.

Πάρτε μια στήλη.
Μερικές φορές χρειάζεται να αποκτήσετε έναν απλό μονοδιάστατο πίνακα ζητώντας ένα μόνο πεδίο από μια δέσμη συμβολοσειρών. Για αυτό, χρησιμοποιείται η λειτουργία PDO::FETCH_COLUMN.
$data = $pdo -> query("SELECT name FROM users" )-> fetchAll(PDO::FETCH_COLUMN );
πίνακας(
0 => "Γιάννης",
1 => "Mike" ,
2 => "Μαρία" ,
3 => "Kathy" ,
)

Λάβετε ζεύγη κλειδιών-τιμών.
Επίσης μια δημοφιλής μορφή όταν είναι επιθυμητό να λαμβάνεται η ίδια στήλη, αλλά ευρετηριασμένη όχι με αριθμούς, αλλά με ένα από τα πεδία. Η σταθερά PDO::FETCH_KEY_PAIR είναι υπεύθυνη για αυτό.
$data = $pdo -> query("SELECT id, name FROM users" )-> fetchAll(PDO::FETCH_KEY_PAIR );
πίνακας(
104 => "Γιάννης" ,
110
120 => "Μαρία" ,
121
)

Λάβετε όλες τις σειρές ευρετηριασμένες από ένα πεδίο.
Είναι επίσης συχνά απαραίτητο να λαμβάνετε όλες τις σειρές από τη βάση δεδομένων, αλλά και να καταχωρούνται στο ευρετήριο όχι με αριθμούς, αλλά από ένα μοναδικό πεδίο. Αυτό κάνει η σταθερά PDO::FETCH_UNIQUE.
$data = $pdo -> query("SELECT * FROM users" )-> fetchAll(PDO::FETCH_UNIQUE );
πίνακας(
104 => πίνακας (
"name" => "Γιάννης" ,
"car" => "Toyota" ,
),
110 => πίνακας (
"name" => "Mike" ,
"car" => "Ford" ,
),
120 => πίνακας (
"name" => "Μαρία" ,
"car" => "Mazda" ,
),
121 => πίνακας (
"name" => "Kathy" ,
"car" => "Mazda" ,
),
)

Θα πρέπει να θυμόμαστε ότι το πρώτο πεδίο στη στήλη πρέπει να είναι ένα μοναδικό πεδίο.

Συνολικά, υπάρχουν πάνω από δώδεκα διαφορετικοί τρόποι λήψης δεδομένων σε ΠΟΠ. Επιπλέον, μπορείτε να τα συνδυάσετε! Αλλά αυτό είναι ένα θέμα για ένα ξεχωριστό άρθρο.

Όταν εργάζεστε με προετοιμασμένες εκφράσεις, θα πρέπει να καταλάβετε ότι ένα σύμβολο κράτησης θέσης μπορεί να αντικαταστήσει μόνο μια συμβολοσειρά ή έναν αριθμό. κανενα απο τα δυο λέξη-κλειδί, ούτε ένα αναγνωριστικό, ούτε ένα μέρος μιας συμβολοσειράς ή ένα σύνολο συμβολοσειρών δεν μπορούν να αντικατασταθούν μέσω ενός σύμβολο κράτησης θέσης. Επομένως, για LIKE, πρέπει πρώτα να προετοιμάσετε ολόκληρη τη συμβολοσειρά αναζήτησης και, στη συνέχεια, να την αντικαταστήσετε στο ερώτημα:

$name = " % $name % " ;
$stm = $pdo -> προετοιμασία( "ΕΠΙΛΟΓΗ * ΑΠΟ πίνακα ΠΟΥ το όνομα ΑΡΕΣΕΙ ;");
$stm -> execute(array($name ));
$data = $stm -> fetchAll();

Λοιπόν, καταλαβαίνεις την ιδέα. Είναι κακό και εδώ. Το PDO δεν παρέχει καθόλου εργαλεία για εργασία με αναγνωριστικά και πρέπει να μορφοποιηθούν με τον παλιό τρόπο, χειροκίνητα (ή να κοιτάξουμε, τελικά, προς το SafeMysql , στο οποίο αυτό, όπως και πολλά άλλα ζητήματα, επιλύεται απλά και κομψά).
Θα πρέπει να θυμόμαστε ότι οι κανόνες για τη μορφοποίηση των αναγνωριστικών διαφέρουν για διαφορετικές βάσεις δεδομένων.

Στο mysql, για να μορφοποιήσετε μη αυτόματα ένα αναγνωριστικό, πρέπει να κάνετε δύο πράγματα:
- περικλείστε το σε πίσω μονά εισαγωγικά (backticks, "`").
- κλιμακώστε αυτούς τους χαρακτήρες στο εσωτερικό του αναγνωριστικού διπλασιάζοντας.

$field = "`" . str_replace ("`", "``" , $_GET [ "πεδίο" ]). "`";
$sql = $field" ;

Ωστόσο, υπάρχει μια προειδοποίηση εδώ. Η μορφοποίηση από μόνη της μπορεί να μην είναι αρκετή. Ο παραπάνω κώδικας θα μας προστατεύσει από την κλασική ένεση, αλλά σε ορισμένες περιπτώσεις ο εχθρός μπορεί να γράψει κάτι ανεπιθύμητο εάν αντικαταστήσουμε αλόγιστα τα ονόματα πεδίων και πινάκων απευθείας στο ερώτημα. Για παράδειγμα, υπάρχει ένα πεδίο διαχειριστή στον πίνακα χρηστών. Εάν τα ονόματα των εισερχόμενων πεδίων δεν φιλτράρονται, τότε σε αυτό το πεδίο, όταν δημιουργείται αυτόματα ένα αίτημα από ένα POST, οποιοσδήποτε ανόητος θα γράψει τυχόν λάθη.

Επομένως, τα ονόματα των πινάκων και των πεδίων που προέρχονται από τον χρήστη θα πρέπει να ελέγχονται ως προς την εγκυρότητά τους, όπως στο παρακάτω παράδειγμα

Οποιοσδήποτε κώδικας ενσωμάτωσης που μπορεί να δει κανείς σε πολλά σεμινάρια εμπνέει μελαγχολία και επιθυμία να σκοτώσει ένα upsten. Κατασκευές πολλών χιλιομέτρων με την επανάληψη των ίδιων ονομάτων - σε ευρετήρια $_POST, σε ονόματα μεταβλητών, σε ονόματα πεδίων σε αίτημα, σε ονόματα κράτησης θέσης σε αίτημα, σε ονόματα κράτησης θέσης και ονόματα μεταβλητών κατά τη δέσμευση.
Κοιτάζοντας αυτόν τον κωδικό με κάνει να θέλω να σκοτώσω κάποιον ή τουλάχιστον να τον κάνω λίγο πιο σύντομο.

Αυτό μπορεί να γίνει υιοθετώντας τη σύμβαση ότι τα ονόματα πεδίων στη φόρμα θα ταιριάζουν με τα ονόματα πεδίων στον πίνακα. Στη συνέχεια, αυτά τα ονόματα μπορούν να παρατίθενται μόνο μία φορά (για προστασία από την αντικατάσταση που αναφέρθηκε παραπάνω) και χρησιμοποιήστε μια μικρή βοηθητική συνάρτηση για να δημιουργήσετε ένα ερώτημα, το οποίο, λόγω των ιδιαιτεροτήτων του mysql, είναι κατάλληλο τόσο για ερωτήματα INSERT όσο και για UPDATE:

συνάρτηση pdoSet ($allowed, & $values‎, $source = array()) (
$set = " " ;
$values ​​= array();
εάν (! $source ) $source = & $_POST ;
foreach ($επιτρέπεται ως $field ) (
if (isset($source [ $field ])) (
$set .= "`" . str_replace ("`" , "``" , $field ). """. "=: $field , " ;
$values ​​[ $field ] = $πηγή [ $field ];
}
}
return substr ($set , 0 , - 2 );
}

Κατά συνέπεια, για να εισαγάγετε τον κωδικό θα είναι

$allowed = array("name" , "surname" , "email" ); // επιτρεπόμενα πεδία
$sql = "ΕΙΣΑΓΩΓΗ ΣΤΟ ΣΕΤ χρηστών " . pdoSet($allowed, $values);
$stm = $dbh -> προετοιμασία($sql );
$stm -> execute($values);

Και για την ενημέρωση - αυτό:

$allowed = array("name" , "επώνυμο" , "email" , "password" ); // επιτρεπόμενα πεδία
$_POST [ "password" ] = MD5 ($_POST [ "login" ]. $_POST [ "password" ]);
$sql = "ΕΝΗΜΕΡΩΣΗ ΣΕΤ χρηστών " . pdoSet($allowed, $values). " WHERE id = :id" ;
$stm = $dbh -> προετοιμασία($sql );
$values["id"] = $_POST["id"];
$stm -> execute($values);

Όχι πολύ αποτελεσματικό, αλλά πολύ αποτελεσματικό. Επιτρέψτε μου να σας υπενθυμίσω, παρεμπιπτόντως, ότι εάν χρησιμοποιείτε την Κλάση για ασφαλή και άνετη εργασία με τη MySQL, τότε όλα αυτά γίνονται σε δύο γραμμές.

ΠΟΠ και λέξεις-κλειδιά
Εδώ, εκτός από φιλτράρισμα, είναι αδύνατο να σκεφτείς κάτι. Επομένως, είναι ανόητο να εκτελούνται όλοι οι τελεστές που δεν καθορίζονται άμεσα στο αίτημα μέσω της λευκής λίστας:

$dirs = array("ASC" , "DESC" );
$key = array_search($_GET [ "dir" ], $dirs ));
$dir = $παραγγελίες [ $key ];
$sql = "ΕΠΙΛΟΓΗ * ΑΠΟ "Πίνακας" ORDER BY$field $dir" ;

Ορος Π.Ο.Πείναι συντομογραφία του Αντικείμενα δεδομένων PHP. Όπως υποδηλώνει το όνομα, αυτή η τεχνολογία σας επιτρέπει να εργάζεστε με τα περιεχόμενα της βάσης δεδομένων μέσω αντικειμένων.

Γιατί όχι myqli ή mysql;

Τις περισσότερες φορές, όσον αφορά τις νέες τεχνολογίες, τίθεται το ερώτημα για τα πλεονεκτήματά τους σε σχέση με τα παλιά καλά και δοκιμασμένα εργαλεία, καθώς και για τη μεταφορά τρεχόντων και παλαιών έργων σε αυτά.

Αντικειμενοστραφή ΠΟΠ

PHPαναπτύσσεται πολύ ενεργά και στοχεύει να γίνει ένα από τα καλύτερα εργαλεία για την ταχεία ανάπτυξη διαδικτυακών εφαρμογών, τόσο μαζικού όσο και εταιρικού επιπέδου.

Μιλώντας για PHP, θα εννοούμε σύγχρονο αντικειμενοστραφή PHP, που σας επιτρέπει να γράψετε γενικό κώδικα που είναι εύκολο να δοκιμαστεί και να επαναχρησιμοποιηθεί.

Χρήση Π.Ο.Πσας επιτρέπει να φέρετε την εργασία με τη βάση δεδομένων σε αντικειμενοστραφή επίπεδο και να βελτιώσετε τη φορητότητα του κώδικα. Στην πραγματικότητα, η χρήση Π.Ο.Πόχι τόσο δύσκολο όσο θα μπορούσε κανείς να σκεφτεί.

Αφαίρεση

Ας προσποιηθούμε ότι είμαστε ήδη πολύς καιρόςανάπτυξη μιας εφαρμογής χρησιμοποιώντας MySQL. Και τότε, σε ένα σημείο, καθίσταται απαραίτητο να αντικατασταθεί MySQLεπί PostgreSQL.

Τουλάχιστον, θα πρέπει να αντικαταστήσουμε όλες τις κλήσεις mysqli_connect() (mysql_connect())επί pg_connect()και, κατ' αναλογία, άλλες συναρτήσεις που χρησιμοποιούνται για την αναζήτηση και την επεξεργασία δεδομένων.

Χρησιμοποιώντας Π.Ο.Π, θα περιοριστούμε στην αλλαγή μερικών παραμέτρων στα αρχεία διαμόρφωσης.

Δέσμευση παραμέτρων

Η χρήση δεσμευμένων παραμέτρων παρέχει μεγαλύτερη ευελιξία στο ερώτημα και βελτιώνει την προστασία έναντι SQLενέσεις.

Λήψη δεδομένων ως αντικειμένων

Αυτοί που ήδη χρησιμοποιούν ORM(αντικειμενική-σχεσιακή αντιστοίχιση - αντικειμενική-σχεσιακή αντιστοίχιση δεδομένων), για παράδειγμα, Δόγμαγνωρίζουν την ευκολία της παρουσίασης δεδομένων από πίνακες βάσης δεδομένων ως αντικείμενα. Π.Ο.Πσας επιτρέπει να λαμβάνετε δεδομένα με τη μορφή αντικειμένων και χωρίς χρήση ORM.

Η επέκταση mysql δεν υποστηρίζεται πλέον

Υποστήριξη επέκτασης mysqlαφαιρεθεί οριστικά από το νέο PHP 7. Εάν σκοπεύετε να μετεγκαταστήσετε το έργο σας σε νέα έκδοση PHP, θα πρέπει ήδη να χρησιμοποιείτε τουλάχιστον το mysqli σε αυτό. Φυσικά, είναι καλύτερο να αρχίσετε να χρησιμοποιείτε Π.Ο.Παν δεν το έχεις κάνει ήδη.

Μου φαίνεται ότι αυτοί οι λόγοι είναι αρκετοί για να γείρουν τη ζυγαριά προς τη χρήση του Π.Ο.Π. Επιπλέον, δεν χρειάζεται να εγκαταστήσετε τίποτα επιπλέον.

Έλεγχος για ΠΟΠ στο σύστημα

εκδόσεις PHP 5.5και παραπάνω, τις περισσότερες φορές, περιέχουν ήδη μια επέκταση για εργασία Π.Ο.Π. Για έλεγχο, απλώς εκτελέστε μια απλή εντολή στην κονσόλα:

php -i | grep "pdo"

Τώρα ας το ανοίξουμε σε οποιοδήποτε πρόγραμμα περιήγησης και ας βρούμε τα απαραίτητα δεδομένα αναζητώντας τη συμβολοσειρά Π.Ο.Π.

Γνωριμία με Π.Ο.Π

Η διαδικασία εργασίας με Π.Ο.Πόχι πολύ διαφορετικό από το παραδοσιακό. Γενικά η διαδικασία χρήσης Π.Ο.Πμοιάζει με αυτό:

  1. Σύνδεση βάσης δεδομένων.
  2. Εάν είναι απαραίτητο, προετοιμασία αιτήματος και δεσμευτικές παραμέτρους.
  3. Εκτέλεση αιτήματος.

Σύνδεση βάσης δεδομένων

Για να συνδεθείτε στη βάση δεδομένων, πρέπει να δημιουργήσετε ένα νέο αντικείμενο Π.Ο.Πκαι περάστε το το όνομα της πηγής δεδομένων, επίσης γνωστή ως DSN.

Γενικά, DSNαποτελείται από το όνομα του προγράμματος οδήγησης που χωρίζεται με άνω και κάτω τελεία από τη συμβολοσειρά σύνδεσης που είναι συγκεκριμένη για κάθε πρόγραμμα οδήγησης Π.Ο.Π.

Για MySQL, η σύνδεση γίνεται ως εξής:

$connection = new PDO("mysql:host=localhost;dbname=mydb;charset=utf8", "root", "root");

$σύνδεση = νέο ΠΟΠ( "mysql:host=localhost;dbname=mydb;charset=utf8", "root" , "root" );

ΣΕ αυτή η υπόθεση, DSNπεριέχει το όνομα του οδηγού mysql, προσδιορίζοντας τον κεντρικό υπολογιστή (πιθανή μορφή host=HOSTNAME:PORT), όνομα βάσης δεδομένων, κωδικοποίηση, όνομα χρήστη MySQLκαι τον κωδικό του.

Αιτήσεων

Διαφορετικός mysqli_query(), V Π.Ο.ΠΥπάρχουν δύο τύποι αιτημάτων:

  • Επιστρεφόμενο αποτέλεσμα ( επιλογή, εμφάνιση);
  • Δεν επιστρέφει κανένα αποτέλεσμα ( εισάγετε, λεπτομέρειακαι άλλοι).

Πρώτα απ 'όλα, ας εξετάσουμε τη δεύτερη επιλογή.

Εκτέλεση ερωτημάτων

Εξετάστε ένα παράδειγμα εκτέλεσης ενός ερωτήματος χρησιμοποιώντας ένα παράδειγμα εισάγετε.

$connection->exec("INSERT INTO users VALUES (1, "somevalue"");

$connection -> exec();

Φυσικά, αυτό το ερώτημα επιστρέφει τον αριθμό των επηρεαζόμενων σειρών και μπορείτε να το δείτε ως εξής.

$affectedRows = $connection->exec("INSERT INTO users VALUES (1, "somevalue""); echo $affectedRows;

$affectedRows = $connection -> exec( "INSERT INTO users VALUES (1, "somevalue"") ;

echo $affectedRows ;

Λήψη αποτελεσμάτων ερωτήματος

Σε περίπτωση χρήσης mysqli_query(), ο κωδικός θα μπορούσε να είναι ο εξής.

$result = mysql_query("SELECT * FROM users"); while($row = mysql_fetch_assoc($result)) ( echo $row["id"] . " " . $row["name"];)

$result = mysql_query ("SELECT * FROM users" ) ;

ενώ ($row = mysql_fetch_assoc ($result ) ) (

Για Π.Ο.Π, ο κώδικας θα είναι απλούστερος και πιο συνοπτικός.

foreach($connection->query("SELECT * FROM users") ως $row) ( echo $row["id"] . " " . $row["name"]; )

foreach ($connection -> query("SELECT * FROM users" ) as $row ) (

echo $row [ "id" ] . " " . $row [ "όνομα" ] ;

Λειτουργίες απόκτησης δεδομένων

Οπως λέμε mysqli, Π.Ο.Πσας επιτρέπει να λαμβάνετε δεδομένα διαφορετικούς τρόπους λειτουργίας. Για να προσδιορίσετε τη λειτουργία, την κλάση Π.Ο.Ππεριέχει τις αντίστοιχες σταθερές.

  • ΠΟΠ::FETCH_ASSOC- επιστρέφει έναν πίνακα με ευρετήριο με το όνομα της στήλης στον πίνακα της βάσης δεδομένων.
  • ΠΟΠ::FETCH_NUM- επιστρέφει έναν πίνακα με ευρετήριο με αριθμό στήλης.
  • ΠΟΠ::FETCH_OBJ- επιστρέφει ένα ανώνυμο αντικείμενο με ονόματα ιδιοτήτων που αντιστοιχούν σε ονόματα στηλών. Για παράδειγμα, το $row->id θα περιέχει την τιμή από τη στήλη id.
  • ΠΟΠ::FETCH_CLASS- επιστρέφει μια νέα παρουσία της κλάσης, με τιμές ιδιοτήτων που αντιστοιχούν στα δεδομένα από τη γραμμή του πίνακα. Εάν η παράμετρος έχει καθοριστεί ΠΟΠ::FETCH_CLASSTYPE(Για παράδειγμα ΠΟΠ::FETCH_CLASS | ΠΟΠ::FETCH_CLASSTYPE), το όνομα της κλάσης θα καθοριστεί από την τιμή της πρώτης στήλης.

Σημείωση: δεν είναι πλήρης λίστα, όλες οι πιθανές σταθερές και παραλλαγές του συνδυασμού τους είναι διαθέσιμες στην τεκμηρίωση.

Ένα παράδειγμα λήψης ενός συσχετιστικού πίνακα:

$statement = $connection->query("SELECT * FROM users"); while($row = $statement->fetch(PDO::FETCH_ASSOC)) ( echo $row["id"] . " " . $row["name"]; )

$statement = $connection ->

ενώ ($row = $statement -> fetch (PDO::FETCH_ASSOC) ) (

echo $row [ "id" ] . " " . $row [ "όνομα" ] ;

Σημείωση: Συνιστάται να καθορίζετε πάντα τη λειτουργία δειγματοληψίας, από τη λειτουργία δειγματοληψίας ΠΟΠ::FETCH_BOTHθα απαιτήσει δύο φορές περισσότερη μνήμη- μάλιστα, θα δημιουργηθούν δύο πίνακες, ένας συνειρμικός και ένας κανονικός.

Σκεφτείτε να χρησιμοποιήσετε τη λειτουργία δείγματος ΠΟΠ::FETCH_CLASS. Ας δημιουργήσουμε μια τάξη χρήστης:

class User ( προστατευμένο $id; προστατευμένο $όνομα; δημόσια συνάρτηση getId() ( return $this->id; ) δημόσια συνάρτηση setId($id) ( $this->id = $id; ) δημόσια συνάρτηση getName() ( return $this->name; ) δημόσια συνάρτηση setName($name) ( $this->name = $name; ) )

Χρήστης κατηγορίας

προστατευμένο $id ;

προστατευμένο $name ;

δημόσια συνάρτηση getId()

επιστροφή $this -> id ;

δημόσια συνάρτηση setId ($id)

$this -> id = $id ;

δημόσια συνάρτηση getName()

επιστροφή $this -> name ;

δημόσια συνάρτηση setName ($name )

$this -> name = $name ;

Τώρα ας επιλέξουμε τα δεδομένα και ας εμφανίσουμε τα δεδομένα χρησιμοποιώντας τις μεθόδους κλάσης:

$statement = $connection->query("SELECT * FROM users"); while($row = $statement->fetch(PDO::FETCH_CLASS, "User")) ( echo $row->getId() . " " . $row->getName(); )

$statement = $connection -> ερώτημα ("SELECT * FROM users" ) ;

ενώ ($row = $statement -> fetch (PDO::FETCH_CLASS , "User" ) ) (

echo $row -> getId() . " " . $row -> getName();

Προετοιμασμένα ερωτήματα και δέσμευση παραμέτρων

Για να κατανοήσετε την ουσία και όλα τα οφέλη της δέσμευσης παραμέτρων, πρέπει να ρίξετε μια πιο προσεκτική ματιά στους μηχανισμούς Π.Ο.Π. Όταν καλείται $statement -> query()στον παραπάνω κώδικα, Π.Ο.Πθα ετοιμάσει ένα ερώτημα, θα το εκτελέσει και θα επιστρέψει το αποτέλεσμα.

Όταν καλείται $connection -> προετοιμασία()δημιουργείται ένα έτοιμο ερώτημα. Τα προετοιμασμένα ερωτήματα είναι η ικανότητα του συστήματος διαχείρισης βάσης δεδομένων να λαμβάνει ένα πρότυπο ερωτήματος, να το μεταγλωττίζει και να το εκτελεί αφού λάβει τις τιμές των μεταβλητών που χρησιμοποιούνται στο πρότυπο. Οι μηχανές προτύπων λειτουργούν με τον ίδιο τρόπο. ΈξυπνοςΚαι Κλαδάκι.

Όταν καλείται $statement -> execute()Οι τιμές περνούν για αντικατάσταση στο πρότυπο ερωτήματος και το DBMS εκτελεί το ερώτημα. Αυτή η ενέργεια είναι παρόμοια με την κλήση της συνάρτησης προτύπου καθιστώ().

Ένα παράδειγμα χρήσης προετοιμασμένων ερωτημάτων στο PHP ΠΟΠ:

Στον παραπάνω κώδικα, προετοιμάζεται ένα ερώτημα για την επιλογή μιας εγγραφής με πεδίο ταυτότηταίση με την τιμή που θα αντικατασταθεί :ταυτότητα. Σε αυτό το στάδιο, το DBMS θα αναλύσει και θα μεταγλωττίσει το ερώτημα, πιθανώς χρησιμοποιώντας προσωρινή αποθήκευση (ανάλογα με τις ρυθμίσεις).

Τώρα πρέπει να περάσετε την παράμετρο που λείπει και να εκτελέσετε το αίτημα:

$id = 5; $statement->execute([ ":id" => $id ]);

Οφέλη από τη χρήση συνδεδεμένων παραμέτρων

Ίσως, αφού δούμε πώς λειτουργούν τα προετοιμασμένα ερωτήματα και τις σχετικές παραμέτρους, τα οφέλη από τη χρήση τους να γίνουν ξεκάθαρα.

Π.Ο.Ππαρέχει έναν βολικό τρόπο διαφυγής δεδομένων χρήστη, για παράδειγμα, αυτός ο κωδικός δεν χρειάζεται πλέον:

Αντίθετα, είναι πιο λογικό να κάνετε αυτό:

Μπορείτε ακόμη να συντομεύσετε περαιτέρω τον κώδικα χρησιμοποιώντας αριθμημένες παραμέτρους αντί για ονομαστές:

Ταυτόχρονα, η χρήση προετοιμασμένων ερωτημάτων σάς επιτρέπει να βελτιώσετε την απόδοση όταν χρησιμοποιείτε το ίδιο ερώτημα προτύπου πολλές φορές. Δείγμα επιλογής πέντε τυχαίων χρηστών από τη βάση δεδομένων:

$numberOfUsers = $connection->query("SELECT COUNT(*) FROM users")->fetchColumn(); $χρήστες = ; $statement = $connection->prepare("SELECT * FROM users WHERE id = ? LIMIT 1"); για ($i = 1; $i<= 5; $i++) { $id = rand(1, $numberOfUsers); $users = $statement->execute([$id])->fetch(PDO::FETCH_OBJ); )

$numberOfUsers = $connection -> ερώτημα ("SELECT COUNT(*) FROM users" ) -> fetchColumn () ;

$χρήστες = ;

για ($i = 1 ; $i<= 5 ; $i ++ ) {

$id = rand (1 , $numberOfUsers ) ;

$users = $statement -> execute ([ $id ] ) -> fetch (PDO::FETCH_OBJ ) ;

Όταν καλείτε μια μέθοδο προετοιμάζω(), το DBMS θα αναλύσει και θα μεταγλωττίσει το ερώτημα, χρησιμοποιώντας προσωρινή αποθήκευση εάν είναι απαραίτητο. Αργότερα στον κύκλο Για, ανακτώνται μόνο τα δεδομένα με την καθορισμένη παράμετρο. Αυτή η προσέγγιση σάς επιτρέπει να λαμβάνετε δεδομένα πιο γρήγορα, μειώνοντας τον χρόνο εκτέλεσης της εφαρμογής.

Κατά την παραλαβή σύνολοχρήστες στη μέθοδο βάσης δεδομένων χρησιμοποιήθηκε fetchColumn(). Αυτή η μέθοδος επιστρέφει την τιμή μιας στήλης και είναι χρήσιμη όταν επιστρέφονται βαθμωτές τιμές όπως μέτρηση, άθροισμα, μέγιστες ή ελάχιστες τιμές.

Δεσμευμένες τιμές και ο χειριστής IN

Συχνά, όταν ξεκινάμε με Π.Ο.Π, υπάρχουν δυσκολίες με τον χειριστή ΣΕ. Για παράδειγμα, ας υποθέσουμε ότι ο χρήστης εισάγει πολλά ονόματα διαχωρισμένα με κόμμα. Η είσοδος χρήστη αποθηκεύεται σε μια μεταβλητή $names.

Σε αυτό το τελευταίο άρθρο, θα εξετάσουμε, τι είναι προετοιμασμένα ερωτήματα, πώς να συλλάβετε τα λάθηΚαι τι είναι οι συναλλαγές στην Π.Ο.Π.

Έτοιμα ερωτήματα

Όταν εκτελούμε ένα ερώτημα βάσης δεδομένων, αυτό αναλύεται και βελτιστοποιείται, κάτι που φυσικά απαιτεί χρόνο. Εάν έχουμε πολλά σύνθετα ερωτήματα, τότε αυτό μπορεί να διαρκέσει πολύ. Χρησιμοποιώντας το ίδιο έτοιμες ερωτήσεις, αυτό γίνεται μία φορά και μετά μπορούμε να χρησιμοποιήσουμε το ερώτημά μας όσες φορές θέλουμε. Επίσης, δεν χρειάζεται να ξεφύγουμε από τις παραμέτρους, γιατί πρόγραμμα οδήγησης βάσης δεδομένωνθα τα κάνει όλα μόνος του. Ας δούμε πώς να τα χρησιμοποιήσουμε.

$stmt = $db->prepare("INSERT INTO articles (title, text) VALUES (:title, :text)");
$stmt->bindParam(":title", $title);
$stmt->bindParam(":text", $text);



$stmt->execute();



$stmt->execute();

Για να προετοιμάσουμε ένα αίτημα, το γράφουμε στη μέθοδο προετοιμάζω, όπου αντί για τιμές καθορίζουμε μια γραμμή όπως αυτή: ":Ονομα". Στη μέθοδο bindParamκαθορίζουμε σε ποια γραμμή ποια δεδομένα να δεσμεύσουμε. Στην περίπτωσή μας, στη γραμμή :τίτλοςδεσμευτικά δεδομένα από μια μεταβλητή $title, και στη γραμμή :κείμενο- δεδομένα από μια μεταβλητή $text. Για να εκτελέσετε ένα αίτημα, πρέπει να καλέσετε τη μέθοδο εκτέλεση. Τέτοιες παράμετροι ονομάζονται ονομάστηκε, κοιτάξτε τώρα ανώνυμος.

$stmt = $db->prepare("INSERT INTO articles (title, text) VALUES (?, ?)");
$stmt->bindParam(1, $title);
$stmt->bindParam(2, $text);

$title = "τίτλος του άρθρου 1";!}
$text = "Κάποιο κείμενο για το πρώτο άρθρο";
$stmt->execute();

$title = "τίτλος του άρθρου 2";!}
$text = "Κάποιο κείμενο για το δεύτερο άρθρο";
$stmt->execute();

Εδώ όλα είναι πανομοιότυπα, εκτός από το ότι αντί για τη γραμμή :Ονομαυποδεικνύεται ένα ερωτηματικό και στη μέθοδο bindParamαριθμός 1 που σημαίνει πρώταερωτηματικό και αριθμό 2 - δεύτεροςερωτηματικό. Χρησιμοποιήστε όποιον τρόπο σας αρέσει περισσότερο.

Λάθη σύλληψης

Για να εντοπίσουμε λάθη, χρησιμοποιούμε τη γνωστή κατασκευή προσπάθησε να πιάσειςκαι τάξη Εξαίρεση PDO.

Δοκιμάστε(
$db = νέο ΠΟΠ("myql:host=$host;dbname=$dbname", $user, $pass);
) catch(PDOException $e) (
echo "Έχετε ένα σφάλμα: ".$e->getMessage()."
";
echo "Online: ".$e->getLine();
}

Για παράδειγμα, έκανα ένα λάθος και έγραψα mysql, αλλά όχι mysql. Αυτό το σφάλμα θα εντοπιστεί και θα εμφανίσουμε το κείμενό του και σε ποια γραμμή παρουσιάστηκε το σφάλμα.

Συναλλαγές

ας σκεφτούμε συναλλαγέςακριβώς στο παράδειγμα.

Δοκιμάστε(
$db = νέο ΠΟΠ("mysql:host=$host;dbname=$dbname", $user, $pass);
$db->beginTransaction();

$stmt = $db->exec("INSERT INTO `articles`(`title`) VALUES("title1")");
$stmt = $db->exec("INSERT INTO `articles`(`title`) VALUES("title2")");
exit ("σφάλμα");

$stmt = $db->exec("INSERT INTO `articles`(`title`) VALUES("title3")");
$db->commit();

) catch(PDOException $e) (
$db->rollBack();
}

έναρξη συναλλαγήςσημαίνει ότι ξεκινάμε μια συναλλαγή. Διαπράττωεπιβεβαιώνει τις αλλαγές και rollbackακυρώνει τα πάντα.

Η ουσία των συναλλαγών είναι ότι είτε κάνουμε τα πάντα είτε δεν κάνουμε τίποτα. Στο παράδειγμά μας, εισάγουμε στον πίνακα άρθρααξίες τίτλος 1, τίτλος2, τίτλος 3. Αλλά μετά την εισαγωγή της δεύτερης τιμής, προσομοιώσαμε ένα σφάλμα σταματώντας το σενάριο με έξοδος. Αν δεν χρησιμοποιούσαμε συναλλαγές, τότε έχουμε τα δύο πρώτα τίτλοςθα εισαχθεί, αλλά το τελευταίο δεν είναι. Στο παράδειγμά μας, αυτό δεν είναι απαραίτητο, αλλά υπάρχουν φορές που αυτό μπορεί να οδηγήσει σε σοβαρά σφάλματα στην εφαρμογή. Για να μην συμβεί αυτό, χρησιμοποιούμε συναλλαγές, όπου η μέθοδος rollbackθα επιστρέψει τα πάντα στην αρχική τους μορφή και τα δύο πρώτα μας τίτλοςδεν θα εισαχθεί ούτε και αν όλα πήγαν καλά, χωρίς σφάλματα, τότε η μέθοδος διαπράττωθα επιβεβαιώσει τις αλλαγές και τις τρεις τίτλοςθα εισαχθεί με επιτυχία.

συμπέρασμα

Έτσι, στα τρία άρθρα μας για εκμάθησης Π.Ο.Π, καλύψαμε όλα όσα χρειάζεστε για να χρησιμοποιήσετε αυτή τη διεπαφή με ευκολία. Νομίζω ότι καταλαβαίνεις πώς Π.Ο.Πκάνει τη ζωή μας πιο εύκολη και θα τη χρησιμοποιήσουμε στα έργα σας. Καλή τύχη!

Αυτοί είναι πίνακες, αλλά μόνο για ανάγνωση (μπορείτε να κάνετε κάποιες αλλαγές, αλλά είναι εξαιρετικά περιορισμένες). Στην πραγματικότητα, αυτός είναι ένας συνηθισμένος πίνακας, αλλά δημιουργείται με βάση κάποιο ερώτημα (άλλοι πίνακες), π.χ. είναι ένας «σύνδεσμος» σε κάποιο ερώτημα. Εξετάστε ένα παράδειγμα:

ΔΗΜΙΟΥΡΓΙΑ ΠΙΝΑΚΑ t(όνομα, τιμή); //δημιουργία πίνακα CREATE VIEW v AS SELECT όνομα, τιμή, όνομα * τιμή ΩΣ τιμή FROM t;//δημιουργία άλλου πίνακα, το τρίτο πεδίο ως γινόμενο των δύο πρώτων SELECT * FROM v; //λήψη δεδομένων από τον πίνακα

Εκείνοι. δημιουργήσαμε έναν πίνακα με ένα τρίτο πεδίο που κανείς δεν γνωρίζει. Και δεν χρειάζεται να το δείξετε σε όλους. Εκείνοι. μπορούμε να δημιουργήσουμε έναν πίνακα χρησιμοποιώντας το View, για παράδειγμα, σε μια εταιρεία, για το τμήμα HR, για τους υπαλλήλους, για το εκπαιδευτικό τμήμα, για τη λογιστική. Η ενέργεια είναι παρόμοια με τη χρήση του πρώτου πίνακα ως πρότυπο και την προσθήκη νέων πεδίων σε αυτόν.

Έτοιμα ερωτήματα

Υπάρχουν περιπτώσεις που έχουμε πολλές εγγραφές (για παράδειγμα, 50000) στη βάση δεδομένων και επιλέγονται σε βρόχο. Εάν ωθήσουμε το mysql_query εκεί, τότε αυτό το ερώτημα θα αναλυθεί 50.000 φορές. Για να μην χάνουμε χρόνο σε μια τέτοια ανάλυση, υπάρχει ένα έτοιμο αίτημα - αυτό είναι ένα αίτημα που δίνεται στη βάση δεδομένων εκ των προτέρων, αναλύεται μία φορά και η βάση δεδομένων είναι έτοιμη να το δεχτεί. Παράδειγμα:

mysql_connect("localhost", "root", "password"); mysql_select_db("test"); mysql_query("PREPARE myinsert FROM // γράψτε το όνομα του προετοιμασμένου ερωτήματος "INSERT INTO test_table (όνομα, τιμή) VALUES (?, ?)""); //εδώ είναι το έτοιμο ερώτημα για ($i = 0; $i< 1000; $i++){ mysql_query("SET @name = "Товар # $i""); //установить значение "товар" для переменной @name mysql_query("SET @price = " . ($i * 10)); //установить значение цены для переменной @price mysql_query("EXECUTE myinsert USING @name, @price"); //исполнить подготовленный запрос, используя эти две переменные } mysql_close();

Στη γραμμή της προετοιμασμένης ερώτησης, οι τιμές που πρέπει να εισαχθούν είναι άγνωστες (σημάδι;). Στη συνέχεια, στον βρόχο ρίχνουμε τις τιμές στον πίνακα. Εκείνοι. μέσα στη γλώσσα mysql βλέπουμε τις μεταβλητές μας, τις συναρτήσεις μας.