PDO::prepare
Bereitet eine Anweisung für die Ausführung vor.
Syntax
PDOStatement PDO::prepare ( $statement [ , array(key_pair) ] )
Parameter
$statement
Eine Zeichenfolge, die die SQL-Anweisung enthält
key_pair
Ein Array mit einem Attributnamen und -wert Weitere Informationen finden Sie im Abschnitt Hinweise.
Rückgabewert
Gibt ein PDOStatement
Objekt für Erfolg zurück. Gibt bei Einem Fehler ein PDOException
Objekt oder false zurück, abhängig vom Wert von PDO::ATTR_ERRMODE
.
Hinweise
Die Microsoft Drivers für PHP für SQL Server wertet die vorbereiteten Anweisungen erst aus, wenn sie ausgeführt werden.
In der folgenden Tabelle sind die möglichen Werte für key_pair aufgelistet.
Key | Beschreibung |
---|---|
PDO::ATTR_CURSOR |
Definiert das Cursorverhalten. Der Standardwert ist PDO::CURSOR_FWDONLY , ein nicht scrollbarer Vorwärtscursor. PDO::CURSOR_SCROLL ist ein scrollbarer Cursor.Beispiel: array( PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY ) .Bei Festlegung auf PDO::CURSOR_SCROLL , können Sie dann PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE den Typ des bildlauffähigen Cursors festlegen, der weiter unten in diesem Artikel beschrieben wird.Weitere Informationen zu Resultsets und Cursorn im PDO_SQLSRV Treiber finden Sie unter Cursortypen (PDO_SQLSRV Treiber). |
PDO::ATTR_EMULATE_PREPARES |
Dieses Attribut lautet standardmäßig „false“, kann aber durch PDO::ATTR_EMULATE_PREPARES => true geändert werden. Details und ein Beispiel finden Sie unter Emulate_Prepare. |
PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE |
Gibt den Typ des scrollbaren Cursors an. Gilt nur, wenn PDO::ATTR_CURSOR auf PDO::CURSOR_SCROLL gesetzt ist. Weitere Informationen zu den Werten, die dieses Attribut übernehmen kann, finden Sie weiter unten in diesem Artikel. |
PDO::SQLSRV_ATTR_DECIMAL_PLACES |
Gibt die Anzahl der Dezimalstellen beim Formatieren abgerufener Geldwerte (vom Typ „money“) an. Diese Option funktioniert nur, wenn PDO::SQLSRV_ATTR_FORMAT_DECIMALS auf „true“ festgelegt ist. Weitere Informationen finden Sie unter Formatieren von Dezimalzeichenfolgen und Geldwerten (PDO_SQLSRV-Treiber). |
PDO::SQLSRV_ATTR_DIRECT_QUERY |
Wenn True , gibt die direkte Abfrageausführung an. False bedeutet vorbereitete Anweisungsausführung. Weitere Informationen zu PDO::SQLSRV_ATTR_DIRECT_QUERY finden Sie unter Direkte Anweisungsausführung und vorbereitete Anweisungsausführung im PDO_SQLSRV-Treiber. |
PDO::SQLSRV_ATTR_ENCODING |
PDO::SQLSRV_ENCODING_UTF8 (Standard)PDO::SQLSRV_ENCODING_SYSTEM PDO::SQLSRV_ENCODING_BINARY |
PDO::SQLSRV_ATTR_FETCHES_DATETIME_TYPE |
Gibt an, ob Datums- und Uhrzeittypen als PHP-DateTime-Objekte abgerufen werden sollen. Weitere Informationen finden Sie unter Vorgehensweise: Abrufen von Datums- und Uhrzeittypen als PHP-datetime-Objekte mit dem PDO_SQLSRV-Treiber. |
PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE |
Verarbeitet die Abrufe numerischer Werte aus Spalten mit numerischen SQL-Typen. Weitere Informationen finden Sie unter PDO::setAttribute. |
PDO::SQLSRV_ATTR_FORMAT_DECIMALS |
Gibt an, ob Dezimalzeichenfolgen gegebenenfalls führende Nullen hinzugefügt werden sollen. Bei Festlegung erlaubt diese Option der Option PDO::SQLSRV_ATTR_DECIMAL_PLACES das Formatieren von Datentypen vom Typ „money“. Weitere Informationen finden Sie unter Formatieren von Dezimalzeichenfolgen und Geldwerten (PDO_SQLSRV-Treiber). |
PDO::SQLSRV_ATTR_QUERY_TIMEOUT |
Weitere Informationen finden Sie unter PDO::setAttribute. |
Bei Verwendung von PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL
können Sie mit PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE
den Typ des Cursors festlegen. Übergeben Sie beispielsweise das folgende Array, um PDO::prepare
einen dynamischen Cursor festzulegen:
array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL, PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE => PDO::SQLSRV_CURSOR_DYNAMIC));
In der folgenden Tabelle sind die möglichen Werte für PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE
aufgeführt. Weitere Informationen zu scrollbaren Cursorn finden Sie unter Cursortypen (PDO_SQLSRV-Treiber).
Wert | Beschreibung |
---|---|
PDO::SQLSRV_CURSOR_BUFFERED |
Erstellt einen clientseitigen (gepufferten) statischen Cursor, der das Resultset auf dem Clientcomputer in den Arbeitsspeicher puffert. |
PDO::SQLSRV_CURSOR_DYNAMIC |
Erstellt einen serverseitigen (nicht gepufferten) dynamischen Cursor, mit dem Sie in beliebiger Reihenfolge auf Zeilen zugreifen und Änderungen in der Datenbank widerspiegeln können. |
PDO::SQLSRV_CURSOR_KEYSET |
Erstellt einen serverseitigen Keysetcursor. Ein Keysetcursor aktualisiert die Zeilenanzahl nicht, wenn eine Zeile aus der Tabelle gelöscht wird (eine gelöschte Zeile wird ohne Werte zurückgegeben). |
PDO::SQLSRV_CURSOR_STATIC |
Erstellt einen serverseitigen statischen Cursor, mit dem Sie in beliebiger Reihenfolge auf Zeilen zugreifen können, aber keine Änderungen in der Datenbank widerspiegeln.PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL impliziert PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE => PDO::SQLSRV_CURSOR_STATIC . |
Sie können ein PDOStatement
Objekt schließen, indem Sie Folgendes aufrufen unset
:
unset($stmt);
Beispiel für nur Vorwärtscursor
In diesem Beispiel wird gezeigt, wie Sie mit Parametermarkierungen und einem Vorwärtscursor arbeiten PDO::prepare
.
<?php
$database = "Test";
$server = "(local)";
$conn = new PDO( "sqlsrv:server=$server ; Database = $database", "", "");
$col1 = 'a';
$col2 = 'b';
$query = "insert into Table1(col1, col2) values(?, ?)";
$stmt = $conn->prepare( $query, array( PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY, PDO::SQLSRV_ATTR_QUERY_TIMEOUT => 1 ) );
$stmt->execute( array( $col1, $col2 ) );
print $stmt->rowCount();
echo "\n";
$query = "insert into Table1(col1, col2) values(:col1, :col2)";
$stmt = $conn->prepare( $query, array( PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY, PDO::SQLSRV_ATTR_QUERY_TIMEOUT => 1 ) );
$stmt->execute( array( ':col1' => $col1, ':col2' => $col2 ) );
print $stmt->rowCount();
unset($stmt);
?>
Beispiel für statischen Cursor
In diesem Beispiel wird die Verwendung PDO::prepare
mit einem serverseitigen statischen Cursor veranschaulicht. Ein Beispiel für einen clientseitigen Cursor finden Sie unter Cursortypen (PDO_SQLSRV-Treiber).
<?php
$database = "AdventureWorks";
$server = "(local)";
$conn = new PDO( "sqlsrv:server=$server ; Database = $database", "", "");
$query = "select * from Person.ContactType";
$stmt = $conn->prepare( $query, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL));
$stmt->execute();
echo "\n";
while ( $row = $stmt->fetch( PDO::FETCH_ASSOC ) ){
print "$row[Name]\n";
}
echo "\n..\n";
$row = $stmt->fetch( PDO::FETCH_BOTH, PDO::FETCH_ORI_FIRST );
print_r($row);
$row = $stmt->fetch( PDO::FETCH_ASSOC, PDO::FETCH_ORI_REL, 1 );
print "$row[Name]\n";
$row = $stmt->fetch( PDO::FETCH_NUM, PDO::FETCH_ORI_NEXT );
print "$row[1]\n";
$row = $stmt->fetch( PDO::FETCH_NUM, PDO::FETCH_ORI_PRIOR );
print "$row[1]..\n";
$row = $stmt->fetch( PDO::FETCH_NUM, PDO::FETCH_ORI_ABS, 0 );
print_r($row);
$row = $stmt->fetch( PDO::FETCH_NUM, PDO::FETCH_ORI_LAST );
print_r($row);
?>
Gezieltes Beispiel
Die folgenden beiden Codeausschnitte zeigen die Verwendung PDO::prepare
mit Daten, die für Char / varchar-Spalten vorgesehen sind. Da die Standardcodierung für PDO::prepare
UTF-8 lautet, kann der Benutzer die Option PDO::SQLSRV_ENCODING_SYSTEM
verwenden, um implizite Konvertierungen zu vermeiden.
Option 1:
$options = array(PDO::SQLSRV_ATTR_ENCODING => PDO::SQLSRV_ENCODING_SYSTEM);
$statement = $pdo->prepare(
'SELECT *
FROM myTable
WHERE myVarcharColumn = :myVarcharValue',
$options
);
$statement->bindValue(':myVarcharValue', 'my data', PDO::PARAM_STR);
Option 2:
$statement = $pdo->prepare(
'SELECT *
FROM myTable
WHERE myVarcharColumn = :myVarcharValue'
);
$p = 'my data';
$statement->bindParam(':myVarcharValue', $p, PDO::PARAM_STR, 0, PDO::SQLSRV_ENCODING_SYSTEM);
Prepare-Beispiel
Dieses Beispiel zeigt, wie PDO::prepare verwendet wird, wenn PDO::ATTR_EMULATE_PREPARES
auf „true“ gesetzt ist.
<?php
$serverName = "yourservername";
$username = "yourusername";
$password = "yourpassword";
$database = "tempdb";
$conn = new PDO("sqlsrv:server = $serverName; Database = $database", $username, $password);
$pdo_options = array();
$pdo_options[PDO::ATTR_EMULATE_PREPARES] = true;
$pdo_options[PDO::SQLSRV_ATTR_ENCODING] = PDO::SQLSRV_ENCODING_UTF8;
$stmt = $conn->prepare("CREATE TABLE TEST([id] [int] IDENTITY(1,1) NOT NULL,
[name] nvarchar(max))",
$pdo_options);
$stmt->execute();
$prefix = '가각';
$name = '가각ácasa';
$name2 = '가각sample2';
$stmt = $conn->prepare("INSERT INTO TEST(name) VALUES(:p0)", $pdo_options);
$stmt->execute(['p0' => $name]);
unset($stmt);
$stmt = $conn->prepare("SELECT * FROM TEST WHERE NAME LIKE :p0", $pdo_options);
$stmt->execute(['p0' => "$prefix%"]);
foreach ($stmt as $row) {
echo "\n" . 'FOUND: ' . $row['name'];
}
unset($stmt);
unset($conn);
?>
Der PDO_SQLSRV
Treiber ersetzt intern alle Platzhalter durch die Parameter, die von PDOStatement::bindParam()gebunden sind. Daher wird eine SQL-Abfragezeichenfolge ohne Platzhalter an den Server gesendet. Betrachten Sie das folgende Beispiel:
$statement = $PDO->prepare("INSERT into Customers (CustomerName, ContactName) VALUES (:cus_name, :con_name)");
$statement->bindParam(:cus_name, "Cardinal");
$statement->bindParam(:con_name, "Tom B. Erichsen");
$statement->execute();
Wenn PDO::ATTR_EMULATE_PREPARES
auf „false“ gesetzt ist (der Standardfall), werden diese Daten an die Datenbank gesendet:
"INSERT into Customers (CustomerName, ContactName) VALUES (:cus_name, :con_name)"
Information on :cus_name parameter
Information on :con_name parameter
Der Server führt die Abfrage mithilfe des parametrisierten Abfragefeatures für Bindungsparameter aus. Wenn jedoch PDO::ATTR_EMULATE_PREPARES
auf „true“ gesetzt ist, sieht die an den Server gesendete Abfrage in etwa so aus:
"INSERT into Customers (CustomerName, ContactName) VALUES ('Cardinal', 'Tom B. Erichsen')"
Durch das Festlegen von PDO::ATTR_EMULATE_PREPARES
auf „true“ können einige Einschränkungen in SQL Server umgangen werden. Sql Server unterstützt beispielsweise keine benannten oder positionsbezogenen Parameter in einigen Transact-SQL-Klauseln. Darüber hinaus verfügt SQL Server über eine Beschränkung der Bindung von 2.100 Parametern.
Hinweis
Bei emulierten Vorbereitungen, die auf "true" festgelegt sind, wird die Sicherheit parametrisierter Abfragen nicht wirksam. Daher sollte Ihre Anwendung sicherstellen, dass die An die Parameter gebundenen Daten keinen schädlichen Transact-SQL-Code enthalten.
Codieren
Wenn der Benutzer Parameter mit unterschiedlichen Codierungen (z. B. UTF-8 oder binär) binden möchte, sollte er die Codierung im PHP-Skript eindeutig angeben.
Der Treiber überprüft zunächst die in PDO::bindParam()
(z. PDO_SQLSRV
B$statement->bindParam(:cus_name, "Cardinal", PDO::PARAM_STR, 10, PDO::SQLSRV_ENCODING_UTF8)
. ) angegebene Codierung.
Wenn sie nicht gefunden wird, prüft der Treiber, ob eine Codierung in PDO::prepare()
oder PDOStatement::setAttribute()
festgelegt ist. Andernfalls verwendet der Treiber die in PDO::__construct()
oder PDO::setAttribute()
.
Darüber hinaus kann der Benutzer ab Version 5.8.0 bei Verwendung von PDO::p repare mit PDO::ATTR_EMULATE_PREPARES
"true" die in PHP 7.2 eingeführten erweiterten Zeichenfolgentypen verwenden, um sicherzustellen, dass das N
Präfix verwendet wird. Die folgenden Codeausschnitte zeigen verschiedene Alternativen an.
Hinweis
Standardmäßig ist EMULATE_PREPARES auf FALSE festgelegt. In diesem Fall werden die erweiterten PDO-Zeichenfolgenkonstanten ignoriert.
Treiberoption PDO::SQLSRV_ENCODING_UTF8 beim Binden verwenden
$p = '가각';
$sql = 'SELECT :value';
$options = array(PDO::ATTR_EMULATE_PREPARES => true);
$stmt = $conn->prepare($sql, $options);
$stmt->bindParam(':value', $p, PDO::PARAM_STR, 0, PDO::SQLSRV_ENCODING_UTF8);
$stmt->execute();
Verwenden des PDO::SQLSRV_ATTR_ENCODING-Attributs
$p = '가각';
$sql = 'SELECT :value';
$options = array(PDO::ATTR_EMULATE_PREPARES => true, PDO::SQLSRV_ATTR_ENCODING => PDO::SQLSRV_ENCODING_UTF8);
$stmt = $conn->prepare($sql, $options);
$stmt->execute([':value' => $p]);
Verwenden der PDO-Konstante PDO::P ARAM_STR_NATL
$p = '가각';
$sql = 'SELECT :value';
$options = array(PDO::ATTR_EMULATE_PREPARES => true);
$stmt = $conn->prepare($sql, $options);
$stmt->bindParam(':value', $p, PDO::PARAM_STR | PDO::PARAM_STR_NATL);
$stmt->execute();
Festlegen des Standardzeichenfolgenparametertyps PDO::P ARAM_STR_NATL
$conn->setAttribute(PDO::ATTR_DEFAULT_STR_PARAM, PDO::PARAM_STR_NATL);
$p = '가각';
$sql = 'SELECT :value';
$options = array(PDO::ATTR_EMULATE_PREPARES => true);
$stmt = $conn->prepare($sql, $options);
$stmt->execute([':value' => $p]);
Begrenzungen
Wie Sie sehen können, erfolgt die Bindung intern durch den Treiber. Eine gültige Abfrage wird zur Ausführung ohne Parameter an den Server gesendet. Im Vergleich zum regulären Fall ergeben sich einige Einschränkungen, wenn das parametrisierte Abfragefeature nicht verwendet wird.
- Es funktioniert nicht für Parameter, die als
PDO::PARAM_INPUT_OUTPUT
gebunden sind.- Wenn der Benutzer
PDO::PARAM_INPUT_OUTPUT
inPDO::bindParam()
angibt, wird eine PDO-Ausnahme ausgelöst.
- Wenn der Benutzer
- Es funktioniert nicht für Parameter, die als Ausgabeparameter gebunden sind.
- Wenn der Benutzer eine vorbereitete Anweisung mit Platzhaltern erstellt, die für Ausgabeparameter bestimmt sind (d. h. ein Gleichheitszeichen unmittelbar nach einem Platzhalter, wie
SELECT ? = COUNT(*) FROM Table1
), wird eine PDO-Ausnahme ausgelöst. - Wenn eine vorbereitete Anweisung eine gespeicherte Prozedur mit einem Platzhalter als Argument für einen Ausgabeparameter aufruft, wird keine Ausnahme ausgelöst, da der Treiber den Ausgabeparameter nicht erkennen kann. Die Variable, die der Benutzer für den Ausgabeparameter bereitstellt, bleibt jedoch unverändert.
- Wenn der Benutzer eine vorbereitete Anweisung mit Platzhaltern erstellt, die für Ausgabeparameter bestimmt sind (d. h. ein Gleichheitszeichen unmittelbar nach einem Platzhalter, wie
- Doppelte Platzhalter für einen binärcodierten Parameter funktionieren nicht.