O que bind_param realiza?

Estou aprendendo sobre como evitar injeções de SQL e estou um pouco confuso.

Ao usar bind_param, não entendo o propósito. Na página do manual, encontrei este exemplo:

$stmt = mysqli_prepare($link, "INSERT INTO CountryLanguage VALUES (?, ?, ?, ?)"); mysqli_stmt_bind_param($stmt, 'sssd', $code, $language, $official, $percent); $code = 'DEU'; $language = 'Bavarian'; $official = "F"; $percent = 11.2; 

Agora, supondo que essas 4 variables ​​foram inseridas pelo usuário, não entendo como isso evita injeções de SQL. Pelo meu entendimento, eles ainda podem inserir o que eles querem lá.

Eu também não consigo encontrar uma explicação para o 'sssd' lá. O que isso faz? É isso que o torna seguro?

Pergunta final: eu li sobre outra pergunta que mysqli_real_escape_string está obsoleta, mas não diz isso no manual. Como é obsoleto? Não pode escaping mais de caracteres especiais por algum motivo?

Nota: Esta pergunta explicou o que bind_param faz, mas ainda não entendo por que é mais seguro ou mais protegido. Explicação Bind_param

Agora, supondo que essas 4 variables ​​foram inseridas pelo usuário, não entendo como isso evita injeções de SQL. Pelo meu entendimento, eles ainda podem inserir o que eles querem lá.

O princípio principal está usando a declaração preparada que é projetada para enviar consulta segura ao servidor db, isso pode ser feito escapando a input do usuário que não faz parte da consulta real, e também verificando a consulta sem nenhuma cláusula (onde) para verificar a validade da consulta antes de usar qualquer parâmetro.

A partir desta pergunta: PDO envia consulta em bruto para o MySQL enquanto Mysqli envia consulta preparada, ambos produzem o mesmo resultado

 $stmt = $mysqli->prepare("SELECT * FROM users WHERE username =?")) { $stmt->bind_param("i", $user); $user = "''1''"; 

logs do servidor:

  130802 23:39:39 175 Connect ****@localhost on testdb 175 Prepare SELECT * FROM users WHERE username =? 175 Execute SELECT * FROM users WHERE username =0 175 Quit 

Ao usar a declaração preparada, o servidor db verificará a consulta sem qualquer parâmetro, nesta fase, os erros podem ser detectados antes de ligar qualquer parâmetro e, se a consulta for válida, os parâmetros também serão enviados ao servidor para finalizar a consulta.

Do PHP Manual http://php.net/manual/en/mysqli.quickstart.prepared-statements.php :

Injeção de fuga e SQL

As variables ​​vinculadas serão escapadas automaticamente pelo servidor. O servidor insere seus valores de escape nos lugares apropriados no modelo de declaração antes da execução. Uma dica deve ser fornecida ao servidor para o tipo de variável vinculada, para criar uma conversão apropriada. Veja a function mysqli_stmt_bind_param () para obter mais informações.

Eu também não consigo encontrar uma explicação para o ‘sssd’ lá. O que isso faz? É isso que o torna seguro?

A resposta está aqui: http://php.net/manual/en/mysqli-stmt.bind-param.php

 i corresponding variable has type integer d corresponding variable has type double s corresponding variable has type string b corresponding variable is a blob and will be sent in packets 

Pergunta final: eu li sobre outra pergunta que mysqli_real_escape_string está obsoleta, mas não diz isso no manual. Como é obsoleto? Não pode escaping mais de caracteres especiais por algum motivo?

Você pode dar uma referência? Eu acho você incompreendido com ( mysql_real_escape_string() )

Ao usar declarações preparadas, você está separando as consultas SQL dos dados inseridos pelo usuário. Em vez de dados de input, você coloca espaços reservados (‘?’ Char) em sua consulta SQL. Em seguida, você envia a consulta para o servidor DBMS (por exemplo: MySQL) por meio do método “mysqli :: prepare”. Então, o servidor verifica se tudo está bem e, em caso afirmativo, ele aguarda dados de input. Até agora já conhece sua consulta. Apenas tem que aguardar dados de input para vincular a consulta.

Neste ponto, “bind_param” entra em ação, marcando espaços reservados aos dados inseridos pelo usuário. Observe que bind_param apenas vincula os dados aos espaços reservados deixando inalterada a consulta . Portanto, não há maneira de alterar a consulta SQL original, porque já enviou para o servidor por meio do método de preparação e porque você está enviando consultas SQL e dados de input separadamente para que os dados inseridos pelo usuário não possam interferir com as consultas.

DE QUALQUER FORMA…

O propósito real de usar uma declaração preparada no SQL é cortar o custo do processamento de consultas, NÃO para separar os dados da consulta. É assim que está sendo usado agora, e não como ele foi projetado para ser usado em primeiro lugar.

‘sssd’ significa “string”, “string”, “string” e “double”. Na verdade: $ code é uma string, $ language is a string, $ official é uma string e $ percent é um tipo duplo.

mysqli_real_escape_string não está obsoleto, mas mysql_real_escape_string está obsoleto (o primeiro é mysqlI, onde eu significo “melhorado”).