如果条件PHP忽略函数

时间:2017-08-10 12:51:04

标签: php mysql

我有一些代码,但是当category_id = 1,4,9时,我希望它忽略'customer :: $ data ['vehicle_id']'。

我一直在努力使用下面的代码并且添加另一个功能是出于我的能力,所以任何建议都会很棒。提前谢谢。

如果未选择vehicle_id,则可以正常工作。

if (empty($_GET['manufacturer_id'])) {
  $manufacturers_query = database::query(
    "select distinct m.id, m.name from ". DB_TABLE_PRODUCTS ." p
    left join ". DB_TABLE_MANUFACTURERS ." m on m.id = p.manufacturer_id ".
    (!empty($_GET['category_id']) ? " left join " . DB_TABLE_PRODUCTS_TO_CATEGORIES . " pc on pc.product_id = p.id " : "").
    (!empty(customer::$data['vehicle_id']) ? " left join " . DB_TABLE_PRODUCTS_TO_VEHICLES . " ptv on ptv.product_id = p.id " : "").
    "where p.status
    and manufacturer_id
    ". (!empty($_GET['category_id']) ? "and pc.category_id = " . (int)$_GET['category_id']  : "") ."
    ". (!empty(customer::$data['vehicle_id']) ? "and ptv.vehicle_id = " . (int)customer::$data['vehicle_id']  : "") ."
    order by m.name asc;"
  );

我尝试过使用它:

". (!empty(customer::$data['vehicle_id']) && (!empty($_GET['category_id']) || !array_intersect(array(1, 4, 9), $_GET['category_id'])) ? "and ptv.vehicle_id = " . (int)customer::$data['vehicle_id']  : "") ."

编辑:

while($manufacturer = database::fetch($manufacturers_query)) {
      $box_filter->snippets['manufacturers'][] = array(
        'id' => $manufacturer['id'],
        'name' => $manufacturer['name'],
        'href' => document::ilink('manufacturer', array('manufacturer_id' => $manufacturer['id'])),
      );
    }

1 个答案:

答案 0 :(得分:0)

我已经采用了相当混乱的代码并对其进行了重构,因此它在很多小的和大的方面都是可读的,可维护的和更好的。它并不完美,但现在可以推理出来。

我还为您排除了SQL注入机会,但您仍需要重新设计database::query()函数,以便它接受一个参数数组,以便在准备好的语句执行中与您的SQL查询一起使用。我在您的查询中使用了命名占位符以使其可读。

以这种方式执行重构,允许我添加一个布尔标志,如果你的忽略条件为真,我可以设置它($_GET['category_id']等于[1,4,9]之一)     

if (empty($_GET['manufacturer_id'])) 
{
    $ignoreVehicleId = false;
    $params = [];
    $query = "select distinct m.id, m.name 
                from ${DB_TABLE_PRODUCTS} p
                left join ${DB_TABLE_MANUFACTURERS} m on m.id = p.manufacturer_id ";

    if( !empty($_GET['category_id'])
    {
        $query .= " left join ${DB_TABLE_PRODUCTS_TO_CATEGORIES} pc on pc.product_id = p.id ";

        if(in_array($_GET["category_id"], [1,4,9])   // <---  This array should be better documented to not use MAGIC NUMBERS. What is 1,4 or 9?
        {
            $ignoreVehicleId = true;
        }
    }

    if( $ignoreVehicleId === false && !empty( customer::$data['vehicle_id'])
    {
        $query .= " left join ${DB_TABLE_PRODUCTS_TO_VEHICLES} ptv on ptv.product_id = p.id ";
    }

    $query .= "where p.status and manufacturer_id ";

    /*
    *   In the following two IF's named parameters for prepared statements are being used.
    *   You need to refactor the database::query() function to accept a params array.
    *   Read up on using prepared statements with mysqli_* or better, PDO. 
    *
    *   DO NOT BUILD QUERIES WITH VARIABLES ANY OTHER WAY!!! 
    *
    *   If you do you are asking to be pwned by someone using your less than secure
    *   practises to do SQL Injection.
    */
    if( !empty($_GET['category_id'])
    {
        " and pc.category_id = :category_id ";
        $params[":category_id"] = (int)$_GET['category_id'];
    }

    if( $ignoreVehicleId === false && !empty(customer::$data['vehicle_id'])
    {
        " and ptv.vehicle_id = :vehicle_id ";
        $params[":vehicle_id"] = (int)customer::$data['vehicle_id'];
    }

    $query .= " order by m.name asc;"

    $manufacturers_query = database::query($query, $params);

}