Condividi tramite


PDO::prepare

Download del driver PHP

Prepara un'istruzione per l'esecuzione.

Sintassi

PDOStatement PDO::prepare ( $statement [ , array(key_pair) ] )

Parametri

$statement

stringa contenente l'istruzione SQL.

key_pair

matrice contenente il nome e il valore di un attributo. Per altre informazioni, vedere la sezione Osservazioni.

Valore restituito

Restituisce un PDOStatement oggetto in caso di esito positivo. In caso di errore, restituisce un PDOException oggetto o false a seconda del valore di PDO::ATTR_ERRMODE.

Osservazioni:

I driver Microsoft per PHP per SQL Server non valutano le istruzioni preparate fino all'esecuzione.

Nella tabella seguente sono elencati i valori key_pair possibili.

Chiave Descrizione
PDO::ATTR_CURSOR Specifica il comportamento del cursore. Il valore predefinito è PDO::CURSOR_FWDONLY, un cursore di tipo forward non scorrevole. PDO::CURSOR_SCROLL è un cursore scorrevole.

Ad esempio: array( PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY ).

Se impostato su PDO::CURSOR_SCROLL, è quindi possibile usare PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE per impostare il tipo di cursore scorrevole, descritto più avanti in questo articolo.

Per altre informazioni sui set di risultati e i cursori nel PDO_SQLSRV driver, vedere Tipi di cursori (driver PDO_SQLSRV).
PDO::ATTR_EMULATE_PREPARES Per impostazione predefinita, questo attributo è false. È possibile modificare questa impostazione usando PDO::ATTR_EMULATE_PREPARES => true. Per informazioni dettagliate e un esempio, vedere la sezione relativa a EMULATE_PREPARES.
PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE Specifica il tipo di cursore scorrevole. È valido solo quando PDO::ATTR_CURSOR è impostato su PDO::CURSOR_SCROLL. Vedere più avanti in questo articolo per i valori che questo attributo può accettare.
PDO::SQLSRV_ATTR_DECIMAL_PLACES Specifica il numero di posizioni decimali per la formattazione dei valori money recuperati. Questa opzione funziona solo quando PDO::SQLSRV_ATTR_FORMAT_DECIMALS è true. Per altre informazioni, vedere Formattazione di stringhe decimali e valori money (driver PDO_SQLSRV).
PDO::SQLSRV_ATTR_DIRECT_QUERY Quando True, specifica l'esecuzione diretta della query. False indica l'esecuzione dell'istruzione preparata. Per altre informazioni su PDO::SQLSRV_ATTR_DIRECT_QUERY, vedere Esecuzione di istruzioni diretta e preparata nel driver PDO_SQLSRV.
PDO::SQLSRV_ATTR_ENCODING PDO::SQLSRV_ENCODING_UTF8 (predefinito)
PDO::SQLSRV_ENCODING_SYSTEM
PDO::SQLSRV_ENCODING_BINARY
PDO::SQLSRV_ATTR_FETCHES_DATETIME_TYPE Specifica se recuperare i tipi di data e ora come oggetti DateTime PHP. Per altre informazioni, vedere Procedura: Recuperare i tipi di data e ora come oggetti DateTime PHP usando il driver PDO_SQLSRV.
PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE Gestisce i recuperi numerici dalle colonne con tipi SQL numerici. Per altre informazioni, vedere PDO::setAttribute.
PDO::SQLSRV_ATTR_FORMAT_DECIMALS Specifica se aggiungere zeri iniziali alle stringhe decimali quando appropriato. Se impostata, questa opzione abilita l'opzione PDO::SQLSRV_ATTR_DECIMAL_PLACES per la formattazione dei tipi money. Per altre informazioni, vedere Formattazione di stringhe decimali e valori money (driver PDO_SQLSRV).
PDO::SQLSRV_ATTR_QUERY_TIMEOUT Per altre informazioni, vedere PDO::setAttribute.

Quando si usa PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL, è possibile usare PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE per specificare il tipo di cursore. Ad esempio, passare la matrice seguente a per PDO::prepare impostare un cursore dinamico:

array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL, PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE => PDO::SQLSRV_CURSOR_DYNAMIC));

La tabella seguente mostra i valori possibili perPDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE. Per altre informazioni sui cursori scorrevoli, vedere Tipi di cursore (driver PDO_SQLSRV).

Valore Descrizione
PDO::SQLSRV_CURSOR_BUFFERED Crea un cursore statico (con buffer) lato client, che memorizza il set di risultati nel buffer in memoria sul computer client.
PDO::SQLSRV_CURSOR_DYNAMIC Crea un cursore dinamico lato server (senza buffer), che consente di accedere alle righe in qualsiasi ordine e riflettere le modifiche nel database.
PDO::SQLSRV_CURSOR_KEYSET Crea un cursore keyset sul lato server. Un cursore keyset non aggiorna il conteggio delle righe se una riga viene eliminata dalla tabella (viene restituita una riga eliminata senza valori).
PDO::SQLSRV_CURSOR_STATIC Crea un cursore statico lato server, che consente di accedere alle righe in qualsiasi ordine, ma non riflette le modifiche nel database.

PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL implica PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE => PDO::SQLSRV_CURSOR_STATIC.

È possibile chiudere un PDOStatement oggetto chiamando unset:

unset($stmt);

Esempio di cursore forward-only

Questo esempio mostra come usare PDO::prepare con marcatori di parametro e un cursore forward-only.

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

Esempio di cursore statico

Questo esempio illustra come usare PDO::prepare con un cursore statico lato server. Per un esempio con un cursore lato client, vedere Tipi di cursore (driver PDO_SQLSRV).

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

Esempio di destinazione

I due frammenti di codice seguenti illustrano come usare PDO::prepare con i dati destinati alle colonne varchar char / . Poiché la codifica predefinita per PDO::prepare è UTF-8, l'utente può usare l'opzione PDO::SQLSRV_ENCODING_SYSTEM per evitare conversioni implicite.

Opzione 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);

Opzione 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);

Esempio di preparazione

Questo esempio illustra come usare PDO::prepare con PDO::ATTR_EMULATE_PREPARES impostato su true.

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

Il PDO_SQLSRV driver sostituisce internamente tutti i segnaposto con i parametri associati da PDOStatement::bindParam(). Al server viene pertanto inviata una stringa di query SQL senza segnaposto. Si consideri questo esempio:

$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();

Con PDO::ATTR_EMULATE_PREPARES impostato su false (caso predefinito), i dati inviati al database sono i seguenti:

"INSERT into Customers (CustomerName, ContactName) VALUES (:cus_name, :con_name)"
Information on :cus_name parameter
Information on :con_name parameter

Il server esegue la query usando la relativa funzionalità di query con parametri per i parametri di associazione. Con PDO::ATTR_EMULATE_PREPARES impostato su true, invece, la query inviata al server è essenzialmente la seguente:

"INSERT into Customers (CustomerName, ContactName) VALUES ('Cardinal', 'Tom B. Erichsen')"

L'impostazione di PDO::ATTR_EMULATE_PREPARES su true consente di ignorare alcune restrizioni di SQL Server. Ad esempio, SQL Server non supporta parametri denominati o posizionali in alcune clausole Transact-SQL. SQL Server ha inoltre un limite di associazione di 2.100 parametri.

Nota

Con emulazione prepara l'impostazione su true, la sicurezza delle query con parametri non è effettiva. Pertanto, l'applicazione deve assicurarsi che i dati associati ai parametri non contengano codice Transact-SQL dannoso.

Codifica

Per associare parametri con codifiche diverse, ad esempio UTF-8 o binaria, l'utente dovrà specificare chiaramente la codifica nello script PHP.

Il PDO_SQLSRV driver controlla innanzitutto la codifica specificata in PDO::bindParam() , ad esempio $statement->bindParam(:cus_name, "Cardinal", PDO::PARAM_STR, 10, PDO::SQLSRV_ENCODING_UTF8).

Se non è presente, il driver controlla se è impostata una codifica in PDO::prepare() o PDOStatement::setAttribute(). In caso contrario, il driver usa la codifica specificata in PDO::__construct() o PDO::setAttribute().

Inoltre, a partire dalla versione 5.8.0, quando si usa PDO::p repare con PDO::ATTR_EMULATE_PREPARES impostato su true, l'utente può usare i tipi di stringa estesi introdotti in PHP 7.2 per assicurarsi che venga usato il N prefisso. I frammenti di codice seguenti visualizzano varie alternative.

Nota

Per impostazione predefinita, emulate prepares è impostato su false e in questo caso le costanti di tipo stringa PDO estese verranno ignorate.

Usare l'opzione driver PDO::SQLSRV_ENCODING_UTF8 durante l'associazione

$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();

Usare l'attributo 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]);

Usare la costante PDO 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();

Impostare il tipo di parametro stringa predefinito 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]);

Limiti

Come è possibile osservare, l'associazione viene eseguita internamente dal driver. Al server viene inviata per l'esecuzione una query valida senza parametri. Rispetto al caso normale, alcune limitazioni comportano un risultato quando la funzionalità di query con parametri non è in uso.

  • Non funziona per i parametri associati come PDO::PARAM_INPUT_OUTPUT.
    • Quando l'utente specifica PDO::PARAM_INPUT_OUTPUT in PDO::bindParam(), viene generata un'eccezione PDO.
  • Non funziona per i parametri associati come parametri di output.
    • Quando l'utente crea un'istruzione preparata con segnaposto per i parametri di output (ossia con un segno uguale subito dopo il segnaposto, come SELECT ? = COUNT(*) FROM Table1), viene generata un'eccezione PDO.
    • Quando un'istruzione preparata richiama una stored procedure con un segnaposto come argomento per un parametro di output, non viene generata alcuna eccezione perché il driver non riesce a rilevare il parametro di output. Tuttavia, la variabile fornita dall'utente per il parametro di output rimane invariata.
  • I segnaposto duplicati per un parametro con codifica binaria non funzionano.