webForumDet fria alternativet

Lägga till fält för sökning? (PHP-MySQL)

PHP

1 svar · 835 visningar · startad av bassebhu

Medlem sedan nov. 20016 480 inlägg
Frågan#1

Hallå!

Jag använder följande kod för att söka i en databas. Det funkar bra, men jag skulle vilja söka på mer än ett fält. Har aldrig pillat med prepared statements förut så vet inte hur jag får in ett till frågetecken i frågan :)

Skickar med rätt mycket kod, men scrolla ner till SELECT-delen samt nästa kodstycke där jag visar vad jag vill så borde det vara superlätt att förstå.

$term = trim($_GET['term']);
 
$a_json = array();
$a_json_row = array();
 
//$a_json_invalid = array(array("id" => "#", "value" => $term, "label" => "Only letters and digits are permitted..."));
//$json_invalid = json_encode($a_json_invalid);
 
// replace multiple spaces with one
$term = preg_replace('/\s+/', ' ', $term);
 
// SECURITY HOLE ***************************************************************
// allow space, any unicode letter and digit, underscore and dash
if(preg_match("/[^\040\pL\pN_-]/u", $term)) {
  print $json_invalid;
  exit;
}
// *****************************************************************************
 
// database connection
$conn = new mysqli(DB_HOST, DB_USER, DB_PASSWORD, DB_DATABASE);

if($conn->connect_error) {
  echo 'Database connection failed...' . 'Error: ' . $conn->connect_errno . ' ' . $conn->connect_error;
  exit;
} else {
  $conn->set_charset('utf8');
}
 
$parts = explode(' ', $term);
$p = count($parts);

/**
 * $stmt->bind_param('s', $param); does not accept params array
 * and if call_user_func_array will be used, array params need to passed by reference
 */
$a_part_to_search = array();
$a_parts = array();

$part_type = '';

for($i = 0; $i < $p; $i++) {
  $part_type .= 's';
}
$a_parts[] = & $part_type;
 
foreach($parts as $part) {
  array_push($a_part_to_search, '%' . $part . '%');
}
for($i = 0; $i < $p; $i++) {
  $a_parts[] = & $a_part_to_search[$i];
}
 
$sql = 'SELECT w_title, w_desc FROM works
WHERE NOT w_visibility = 9 ';
for($i = 0; $i < $p; $i++) {
  $sql .= ' AND w_title LIKE ?';
}
$sql .= ' ORDER BY w_title ASC';
 
/* Prepare statement */
$stmt = $conn->prepare($sql);
if($stmt === false) {
  $user_error = 'Wrong SQL: ' . $sql . '<br>' . 'Error: ' . $conn->errno . ' ' . $conn->error;
  trigger_error($user_error, E_USER_ERROR);
}
 
/* Bind parameters. TYpes: s = string, i = integer, d = double,  b = blob */
//$stmt->bind_param('s', $param); does not accept params array
call_user_func_array(array($stmt, 'bind_param'), $a_parts);
 
/* Execute statement */
$stmt->execute();
 
$stmt->bind_result($title, $desc);

Jag testade detta men det gav mig följande fel:
"<b>Warning</b>: mysqli_stmt::bind_param() [<a href='mysqli-stmt.bind-param'>mysqli-stmt.bind-param</a>]: Number of variables doesn't match number of parameters in prepared statement"

$sql = 'SELECT w_title, w_desc FROM works
WHERE NOT w_visibility = 9 ';
for($i = 0; $i < $p; $i++) {
  $sql .= ' AND w_title LIKE ?';
  $sql .= ' OR w_desc LIKE ?';
}
$sql .= ' ORDER BY w_title ASC';

Kan man skriva typ "AND w_title||w_desc LIKE ?" eller liknande?
Om inte, hur anger jag ett till frågetecken. I det här fallet är det ju samma värde som testas mot två fält.

Tack för hjälp!

Medlem sedan juni 20031 837 inlägg
#2

Du får felmeddelandet pga att arrayn $a_parts inte innehåller lika många element som du har ? i din SQL-sats.

Du binder ihop det med den här raden:
call_user_func_array(array($stmt, 'bind_param'), $a_parts);

270 ms totalt · 4 externa anrop · v20260731065814-full.86ec41c2
130 ms — deklarationer (db)
0 ms — hämta statistik (cache)
132 ms — hämta tråd, inlägg och bilagor (db)
129 ms — ändringar (db)