PDO::prepare

PHP-Treiber herunterladen

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, das einen Attributnamen und einen Wert enthält. Weitere Informationen finden Sie im Abschnitt Hinweise.

Rückgabewert

Bei Erfolg wird ein PDOStatement-Objekt zurückgegeben. Bei einem Fehler wird entweder ein PDOException-Objekt oder „false“ zurückgegeben, abhängig vom Wert für PDO::ATTR_ERRMODE.

Bemerkungen

Microsoft-Treiber für PHP für SQL Server wertet keine vorbereiteten Anweisungen vor der Ausführung aus.

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 Einstellung auf PDO::CURSOR_SCROLL können Sie dann mit PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE den Typ des scrollbaren Cursors einstellen, der unten 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. Unten finden Sie die Werte, die dieses Attribut annehmen kann.
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 Wird hierfür der Wert „true“ festgelegt, werden Abfragen direkt ausgeführt. Der Wert „false“ sorgt dafür, dass vorbereitete Anweisungen ausgeführt werden. 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 folgendes Array an PDO::prepare, um 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 (gepufferten) dynamischen Cursor, der es Ihnen erlaubt, auf Zeilen in beliebiger Reihenfolge zuzugreifen und Änderungen in der Datenbank widerspiegelt.
PDO::SQLSRV_CURSOR_KEYSET Erstellt einen serverseitigen Keysetcursor. Ein Keysetcursor aktualisiert nach dem Löschen einer Zeile aus einer Tabelle nicht die Zeilenanzahl (eine gelöschte Zeile wird ohne Werte zurückgegeben).
PDO::SQLSRV_CURSOR_STATIC Erstellt einen serverseitigen statischen Cursor, der es Ihnen zwar erlaubt, auf Zeilen in beliebiger Reihenfolge zuzugreifen, aber die Änderungen in der Datenbank nicht widerspiegelt.

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 unset aufrufen:

unset($stmt);

Beispiel für nur Vorwärtscursor

In diesem Beispiel wird erläutert, wie Sie PDO::prepare mit Parametermarkern und einem Vorwärtscursor verwenden.

<?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

Dieses Beispiel zeigt die Verwendung von PDO::prepare mit einem serverseitigen statischen Cursor. 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 zwei Ausschnitte zeigen, wie Sie PDO::prepare mit Daten für die Spalten CHAR/VARCHAR verwenden. Der Benutzer kann die Option PDO::SQLSRV_ENCODING_SYSTEM zur Vermeidung von impliziten Konvertierungen verwenden, da die Standardcodierung für PDO::prepare UTF-8 ist.

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 durch PDOStatement::bindParam() gebunden sind. Daher wird eine SQL-Abfragezeichenfolge ohne Platzhalter an den Server gesendet. Sehen Sie sich folgendes Beispiel an:

$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

Die Abfrage wird mit einer parametrisierten Abfragefunktion für Bindungsparameter ausgeführt. 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. Beispielsweise werden in einigen Transact-SQL-Klauseln von SQL Server keine benannten oder positionellen Parameter unterstützt. Darüber hinaus begrenzt SQL Server die Bindung auf höchstens 2.100 Parameter.

Hinweis

Wenn EMULATE_PREPARES auf „true“ gesetzt ist, kommt der Sicherheitsgewinn durch parametrisierte Anfragen nicht zum Tragen. Ihre Anwendung sollte deshalb sicherstellen, dass die an den bzw. die Parameter gebunden Daten keinen bösartigen 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 PDO_SQLSRV-Treiber überprüft zunächst die in PDO::bindParam() angegebene Codierung (z. B. $statement->bindParam(:cus_name, "Cardinal", PDO::PARAM_STR, 10, PDO::SQLSRV_ENCODING_UTF8)).

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() angegebene Codierung.

Zusätzlich dazu kann der Benutzer ab Version 5.8.0 die erweiterten Zeichenfolgentypen aus PHP 7.2 verwenden, wenn er PDO::prepare nutzt und PDO::ATTR_EMULATE_PREPARES auf TRUE festgelegt ist. So stellt er sicher, dass das N-Präfix verwendet wird. Die nachfolgenden Ausschnitte zeigen verschiedene Alternativen.

Hinweis

Standardmäßig ist EMULATE_PREPARES auf FALSE festgelegt. In diesem Fall werden die erweiterten PDO-Zeichenfolgenkonstanten ignoriert.

Verwenden der Treiberoption PDO::SQLSRV_ENCODING_UTF8 bei der Bindung

$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 Attributs PDO::SQLSRV_ATTR_ENCODING

$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::PARAM_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 Parametertyps der Standardzeichenfolge PDO::PARAM_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]);

Einschränkungen

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. Verglichen mit dem Normalfall ergeben sich einige Einschränkungen, wenn die parametrisierte Abfragefunktion nicht verwendet wird.

  • Sie funktioniert nicht für Parameter, die als PDO::PARAM_INPUT_OUTPUT gebunden sind.
    • Wenn der Benutzer PDO::PARAM_INPUT_OUTPUT in PDO::bindParam() angibt, wird eine PDO-Ausnahme ausgelöst.
  • Sie 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.
  • Doppelte Platzhalter für einen binär kodierten Parameter funktionieren nicht.

Weitere Informationen

PDO-Klasse

PDO