【问题标题】:Method for comparing array keys and creating MySQL Statements比较数组键和创建 MySQL 语句的方法
【发布时间】:2013-07-16 19:39:57
【问题描述】:

在我们正在构建的用户系统中,客户能够销售我们提供的多种产品。这些产品的数量不是太多,但我们可能会(并计划经常添加新产品)。当用户登录到他们的管理门户时,他们可以从提供的所有可用产品列表中启用或禁用他们想要销售的产品。

我们使用复选框和复选框name="products[]" 数组构建了接受“启用”产品值的表单。这部分一切正常。当我们试图为输入的数据构建最佳的 INSERT / UPDATE 方法时,这个问题就出现了。如果稍后(由我们)向客户提供新产品并选择启用该产品,则会插入值。只需选中或取消选中相应的产品复选框,就会发生更新,从而启用或禁用该产品。

INSERTUPDATE if a product is currently disabled 但我无法拿出一个数组来比较正确地将产品更新为“禁用”,如果它当前在数据库中设置为启用。

 foreach($_REQUEST['products'] as $productID) {
    if ( array_key_exists($productID, $_SESSION['productsOffered']) && $_SESSION['productsOffered'][$productID]['status'] == 0) {
        echo 'this product would be turned active.';
        echo "<br>";
    }
    elseif ( array_key_exists($productID, $_SESSION['productsOffered']) && $_SESSION['MYADMIN']['products'][$productID]['status'] == 1) {
        echo 'this product would be turned inactive.';
        echo "<br>";
        <b>THIS IS THE LOGIC WHICH DOES NOT WORK</b>
    }
    elseif ( !array_key_exists($productID, $_SESSION['MYADMIN']['products']) ) {
        echo 'insert';
        echo "<br>";
    }
}

如前所述,此处的 IF 和最终 elseif 工作正常,但中间的英文语句:“如果用户取消选中最初设置为活动的产品,则禁用该特定产品 ID”是不正确的。

感谢您提供的任何建议。

更新 1:初步想法

我相信一种可能可行的方法是构建一个包含所有当前$_SESSION['productsOffered'] 的新数组,并找出哪些当前产品(在更新时)当前设置为活动状态。然后我将能够将新数组与$_REQUEST['products'] 数组进行比较,并确定哪些产品被遗漏(或基本上未选中),然后可以更新适当的产品。

虽然我相信这种方法可能会奏效,但它似乎很草率。 更新 2:这也必须在当前的 foreach 请求之外完成,因为很明显,已停用的产品不会存在于请求中。

更新 3

根据要求,数组中的一些示例数据如下(这是非常简单的数据,接近“真实”):

$_SESSION['productsOffered'] = array(
    [1] => Array
        (
          [ID] => 1,
          [status] => 1,
          [name] => Product 1,
        )

    [2] => Array
        (
          [ID] => 2,
          [status] => 1,
          [name] => Product 2,
        )

);

$_REQUEST['products'] = array('1','2','3','4','5','6','7');

【问题讨论】:

  • 状态值 1(或 0)意味着什么?
  • 1 - 有效,0 - 无效
  • 初始化时你是否也在 $_SESSION['productsOffered'] 数组中存储了非活动产品?
  • 在用户初次登录时——是的,我是。
  • 基于这些信息,我认为我给出的初步答案是有道理的。由于您无法直接针对数据库或会话检查“未选择”产品,因此首先禁用先前启用的产品然后仅启用在此会话中选择的产品是有意义的。

标签: php mysql arrays array-intersect


【解决方案1】:

$_REQUEST['products'] 将仅包含已被用户标记为已检查的产品。所以它不会包含未经检查的产品。这意味着在上面的代码中,控件永远不会转到您正在尝试执行的代码的第二部分。 您可以在此处采用的一种方法是在用户提交表单时首先禁用所有产品。示例 SQL 将是:

$sql = "update product_table set disabled='true' where user_id = 'this_user_id'";

然后你可以遍历你的逻辑来标记用户选择的产品:

foreach($_REQUEST['products'] as $productID) {
    if ( array_key_exists($productID, $_SESSION['productsOffered']) && $_SESSION['productsOffered'][$productID]['status'] == 0) {
        echo 'this product would be turned active.';
        echo "<br>";
    }
    elseif ( !array_key_exists($productID, $_SESSION['MYADMIN']['products']) ) {
        echo 'insert';
        echo "<br>";
    }
}

这有点类似于您在更新 1:初步想法中发布的逻辑。 更多信息,例如什么是 $_SESSION['productsOffered'] 数组和示例 $_REQUEST['products'] 数组会有所帮助。

【讨论】:

  • 这样做需要额外的执行查询,但我没想过简单地禁用每个产品,然后按照您的建议运行逻辑。我正在考虑如果更新运行但之后发生其他事情的影响,导致产品被永久禁用,但似乎是一个可行的选择。
  • 我相信有一些修复方法,提前禁用所有产品不会获得预期的效果。假设所有产品都已启用,而用户只想禁用单个产品,此逻辑将禁用所有产品而无法重新启用它们。
  • 我假设为了启用产品,用户必须使用复选框选择它。如果是这种情况,那么即使用户想要禁用单个产品,该逻辑仍然有效。此应用程序面临的限制是信息通过复选框从一个页面传递到另一个页面的方式。复选框只传递已选中字段的值,不提供未选中字段的任何信息。
  • @Maximum2012 - 理解。刚刚更新了一些类似于“真实”信息的示例数据。
【解决方案2】:

你知道mysql中的REPLACE动词吗?

如果不存在则添加新,如果存在则更新。

【讨论】:

  • 问题不在于如何确定INSERT OR UPDATE,而在于如何根据现有产品当前状态和用户输入的状态正确识别和创建更新语句。
  • 另外 - REPLACE 需要“INSERT”和“DELETE”权限。假设对于这个问题,DB 用户由于多种原因没有删除权限。
猜你喜欢
  • 2013-09-15
  • 1970-01-01
  • 1970-01-01
  • 2013-05-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-03
  • 2012-06-26
  • 1970-01-01
相关资源
最近更新 更多