提问者:小点点

在PHP中使用PDO从多个表中搜索哪一种更好的方法?


我有一个HTML表单,其中有一个搜索字段为一个产品名称,下面是复选框,每个复选框为一个商店的产品名称是要搜索。 用户可以通过勾选框从多个店铺进行搜索。 表单向服务器发送一个GET请求,服务器上有一个数据库,该数据库中有用于不同商店的不同表。

<form action="price.php" method="get">
    <input type="text" id="query" name="query" value="">
    <input type="checkbox" name="shop1" id="shop1">
    <input type="checkbox" name="shop2" id="shop2">
    <input type="submit" name="submit" value="submit">
</form>

所以在服务器端,我编写了一个PHP代码,它将从那些表中搜索产品名称,这些表对应于用户检查的商店。 由于将来我会添加越来越多的商店,下面哪种PHP代码更适合呢?

版本1

<?php
function search($pdo, $shop) {
if ( isset($_GET[$shop]) && ($_GET['query'] !== "") ) {
    switch ($shop) {
        case "shop1":
            $stmt = $pdo->prepare("SELECT * FROM `shop1` WHERE `name` LIKE :query");
            $stmt->execute(array(":query" => "%". $_GET['query'] . "%"));
            break;
        case "shop2":
            $stmt = $pdo->prepare("SELECT * FROM `shop2` WHERE `name` LIKE :query");
            $stmt->execute(array(":query" => "%". $_GET['query'] . "%"));
            break;
        ...
        ...
        ...
    }

    $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
    if ( count($rows) === 0 ) {
        $_SESSION[$shop] = 'nothing found from '. $shop;
        return array();
    } else {
        return $rows;
    }
    } else {
        return array();
    }
}

if ( ! isset($_GET['query']) ) {
    $_SESSION['success'] = "search for an item";
} else {
    $rowsShop1 = search($pdo, "shop1");
    $rowsShop2 = search($pdo, "shop2");
    ...
    ...
    ...
}
?>

版本2

<?php
function search1($pdo, $shop, $sql) {
    $stmt = $pdo->prepare($sql);
    $stmt->execute(array(":query" => "%". $_GET['query'] . "%"));
    $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
    if ( count($rows) === 0 ) {
        $_SESSION[$shop] = 'nothing found from '. $shop;
        return array();
    } else {
        return $rows;
    }
}

if ( ! isset($_GET['query']) ) {
    $_SESSION['success'] = "search for an item";
} else {
    if ( isset($_GET['shop1']) && ($_GET['query'] !== "") ) {
        $rowsShop1 = search1($pdo, "shop1", "SELECT * FROM `shop1` WHERE `name` LIKE :query");
    }
    if ( isset($_GET['shop2']) && ($_GET['query'] !== "") ) {
        $rowsShop2 = search1($pdo, "shop2", "SELECT * FROM `shop2` WHERE `name` LIKE :query");
    }
    ...
    ...
    ...
}
?>

或者有没有更好的方法来做到这一点?


共2个答案

匿名用户

除了我的评论之外,这里还有一个小提琴,您可以尝试一下我描述的数据库模型:https://www.db-fiddle.com/f/wpuc6p87myukkbywztvk7x/0

这可以让您轻松地通过自己的CRUD管理您的商店和产品,而不必在几个表中工作。

下面是SQL代码,如果小提琴不知何故不再工作了。 (假设MySQL/MariaDB)

create table product
(
    id int auto_increment,
    name varchar(255) not null,
    constraint product_pk
        primary key (id)
);

create table shop
(
    id int auto_increment,
    name varchar(255) not null,
    constraint shop_pk
        primary key (id)
);

create table product_shop
(
  id int auto_increment,
  product_id int,
  shop_id int,
  quantity int not null default 0,
  constraint product_shop_pk
      primary key (id)
);

alter table product_shop
    add constraint product_shop_product_fk
        foreign key (product_id) references product (id);
alter table product_shop
    add constraint product_shop_shop_fk
        foreign key (shop_id) references shop (id);

匿名用户

如果您想保持代码的原样,最好的解决方案是直接使用$shop作为查询中的表var

"SELECT * FROM $shop WHERE `name` LIKE :query"

但这是处理多车间最糟糕的方法。 您的代码将非常难以维护。 如@altherius的评论所说,最好的方法是创建一个shops表并添加与products表的关系