PHP + MYSQL:Vinculação de parâmetro/resultado variável com instruções preparadas

StackOverflow https://stackoverflow.com/questions/12656

  •  08-06-2019
  •  | 
  •  

Pergunta

Em um projeto que estou prestes a encerrar, escrevi e implementei uma solução de mapeamento objeto-relacional para PHP.Antes que os céticos e sonhadores gritem "como diabos?", relaxe - não encontrei uma maneira de fazer a ligação estática tardia funcionar - estou apenas trabalhando em torno disso da melhor maneira possível.

De qualquer forma, atualmente não estou usando instruções preparadas para consulta, porque não consegui encontrar uma maneira de passar um número variável de argumentos para o bind_params() ou bind_result() métodos.

Por que preciso apoiar um número variável de argumentos, você pergunta?Porque a superclasse dos meus modelos (pense na minha solução como um aspirante a PHP ActiveRecord hackeado) é onde a consulta é definida e, portanto, o método find(), por exemplo, não sabe quantos parâmetros seriam necessários para vincular .

Agora, já pensei em construir uma lista de argumentos e passar uma string para eval(), mas não gosto muito dessa solução - prefiro apenas implementar minhas próprias verificações de segurança e transmitir instruções.

Alguém tem alguma sugestão (ou história de sucesso) sobre como fazer isso?Se você puder me ajudar a resolver esse primeiro problema, talvez possamos resolver a vinculação do conjunto de resultados (algo que suspeito que será mais difícil, ou pelo menos consumirá mais recursos se envolver uma consulta inicial para determinar a estrutura da tabela).

Foi útil?

Solução

Em PHP você pode passar um número variável de argumentos para uma função ou método usando call_user_func_array.Um exemplo de método seria:

call_user_func_array(array(&$stmt, 'bindparams'), $array_of_params);

A função será chamada com cada membro do array passado como seu próprio argumento.

Outras dicas

Você precisa ter certeza de que $array_of_params é um array de links para variáveis, não se valorizam.Deveria estar:

$array_of_params[0] = &$param_string; //link to variable that stores types

E então...

$param_string .= "i";
$user_id_var = $_GET['user_id'];//
$array_of_params[] = &$user_id_var; //link to variable that stores value

Caso contrário (se for uma matriz de valores), você obterá:

Aviso PHP:Espera-se que o parâmetro 2 para mysqli_stmt::bind_param() seja uma referência


Mais um exemplo:

$bind_names[] = implode($types); //putting types of parameters in a string
for ($i = 0; $i < count($params); $i++)
{
   $bind_name = 'bind'.$i; //generate a name for variable bind1, bind2, bind3...
   $$bind_name = $params[$i]; //create a variable with this name and put value in it
   $bind_names[] = & $$bind_name; //put a link to this variable in array
}

e BOOOOOM:

call_user_func_array( array ($stmt, 'bind_param'), $bind_names); 

Não tenho permissão para editar, mas acredito no código

call_user_func_array(array(&$stmt, 'bindparams'), $array_of_params);

A referência antes de $stmt não é necessária.Desde $stmt é o objeto e bindparams é o método nesse objeto, a referência não é necessária.Deveria ser:

call_user_func_array(array($stmt, 'bindparams'), $array_of_params);

Para mais informações, consulte o manual do PHP em Funções de retorno de chamada."

call_user_func_array(array(&$stmt, 'bindparams'), $array_of_params);

Não funcionou para mim no meu ambiente, mas essa resposta me colocou no caminho certo.O que realmente funcionou foi:

$sitesql = '';
$array_of_params = array();
foreach($_POST['multiselect'] as $value){
    if($sitesql!=''){
        $sitesql .= "OR siteID=? ";
        $array_of_params[0] .= 'i';
        $array_of_params[] = $value;
    }else{
        $sitesql = " siteID=? ";
        $array_of_params[0] .= 'i';
        $array_of_params[] = $value;
    }
}

$stmt = $linki->prepare("SELECT IFNULL(SUM(hours),0) FROM table WHERE ".$sitesql." AND week!='0000-00-00'");
call_user_func_array(array(&$stmt, 'bind_param'), $array_of_params);
$stmt->execute();
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top