Você está fazendo tanto certo que eu realmente me sinto culpado por apontar que você está fazendo algo errado! :)
Você só pode usar instruções preparadas para parametrizar valores de campo — não identificadores SQL, como nomes de colunas ou tabelas. Portanto, você não poderá passar
A.x
, B.z
etc. em seu JOIN
critérios por meio de parâmetros de instrução preparados:você deve em vez disso, faça o que parece terrivelmente errado e concatene-os diretamente em sua string SQL. No entanto, nem tudo está perdido. Em alguma ordem vaga de preferência, você pode:
-
Apresente ao usuário uma lista de opções, da qual você posteriormente remonta o SQL:
<select name="join_a"> <option value="1">x</option> <option value="2">y</option> </select> <select name="join_b"> <option value="1">z</option> <option value="2">y</option> </select>
Em seguida, seu manipulador de formulários:
switch ($_POST['join_a']) { case 1: $acol = 'x'; break; case 2: $acol = 'y'; break; default: die('Invalid input'); } switch ($_POST['join_b']) { case 1: $bcol = 'z'; break; case 2: $bcol = 'y'; break; default: die('Invalid input'); } $sql .= "FROM A JOIN B ON A.$acol = B.$bcol";
Essa abordagem tem a vantagem de que, além de comprometer o PHP (nesse caso, você terá preocupações muito maiores do que a injeção de SQL), o SQL arbitrário absolutamente não pode encontrar seu caminho em seu RDBMS.
-
Certifique-se de que a entrada do usuário corresponda a um dos valores esperados:
<select name="join_a"> <option>x</option> <option>y</option> </select> <select name="join_b"> <option>z</option> <option>y</option> </select>
Em seguida, seu manipulador de formulários:
if (!in_array($_POST['join_a'], ['x', 'y']) or !in_array($_POST['join_b'], ['z', 'y'])) die('Invalid input'); $sql .= "FROM A JOIN B ON A.$_POST[join_a] = B.$_POST[join_b]";
Esta abordagem depende doin_array
do PHP função para segurança (e também expõe ao usuário seus nomes de coluna subjacentes, mas, devido ao seu aplicativo, duvido que isso seja uma preocupação).
-
Execute alguma limpeza de entrada, como:
mb_regex_encoding($charset); // charset of database connection $sql .= 'FROM A JOIN B ON A.`' . mb_ereg_replace('`', '``', $_POST['join_a']) . '`' . ' = B.`' . mb_ereg_replace('`', '``', $_POST['join_b']) . '`'
Embora aqui citemos a entrada do usuário e substituamos qualquer tentativa do usuário de escapar dessa citação, essa abordagem pode estar cheia de todos os tipos de falhas e vulnerabilidades (nomb_ereg_replace
do PHP função ou manipulação do MySQL de strings especialmente criadas dentro de um identificador entre aspas).
É longe melhor, se possível, usar um dos métodos acima para evitar a inserção de strings definidas pelo usuário no SQL.