【问题标题】:Database Table Won't Update with Mysqli数据库表不会用 Mysqli 更新
【发布时间】:2012-11-21 21:23:17
【问题描述】:

所以我在 php 中通过 mysqli 更新 mysql 表时遇到问题。

数据库连接和类:

<?php
class testDB extends mysqli {
    private static $instance = null;

    private $user = "tester";
    private $pass = "tester01";
    private $dbName = "testdb";
    private $dbHost = "localhost";

 public static function getInstance() {
   if (!self::$instance instanceof self) {
     self::$instance = new self;
   }
   return self::$instance;
 }

 public function __clone() {
   trigger_error('Clone is not allowed.', E_USER_ERROR);
 }
 public function __wakeup() {
   trigger_error('Deserializing is not allowed.', E_USER_ERROR);
 }

private function __construct() {
    parent::__construct($this->dbHost, $this->user, $this->pass, $this->dbName);
    if (mysqli_connect_error()) {
        exit('Connect Error (' . mysqli_connect_errno() . ') '
                . mysqli_connect_error());
    }
    parent::set_charset('utf-8');
}

public function verify_credentials ($username, $password){
   $username = $this->real_escape_string($username);
   $password = $this->real_escape_string($password);
   $result = $this->query("SELECT 1 FROM users WHERE user_username = '" . $username . "' AND user_password = '" . $password . "'");
   return $result->data_seek(0);
}

public function get_vitae() {
    return $this->query("SELECT * FROM vitae");

public function update_vitae($text, $id) {
    $text = $this->real_escape_string($text);
    $this->query("UPDATE vitae SET vitae_text=".$text." WHERE vitae_id = ".$id);
}
}
?>

这是页面代码:

在标题上方,我们通过确保会话已启动来检查登录;然后导入数据库类,其余部分在将表单重新提交到同一页面时调用:

<?php
session_start();
if (!array_key_exists("username", $_SESSION)) {
    header('Location: index.php');
    exit;
}

require_once("includes/db.php");

$vitae_empty = false;

if ($_SERVER['REQUEST_METHOD'] == "POST") {
    if ($_POST['text'] == "") {
        $vitae_empty = true;
    } else if ($_POST["text"]!="") {
        testDB::getInstance()->update_vitae($_POST["text"], $_POST["id"]);
        header('Location: manage.php' );
        exit;
 } 
}

?>

在正文中(标头和 html 的其余部分通过 'require_once' 导入):

    <section>
        <div class="grid_3 header_line"><h2>Update for CV</h2></div>
        <div class="grid_3">
            <?php
            $result = testDB::getInstance()->get_vitae();
            $vitae = mysqli_fetch_array($result);                
            ?>

            <form name="editvitae" action="editvitae.php" method="POST">

                <textarea name="text" rows="50" cols="100"><?php echo $vitae['vitae_text'];?></textarea><br/>
                <?php if ($vitae_empty) echo "Please enter some text.<br/>";?>

                <input type="hidden" name="id" value="<?php echo $vitae["vitae_id"];?>" /> <br/>
                <input type="submit" name="savevitae" value="Save Changes"/>
            </form>
        </div>
        <div class="grid_3">
            <p><a href="manage.php">&lsaquo; back to management consol</a></p>
        </div>
    </section>

在'body'标签之后:

<?php mysql_free_result($result);?>

如您所见,这会从数据库中提取“简历”文本,然后将其循环到同一页面并进行更改以更新表格。它还会检查“文本”框是否为空。

此代码适用于另一个应用程序;我不明白为什么它在这里不起作用。并且在您开始警告我有关注入和安全性之前,我已经删除了大部分内容,试图找到更新的问题。一旦我弄清楚了,它就会重新进入。

我已经尝试剥离文本检查;不同的变量名;在更新数据库之前将帖子值转储到数组中;将帖子值放入静态变量中;检查我所有的拼写等...

我错过了一些东西,我觉得它会很简单。

【问题讨论】:

  • 在您的 UPDATE 查询中,您没有引用 $text;如果您要添加文本,这将导致问题。但是如果您使用的是 mysqli,则应该考虑使用绑定参数,因为它使您的代码更加安全。
  • @andrewsi 是的,这是很好的做法。 mysqli::prepare()mysqli::bind_params() 是个好主意。
  • 当然很简单。谢谢安德鲁斯;你的评论有帮助;它在我的逃跑中。

标签: php mysql


【解决方案1】:

任何时候通过 mysqli 运行 UPDATE,您都需要运行 $mysqli-&gt;commit(); 方法。

您的新update_vitae 将是:

public function update_vitae($text, $id) {
    $text = $this->real_escape_string($text);
    $this->query("UPDATE vitae SET vitae_text=".$text." WHERE vitae_id = ".$id);
    $this->commit;
}

mysqli 还有一个自动提交功能,可以打开或关闭:

$this->autocommit(true); //on
$this->autocommit(false); //off

【讨论】:

  • 只有在您不使用自动提交时才如此。
  • 他不是,通过查看他的代码。不过,我会添加一个注释,谢谢。
  • 没有骰子,我在更新函数的末尾添加了$this-&gt;commit;,什么也没有。
  • 我认为,默认情况下,自动提交设置为开启,您需要明确将其关闭。
  • @user1843278 - 试试SET vitae_test='" . $text . "' WHERE ...。但一定要考虑使用绑定参数。
【解决方案2】:

所以答案确实很简单。正如安德鲁西建议的那样,这是我对更新字符串的转义。这是修复它的更新:

public function update_vitae($text, $id) {
    $text = $this->real_escape_string($text);
    $this->query("UPDATE vitae SET vitae_text = '$text' WHERE vitae_id = ".$id);
}

感谢您的帮助!

我已经设计网站将近 10 年了,但我现在才开始使用“真正的”php 编码,而不是使用准备好的类和 Dreamweaver 的内置函数。有很多东西要学,但在我有限的业余时间里很有趣。

【讨论】:

  • 哦;我将研究绑定参数;任何能够简化和保护我的代码的事情都是一件好事。
【解决方案3】:
$result = $this->query("SELECT 1 FROM users WHERE user_username = '" . $username . "' AND user_password = '" . $password . "'");

谨慎使用逻辑 AND 进行用户身份验证。在使用任何类型的密码之前先完全验证用户名可能更明智。我这样说是关于人们插入的许多例子——; WHERE 1=1 —— 和 like 的东西(但不是特别是这个语句)。当然,这可能需要两次查询,但至少您只需处理一条信息即可确定访问者是否有效。另一个优点可能是节省处理,因为您不必在应用程序或数据库中处理/加密用户密码(直到用户名得到验证)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-04
    • 1970-01-01
    • 2016-10-12
    • 2015-01-31
    相关资源
    最近更新 更多