Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Como incluir uma variável PHP dentro de uma instrução MySQL


As regras para adicionar uma variável PHP dentro de qualquer instrução MySQL são claras e simples:
  1. Qualquer variável que represente um literal de dados SQL , (ou, para simplificar - uma string SQL ou um número) DEVE ser adicionado por meio de uma instrução preparada. Sem exceções.
  2. Qualquer outra parte da consulta, como uma palavra-chave SQL, uma tabela ou um nome de campo ou um operador, deve ser filtrada por uma lista branca .

Portanto, como seu exemplo envolve apenas literais de dados, todas as variáveis ​​devem ser adicionadas por meio de espaços reservados (também chamados de parâmetros). Para fazer isso:
  • Em sua instrução SQL, substitua todas as variáveis ​​por espaços reservados
  • preparar a consulta resultante
  • vincular variáveis ​​para espaços reservados
  • executar a consulta

E aqui está como fazer isso com todos os drivers de banco de dados PHP populares:

Adicionando literais de dados usando mysql ext


Tal driver não existe .

Adicionando literais de dados usando mysqli

$type = 'testing';
$reporter = "John O'Hara";
$query = "INSERT INTO contents (type, reporter, description) 
             VALUES(?, ?, 'whatever')";
$stmt = $mysqli->prepare($query);
$stmt->bind_param("ss", $type, $reporter);
$stmt->execute();

O código é um pouco complicado, mas a explicação detalhada de todos esses operadores pode ser encontrada no meu artigo, Como executar um INSERIR consulta usando Mysqli , bem como uma solução que facilita drasticamente o processo.

Para uma consulta SELECT, você precisará adicionar apenas uma chamada para get_result() método para obter um mysqli_result familiar a partir do qual você pode buscar os dados da maneira usual:
$reporter = "John O'Hara";
$stmt = $mysqli->prepare("SELECT * FROM users WHERE name=?");
$stmt->bind_param("s", $reporter);
$stmt->execute();
$result = $stmt->get_result();
$row = $result->fetch_assoc(); // or while (...)

Adicionando literais de dados usando PDO

$type = 'testing';
$reporter = "John O'Hara";
$query = "INSERT INTO contents (type, reporter, description) 
             VALUES(?, ?, 'whatever')";
$stmt = $pdo->prepare($query);
$stmt->execute([$type, $reporter]);

No PDO, podemos combinar as partes bind e execute, o que é muito conveniente. O PDO também suporta espaços reservados nomeados que alguns consideram extremamente convenientes.

Adicionar palavras-chave ou identificadores


Às vezes temos que adicionar uma variável que representa outra parte de uma consulta, como uma palavra-chave ou um identificador (um banco de dados, uma tabela ou um nome de campo). É um caso raro, mas é melhor estar preparado.

Nesse caso, sua variável deve ser verificada em relação a uma lista de valores explicitamente escrito em seu roteiro. Isso é explicado em meu outro artigo, Adicionando um nome de campo na cláusula ORDER BY com base na escolha do usuário :

Infelizmente, o PDO não tem espaço reservado para identificadores (nomes de tabelas e campos), portanto, um desenvolvedor deve filtrá-los manualmente. Esse filtro geralmente é chamado de "lista branca" (onde apenas listamos valores permitidos) em oposição a uma "lista negra" onde listamos valores não permitidos.

Portanto, temos que listar explicitamente todas as variantes possíveis no código PHP e depois escolher entre elas.

Aqui está um exemplo:
$orderby = $_GET['orderby'] ?: "name"; // set the default value
$allowed = ["name","price","qty"]; // the white list of allowed field names
$key = array_search($orderby, $allowed, true); // see if we have such a name
if ($key === false) { 
    throw new InvalidArgumentException("Invalid field name"); 
}

Exatamente a mesma abordagem deve ser usada para a direção,
$direction = $_GET['direction'] ?: "ASC";
$allowed = ["ASC","DESC"];
$key = array_search($direction, $allowed, true);
if ($key === false) { 
    throw new InvalidArgumentException("Invalid ORDER BY direction"); 
}

Após esse código, tanto $direction e $orderby variáveis ​​podem ser colocadas com segurança na consulta SQL, pois são iguais a uma das variantes permitidas ou haverá um erro.

A última coisa a mencionar sobre os identificadores, eles também devem ser formatados de acordo com a sintaxe específica do banco de dados. Para MySQL deve ser backtick caracteres ao redor do identificador. Portanto, a string de consulta final para nosso pedido por exemplo seria
$query = "SELECT * FROM `table` ORDER BY `$orderby` $direction";