是否检查行插入/更新/删除偏执编程?

时间:2014-02-02 11:13:41

标签: php mysql

我很高兴知道在插入/更新/删除时是否应该始终检查mysql结果?

当我实现(使用PHP)这些检查时,代码开始建立,并提供替代路由来确定每个结果,当我们假设查询成功时,我们只编码一条正确的路由。

另外如果您认为我有时只应该检查,请解释原因,我会尽可能地尽可能地测试,或者根本不测试。

4 个答案:

答案 0 :(得分:2)

这取决于。就像编程中的一切一样。例如,如果要在两个彼此独立的表中插入几乎相同的值,则不需要:

$db->query("INSERT INTO tbl1 (col1, col2) VALUES (val1, val2);");
if ($db->affected_rows == 1) {
    $db->query("INSERT INTO anotherTable (col1, col2) VALUES (val1, val2);");
}

因为你不需要在table1中插入值才能插入table2。

在这种情况下,您只需执行

即可
$db->query("INSERT INTO tbl1 (col1, col2) VALUES (val1, val2);");
$db->query("INSERT INTO anotherTable (col1, col2) VALUES (val1, val2);");

另一方面,您可能有依赖操作。例如。你有一个系统与用户,有一些信用,他们用来购买东西。首先执行减去债权人,然后检查减法是否结束,然后给出货物:

$db->query("UPDATE users SET credits = credits - '$desiredValue' WHERE user_id = '{$_SESSUIN['user_id']}';");
if ($db->affected_rows == 1) {
    $db->query("INSERT INTO user_goods (stuff_id, credits_spent, user_id) VALUES ('$stuff_id', $desiredValue', '{$_SESSUIN['user_id']}');");
}

在这种情况下,它不仅仅是必要的。用户可能没有足够的积分,所以你可以在它的顶部建立一个SELECT检查他是否拥有它们。此外,某些数据库操作可能会阻止用户花费其信用,因此您不能只是为其提供商品。

还有其他方法,您需要这些。

例如,像“UPDATE table1 SET column1 = 1000 WHERE column2 = 5;”这样的更新语句可能会返回0个受影响的行,因为总是有一个值为1000的column1,其中column2的值为5.那么您不需要将依赖操作加倍。


如果你的查询封装在方法中,而不是使它们空洞(没有任何意义),你可以通过返回受影响的行来使它们成为布尔值。稍后将使用简单的if(true)轻松检查。

public function hasCredits($credits, $user_id) {
    $result = $db->query("SELECT credits FROM users WHERE user_id = '$user_id';");
    return $result['credits'] >= $credits; // boolean
}

public function takeCredits($credits, $user_id) {
    $db->query("UPDATE users SET credits = credits - '$credits' WHERE user_id = '$user_id';");
    return $db->affected_rows > 0; // boolean again
}

public function giveStuff($stuff_id) {
    $stuff = $this->getStuffStatics($stuff_id); // method which contains what stuff has as credits etc.
    if (!$this->hasCredits($stuff['credits'], $_SESSION['user_id']) {
        return false; // exit the method if user does not have credits
    }
    if ($this->takeCredits($stuff['credits'], $_SESSION['user_id']) { // if affected rows in takeCredits() > 0;
        $db->query("INSERT INTO user_goods (stuff_id, credits_spent, user_id) VALUES ('$stuff_id', '$stuff['credits']', '{$_SESSUIN['user_id']}');");
    }
    return $db->affected_rows > 0
}

答案 1 :(得分:1)

检查插入/更新/删除的行是否完全没有偏执编程。这是一个很好的做法。

它被称为防御性编程

它适用于所有形式的编程。不仅是数据库插入或删除。这是一种安全的编程实践,可确保代码完成预期的操作。是的,由于额外的约束检查,代码大小增加,但它也使整个系统更加健壮。

阅读更多关于防御性编程的信息:

http://en.wikipedia.org/wiki/Defensive_programming http://www.princeton.edu/~achaney/tmve/wiki100k/docs/Defensive_programming.html

但是,您应执行此操作,具体取决于项目要求。例如,如果您正在开发一个安全性最高的应用程序(例如银行应用程序),那么您应该采用防御性编程。但是对于不需要这种约束的系统(例如,社交网站的轮询系统),不需要进行如此广泛的检查。

在太多和太少之间有一个很好的区别,你需要根据你正在做的项目自己判断平衡。

答案 2 :(得分:0)

优良作法是检查您获得的每个mysqli结果,因为您可能会得到不需要的行/结果或您不期望的奇怪结果,在您无意识地将其放入应用程序之前总是检查返回的数据。

如果你没有测试mysqli部分的故障,你可以提供一个不是你想要的错误的网站/应用程序;)

答案 3 :(得分:0)

这不是偏执狂,但每次更换东西时手动检查都不是很有效。相反,你真的应该依赖一组良好的书面测试,涵盖你应用程序的每个重要方面。测试不容易学习,但是一旦你了解它,你将拥有很好的设计工具,文档和你的编程技能将会提升到更高的水平。关于数据库的Speakint - 有一些模拟数据库访问的工具,所以在开发时你实际上不执行真正的数据库查询。你正在寻找真正的虚拟数据库。测试的最大好处之一是测试作为编码标准,您可以在将来的任何一点进行中继。如果出现问题,您只需运行测试并轻松找到错误。