Muitos bancos de dados mais maduros suportam o conceito de declarações preparadas.
O que são declarações preparadas? Pense nisso como um modelo compilado do SQL que você deseja executar, que pode ser personalizado usando parâmetros variáveis. Declarações preparadas podem trazer dois benefícios principais:
Uma consulta só precisa ser analisada (ou pré-processada) uma vez, mas pode ser executada várias vezes com parâmetros iguais ou diferentes. Quando uma consulta está pronta, o banco de dados analisa, compila e otimiza o plano para execução da consulta. Esse processo leva mais tempo para consultas complexas e pode tornar seu aplicativo significativamente mais lento se a mesma consulta precisar ser repetida várias vezes com parâmetros diferentes. Ao usar instruções preparadas, você pode evitar ciclos repetidos de análise/compilação/otimização. Simplificando, as instruções preparadas utilizam menos recursos e, portanto, são executadas mais rapidamente.
Os parâmetros fornecidos para instruções preparadas não precisam ser colocados entre aspas; Se seu aplicativo usar apenas instruções preparadas, você pode ter certeza de que a injeção de SQL não ocorrerá. (No entanto, se outras partes da consulta forem construídas a partir de entradas sem escape, ainda existe o risco de injeção de SQL).
As instruções preparadas são tão úteis que sua única característica é que o PDO simulará o processamento quando o driver não o suportar. Isso garante que os aplicativos possam usar o mesmo padrão de acesso a dados, independentemente de o banco de dados ter tais recursos.
O exemplo a seguir executa uma consulta de inserção substituindo os espaços reservados nomeados correspondentes por nome e valor.
<?php$stmt = $dbh->prepare("INSERT INTO REGISTRY (nome, valor) VALUES (:nome, :valor)");$stmt->bindParam(':nome', $nome);$stmt- >bindParam(':value', $value);//Inserir uma linha $name = 'one';$value = 1;$stmt->execute();// Insira outra linha com valores diferentes $name = 'two';$value = 2;$stmt->execute();?>
O exemplo a seguir executa uma consulta de inserção substituindo o espaço reservado ?
<?php$stmt = $dbh->prepare("INSERT INTO REGISTRY (nome, valor) VALUES (?, ?)");$stmt->bindParam(1, $name);$stmt->bindParam(2, $value);//Inserir uma linha $name = 'one';$value = 1;$stmt->execute();// Insira outra linha com valores diferentes $name = 'two';$value = 2;$stmt->execute();?>
O exemplo a seguir obtém dados com base no valor-chave no formulário fornecido. A entrada do usuário é citada automaticamente, portanto não há perigo de ataques de injeção de SQL.
<?php$stmt = $dbh->prepare("SELECT * FROM REGISTRY onde nome = ?");if ($stmt->execute(array($_GET['nome']))) { while ($row = $stmt->fetch()) { print_r($row }});>
Se o driver do banco de dados suportar, o aplicativo também poderá vincular parâmetros de saída e entrada. Os parâmetros de saída são frequentemente usados para obter valores de procedimentos armazenados. Os parâmetros de saída são um pouco mais complicados de usar do que os parâmetros de entrada porque, ao vincular um parâmetro de saída, você deve saber o comprimento do parâmetro fornecido. Se o valor vinculado a um parâmetro for maior que o comprimento recomendado, será gerado um erro.
<?php$stmt = $dbh->prepare("CALL sp_returns_string(?)");$stmt->bindParam(1, $return_value, PDO::PARAM_STR, 4000); // Chama o procedimento armazenado $stmt-> execute();print "procedimento retornou $return_valuen";?>
Você também pode especificar parâmetros que tenham valores de entrada e saída, com sintaxe semelhante aos parâmetros de saída. No próximo exemplo, a string "hello" é passada para o procedimento armazenado e, quando o procedimento armazenado retorna, hello é substituído pelo valor retornado pelo procedimento armazenado.
<?php$stmt = $dbh->prepare("CALL sp_takes_string_returns_string(?)");$value = 'hello';$stmt->bindParam(1, $value, PDO::PARAM_STR|PDO::PARAM_INPUT_OUTPUT, 4000 ); // Chama o procedimento armazenado $stmt->execute();print "procedimento retornado $valorn";?>
<?php$stmt = $dbh->prepare("SELECT * FROM REGISTRY where name LIKE '%?%'");$stmt->execute(array($_GET['name']));// Símbolo de espaço reservado deve ser usado em todo o valor $stmt = $dbh->prepare("SELECT * FROM REGISTRY where name LIKE ?");$stmt->execute(array("%$_GET[nome]%"));?>