0

mysqli 準備済みステートメントを使用して検索パラメーターが条件付きであるクエリを作成するには、適切な構造が必要です。$query -> bind_param('sss',$date,$time,$place);

'sss'適用方法と'$date,$time,$place'パラメータを後で順番に適用する方法がわかりません。それらを変数として渡すことはできますか?

古い MySQL の方法:

<?php

// date is obligatory

$date = mysql_real_escape_string($_GET["date"]);

$query="SELECT * FROM dbase WHERE date='$date'"; 

// time field is custom

if(!empty($_GET["time"])) {

    $time= mysql_real_escape_string($_GET["time"]);
    $buildQuery[] = "time='$time'";

}

// place field is also custom

if(!empty($_GET["place"])) {

    $place= mysql_real_escape_string($_GET["place"]);
    $buildQuery[] = "place='$place'";

}

// building query

if(!empty($build)) {

    $query .= ' AND '.implode(' AND ',$build).' ORDER BY date';

}

?>
4

3 に答える 3

1

これは、PDO が MySQLi よりもはるかに簡単な良い例です。

$query="SELECT * FROM dbase";
$terms = array("date" => $date);
$params = array();

// time field is custom

if(isset($_GET["time"])) {
    $terms["sType"] = $time;
}

// place field is also custom

if(isset($_GET["place"])) {
    $terms["place"] = $place;  
}

// building query

if(!empty($terms)) {
    $query .= "WHERE " . implode(" AND ", 
        array_map(function($term) { return "$term = ?"; }, array_keys($terms));
    $params = array_values($terms);
}
$query .= "ORDER BY date";

$stmt = $pdo->pepare($query);
$stmt->execute($params);

PS: 列にtimeplacesTypeの両方を含めるつもりだったかどうかを質問する必要があります。リレーショナル データベースのベスト プラクティスを破っているようです。単なるタイプミスでない限り。

于 2013-07-04T23:17:10.563 に答える
0

テストされていませんが、このようなことができるはずです

$types = array();
$vals = array();

if(isset($_GET["time"])) {
    $types[] = 's';
    $vals[] = $_GET["time"];
    $buildQuery[] = "sType = ?";
}

//...etc...

$args = array_merge(array(join($types)), $vals);
$callable = array($mysqli, 'bind_param');
call_user_func_array($callable, $args));

http://php.net/manual/en/language.types.callable.php

しかし、別のアプローチがあります。SQLでロジックを使用するだけです:

select *
from tbl
where (date = ? or ? = '')
  and (time = ? or ? = '')
  and (place = ? or ? = '')

上記は、各引数を2回バインドし、それらを文字列としてバインドすることを前提としていますが、クエリ文字列パラメーターが設定されていない場合は空の文字列をバインドします...必要に応じて、のようなものを介してnullとしてバインドすることもできます(date = ? or ? is null).

$mysqli->bind_param('ssssss', $date,$date, $time,$time, $place,$place);

ps、mysql オプティマイザーは、その単純なロジックを短時間で処理します。

于 2013-07-04T23:58:21.333 に答える
0

ヤギの返信に基づいて、更新するフィールドが条件付きである UPDATE ステートメントを使用した完全でテスト済みの回答を次に示します。ID (自動インクリメント)、Varchar1 (varchar255)、Varchar2 (varchar255) の 3 つのフィールドを持つ非常に単純なテーブル構造を使用しました。このスクリプトでは、最初の 3 つのレコードの 2 つの varchar フィールドを更新します。このスクリプトに基づいて、更新するフィールドを条件付きで追加または削除するのは非常に簡単です。

$mysqli = new mysqli(...);

$types = array();
$vals = array();
$query = array();

// varchar1
$types[] = 's';
$vals[] = 'foo1';
$query[] = "varchar1=?";

// varchar2
$types[] = 's';
$vals[] = 'foo2';
$query[] = "varchar2=?";

$sql = "UPDATE test SET ".implode(",", $query)." WHERE id IN (1,2,3)";
$stmt = $mysqli->prepare($sql);

$args = array_merge(array(implode($types)), $vals);

$callable = array($stmt, 'bind_param');
call_user_func_array($callable, refValues($args));

$stmt->execute();

function refValues($arr) {
    if (strnatcmp(phpversion(),'5.3') >= 0) //Reference is required for PHP 5.3+ 
    { 
        $refs = array(); 
        foreach($arr as $key => $value) 
            $refs[$key] = &$arr[$key]; 
        return $refs; 
    } 
    return $arr; 
}
于 2016-03-14T13:33:33.820 に答える