2014-04-14 1 views
0

현재 사용자가 여러 가지 기준 (하나 또는 여러 가지 기준)을 사용하여 데이터베이스를 검색 할 수있는 웹 사이트의 매우 간단한 검색 기능을 만드는 중입니다. 많은, 다양한 숫자) 그리고 나는 특히 bind_param()을 사용하고있는 준비된 문항에 문제가있다.간단한 검색 기능, MySQL 준비된 문언 문제

... 
... 
$title = (empty($_POST['eventTitle'])) ? null : $_POST['eventTitle']; 
$venue = (empty($_POST['venue'])) ? null : $_POST['venue']; 
$catID = (empty($_POST['catID'])) ? null : $_POST['catID']; 
$start = (empty($_POST['start'])) ? null : $_POST['start']; 
$end = (empty($_POST['end'])) ? null : $_POST['end']; 
$price = (empty($_POST['price'])) ? null : $_POST['price']; 

include 'database_conn.php'; 

$sql = 'SELECT eventID, eventTitle, venueID, catID, eventStartDate, 
eventEndDate, eventPrice FROM te_events WHERE 1'; 

$sqlCondition = ''; 

$bindFirstArg = '"'; 
$bindSecondArg = ''; 

if($title !== null && !empty($title)) { 

    $sqlCondition = $sqlCondition . " AND eventTitle LIKE \"%" 
    . $title . "%\""; 

} 

if($venue !== null && $venue !== '0') { 

    $sqlCondition = $sqlCondition . " AND venueID=?"; 
    $bindFirstArg = $bindFirstArg . "s"; 
    $bindSecondArg = $bindSecondArg . ", " . $venue; 

} 

if($catID !== null && $catID !== '0') { 

    $sqlCondition = $sqlCondition . " AND catID=?"; 
    $bindFirstArg = $bindFirstArg . "s"; 
    $bindSecondArg = $bindSecondArg . ", " . $catID; 

} 

if($start !== null && $start !== '0') { 

    $sqlCondition = $sqlCondition . " AND eventStartDate=?"; 
    $bindFirstArg = $bindFirstArg . "s"; 
    $bindSecondArg = $bindSecondArg . ", " . $start; 

} 

if($end !== null && $end !== '0') { 

    $sqlCondition = $sqlCondition . " AND eventEndDate=?"; 
    $bindFirstArg = $bindFirstArg . "s"; 
    $bindSecondArg = $bindSecondArg . ", " . $end; 

} 

if($price !== null && !empty($price)) { 

    $sqlCondition = $sqlCondition . " AND eventPrice=?"; 
    $bindFirstArg = $bindFirstArg . "i"; 
    $bindSecondArg = $bindSecondArg . ", " . $price; 

} 

$sql = $sql . $sqlCondition; 
$bindFirstArg = $bindFirstArg . '"'; 

$search_stmt = $conn -> prepare($sql); 

if (false===$search_stmt) { 

    die('prepare() failed: ' . htmlspecialchars($conn->error)); 

} 


$search_stmt -> bind_param($bindFirstArg, $bindSecondArg); 
$search_stmt -> execute(); 
$search_stmt -> bind_result($eventIDRes, $eventTitleRes, $venueIDRes, 
$catIDRes, $eventStartRes, $eventEndRes, $eventPriceRes); 

while ($search_stmt->fetch()) { 

    printf ("%s %s %s %s %s %s %i\n", $eventIDRes, $eventTitleRes, 
    $venueIDRes, $catIDRes, $eventStartRes, $eventEndRes, $eventPriceRes); 

} 

mysqli_stmt_close($search_stmt); 

오류 난 상태를 수신하고있어

경고 : 여기

는 관련 PHP 코드 mysqli_stmt :: bind_param() [mysqli - stmt.bind-PARAM] : 번호 유형의 요소의 정의 문자열 라인 (101) "

에 /var/www/vhosts/numyspace.co.uk/web_users/home/~unn_w12019212/public_html/webdev/searchresult.php에 바인드 변수의 수와 일치하지 않습니다

아이디어가 있으십니까?

+0

쿼리에 포함 된 * each *'? '에 대한 매개 변수를'bind_param'에 전달해야합니다. 하나의 매개 변수 ('$ bindSecondArg') 만 전달합니다. –

+3

MySQLi prepared statements는 각 매개 변수에 대한 데이터 유형을 지정하도록 요구합니다. –

+0

@RocketHazmat - $ bindSecondArg는 사용자 선택에 따라 변수 이름을 포함하는 데 사용되는 변수이므로 실제로는 여러 변수가 있습니다. – Charlieabee

답변

1

당신은 첫 번째 매개 변수로 포맷뿐만 아니라, 쿼리에 ?에 대한 bind_param에게 별도의 인수를 전달해야합니다. 쉼표로 구분 된 문자열을 전달할 수는 없습니다. 작동하지 않습니다. 그냥 처음으로 ?으로 읽은 다음 나머지는 보내지 않았다고 불평합니다.

또한 $bindFirstArg 문자열 안에 따옴표를 추가하지 마십시오. bind_param은 모든 데이터 형식 목록 (i, d, s 또는 b)을 원하기 때문에 "자를 원하지 않습니다.

값을 배열로 집어 넣은 다음 call_user_func_array을 통해 bind_param으로 전화하면됩니다.

$sqlCondition = ''; 

$bindFirstArg = ''; 
$bindParams = array(); 


// You need to bind $title as well, otherwise you are wide open to SQL 
// injection and have just thrown out the benefits of prepared statements 
if($title !== null && !empty($title)) { 
    $sqlCondition .= " AND eventTitle LIKE ?"; 
    $bindFirstArg .= "s"; 

    // Add the `%` to the value, not the query 
    $title = "%{$title}%"; 
    // bind_param wants these to be references 
    $bindParams[] =& $title; 

} 

// Change all your ifs to look like this. 
// They need to push into the $bindParams array 
if($catID !== null && $catID !== '0') { 
    $sqlCondition .= " AND catID=?";  
    $bindFirstArg .= "s"; 

    // bind_param wants these to be references 
    $bindParams[] =& $catID; 
} 

// etc... 

$sql .= $sqlCondition; 
$search_stmt = $conn->prepare($sql); 

// Call bind_param with the correct number of parameters 
array_unshift($bindParams, $bindFirstArg); 
// This will make sure the parameters are passed correctly. 
// Each variable needs to be passed as a separate parameter 
call_user_func_array(array($search_stmt, 'bind_param'), $bindParams); 

$search_stmt->execute(); 
$search_stmt->bind_result($eventIDRes, $eventTitleRes, $venueIDRes, 
    $catIDRes, $eventStartRes, $eventEndRes, $eventPriceRes); 

while ($search_stmt->fetch()) { 
    printf ("%s %s %s %s %s %s %i\n", $eventIDRes, $eventTitleRes, 
     $venueIDRes, $catIDRes, $eventStartRes, $eventEndRes, $eventPriceRes); 
} 

$search_stmt->close(); 
+0

예, 작동합니다. 감사합니다. 그러나 나는 왜 그것이 작동 그래서 나는 가서 혼자서 연구해야할지 모르겠다! – Charlieabee

+0

마술은'call_user_func_array' 함수입니다 :-) –