I am writing a simple search engine for my database using mysqli and prepared statements, I’m currently using call_user_func_array to dynamically create my query. My question is: is there a faster or better way to do this using mysqli?
here’s my code:
<?php
session_start();
require('../../../scripts/bkfunctions.php');
header('Cache-Control: no-cache, must-revalidate');
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Content-type: application/json');
//////////////////
$resultParameters = array();
$paramsArr =array();
$results = array();
////DB OPEN//////////////////////////////////////////
$conn = dbConnect("ITbunker");
$paramsArr = explode(",", $_GET['paramsQuery']);
$qStr="";
$bindParams = array('s');
////////////////////////////////////
foreach ($paramsArr as $n=>$k) {
if ($n==0) {
$qStr = "SELECT * FROM trabajosEnSubasta WHERE MATCH(titulo, descripcion, habilidades) AGAINST (?)";
}
else {
$qStr .= " UNION SELECT * FROM trabajosEnSubasta WHERE MATCH(titulo, descripcion, habilidades) AGAINST (?)";
$bindParams[0] .= 's';
}
array_push($bindParams, $k);
}
///////////////////////////////////////
///Preparar query y ejecutar
$stmt = $conn->prepare($qStr);
call_user_func_array(array($stmt, 'bind_param'), makeValuesReferenced($bindParams));
$stmt->execute();
/////////////////////////////////////////////////////////////////////////////////////////*
$meta = $stmt->result_metadata();
while ($campo = $meta->fetch_field() ) {
$resultParameters[] = &$row[$campo->name];
}
call_user_func_array(array($stmt, 'bind_result'), $resultParameters);
$i=0;
while ( $stmt->fetch() ) {
$i++;
foreach( $row as $key => $val ) {
$results["resultado$i"][$key] = $val;
}
}
echo json_encode($results);
///////////////////////////////////////////////////
$conn->close();
?>
You have a lot of things to address in your question – and
call_user_func_arrayisn’t one of them.Look at your query
This is the sort of query you are building:
And.. it begs the question why you’d do that. This is functionally identical, and likely much faster to execute:
Look at your logic
Therefore requesting a url like
/foo?paramsQuery=a,b,c,d,e,f,g,h,i,jwill currently trigger a 10 table union query, if you update your query syntax, that’ll be a 10 full-text-index query. Is that really what you want? It might be – but for example if someone searches for a known habilidad it’d be a lot more efficient to do:A full-text index is relatively expensive to query, and shouldn’t really be your only means of searching your data.
Profile your code
I have to assume you’re asking about
call_user_func_arraybecause your code is slow to execute. Don’t guess where problems are in code look and find out.Dont waste your time optimizing 0.01%
call_user_func_arraydoes have a cost to use, and that’s why code like this exists. BUT the difference is really, really insignificant (especially in light of the super-heavy UNION queries in the question) unless you’re calling it hundreds+ times. Focus on the things that have the biggest performance impact on your application, not the things that make absolutely no measurable difference one way or the other.