0

データベースを照会するスクリプトがあり、4つのオプションの1つまたはすべてを使用して照会できる必要があります。オプションは、start sku、end sku(検索する範囲が必要なため、これは1つのオプションです)、作成者、作成日です。私は多くのif..elseifステートメントを使用してこれを行うことができることを知っていますが、より良い、より簡単な方法があると考えなければなりません。これが私がこれまでに持っているコードです:

$start =mysql_real_escape_string ($_POST['skuStart']);
$end = mysql_real_escape_string($_POST['skuEnd']);
$source = mysql_real_escape_string($_POST['source']);
$processDate = mysql_real_escape_string($_POST['processDate']);

if(!empty($start) && !empty($end) && empty($source) && empty($processDate)){
$result = $conn->query("Select * from inventory where sku >= $start and sku <= $end");

 } elseif (empty($start) && empty($end) && !empty($source) && empty($processDate)){
$result = $conn->query("Select * from inventory where created_by = '$source'");

 } elseif (empty($start) && empty($end) && empty($source) && !empty($processDate)) {
$result = $conn->query("Select * from inventory where date_process = '$processDate'");

} elseif(!empty($start) && !empty($end) && !empty($source) && empty($processDate)){
$result = $conn->query("Select * from inventory where sku >= $start and sku <= $end and created_by = '$source'");

} else {
$result = $conn->query("Select * from inventory where sku >= '$start' and sku <= '$end' and created_by = '$source' and date_process = '$processDate'");
}

while($row = $result->fetch_assoc())
    {

        $skuArray[$x] = $row['sku'];
        $isbnArray[$x] = $row['isbn13'];
        $qtyArray[$x] = $row['quantity'];
        $defectArray[$x] = $row['defect_id'];
        $sourceArray[$x] = $row['source_id'];
        $featureArray[$x] = $row['feature_id'];
        $locationArray[$x] = $row['location_id'];
        $processDateArray[$x] = $row['date_process'];
        $bookTypeArray[$x] = $row['book_type_id'];
        $createdByArray[$x] = $row['created_by'];
        $modifiedByArray[$x] = $row['modified_by'];

        $x++;

この非常に大雑把な形式は機能していますが、if elseifを単純化する方法はありますか?

注:SQLインジェクションを防ぐためにPDOを使用する必要があることはわかっていますが、まだ完全には学習していないため、これを使用しています。

4

4 に答える 4

2
<?php
$db = new PDO('mysql:host=localhost;dbname=my_db', 'user', 'passwd');

$sql = "SELECT * FROM INVENTORY ";

$where  = array ();
$params = array ();
if (! empty($start) && ! empty($end) {
    $where[] = " sku >= :start AND sku <= :end ";
    $params['start'] = $start;
    $params['end']   = $end;
}
if (! empty($source)) {
    $where[] = " created_by = :source ";
    $params['source'] = $source;
}
if (! empty($processDate)) {
    $where[] = " date_process = :date_process ";
    $params['date_process'] = $processDate;
}

if (! empty($where)) {
    $sql .= ' WHERE ' . join (' AND ', $where);
}

$statement = $db->prepare($sql);
$statement->execute($params);

while ($row = $statement->fetch(PDO::FETCH_ASSOC)) {
   // ...
}
于 2012-07-31T12:39:03.213 に答える
1
$q = array();
if (!empty($start))
  $q[] = "sku >= '$start'";
if (!empty($end))
  $q[] = "sku <= '$end'";
#...
$q = join(') AND (', $q);
$q = "SELECT * FROM inventory WHERE ($q)";

または、これをさらに一歩進めることができます。

$params = array(
   'skuStart' => "sku >= '##'",
   'skuEnd' => "'sku <= '##'",
   #...
);

$q = array();
foreach($params as $k=>$sql) {
   $v = mysql_real_escape_string($_POST[$k]);
   if (!empty($v)) {
     $sql = tr_replace('##', $v, $sql);
     $q[] = $sql;
   }
}
$q = join(') AND (', $q);

次に、検証用のタイプを追加したり、メタデータを強化して小さなフレームワークを構築したりすることができます...

繰り返していると感じるときはいつでも、既存のソリューション(ライブラリ/フレームワーク)を確認するか、ソリューションを構築する必要があります... DRY

于 2012-07-31T12:33:12.937 に答える
1

すでに認識している問題を脇に置いて-PDOに切り替えてバインドされたパラメーターを使用する-次の方法でコードを少し明確にすることができます。

<?php

$start          = mysql_real_escape_string ($_POST['skuStart']);
$end            = mysql_real_escape_string($_POST['skuEnd']);
$source         = mysql_real_escape_string($_POST['source']);
$processDate    = mysql_real_escape_string($_POST['processDate']);
$where          = array();

if(!empty($start))
{
    $where[] = 'sku >= ' . $start;
}

if(!empty($end))
{
    $where[] = 'sku <= ' . $end;
}

if(!empty($source))
{
    $where[] = 'created_by = \''.$source .'\'';
}

if(!empty($processDate))
{
    $where[] = 'date_process = \''.$processDate .'\'';
}

$query = 'SELECT * FROM inventory';

if(count($where))
{
    $query .= ' WHERE ' . implode(' AND ', $where);
}

$result = $conn->query($query);

while($row = $result->fetch_assoc())
    {

        $skuArray[$x] = $row['sku'];
        $isbnArray[$x] = $row['isbn13'];
        $qtyArray[$x] = $row['quantity'];
        $defectArray[$x] = $row['defect_id'];
        $sourceArray[$x] = $row['source_id'];
        $featureArray[$x] = $row['feature_id'];
        $locationArray[$x] = $row['location_id'];
        $processDateArray[$x] = $row['date_process'];
        $bookTypeArray[$x] = $row['book_type_id'];
        $createdByArray[$x] = $row['created_by'];
        $modifiedByArray[$x] = $row['modified_by'];

        $x++;
于 2012-07-31T12:36:34.423 に答える
0

クエリビルダーを使用できます。たとえば、フレームワークを使用しない場合は、https://github.com/jstayton/QueryBuilder (googleで最初に設立されました)。

于 2012-07-31T12:40:08.190 に答える