简体   繁体   English

如何使用PHP更新mysql中的一行数据?

[英]How do I update a row of data in mysql using PHP?

I'm attempting to create a form where the user can update their profile details but it just doesn't seem to work. 我正在尝试创建一个用户可以更新其个人资料详细信息的表单,但它似乎无法正常工作。

I'm quite the beginner in server side programming so I'm piecing together code from different tutorials viz. 我是服务器端编程的初学者,所以我正在拼凑不同教程的代码。 from http://www.codingcage.com/2015/04/php-login-and-registration-script-with.html 来自http://www.codingcage.com/2015/04/php-login-and-registration-script-with.html

The class.user.php file, which originally only had the code for login, and signup. class.user.php文件,最初只有登录和注册的代码。 I copied the signup function and changed some stuff to update instead: 我复制了注册函数并更改了一些内容而不是更新:

public function update($id,$uname,$umob,$uaddr,$uacc,$upass) {
    try {
        $upass = password_hash($upass, PASSWORD_DEFAULT);

        $stmt = $this->conn->prepare(
            "UPDATE users
                SET
                    id       = :id, 
                    name     = :uname, 
                    mobile   = :umob,
                    address  = :uaddr,
                    accNo    = :uacc, 
                    password = :upass
              WHERE id = :id"
        );

        $stmt->bindParam(":id", $id);
        $stmt->bindParam(":upass", $upass);
        $stmt->bindParam(":uacc", $uacc);                                         
        $stmt->bindParam(":uname", $uname);
        $stmt->bindParam(":uaddr", $uaddr); 
        $stmt->bindParam(":umob", $umob);

        $stmt->execute();   

        return $stmt;   
    }
    catch(PDOException $e) {
        echo $e->getMessage();
    }               
}

and in view_account.php : (edit 3, whole file including code corrections by @e_i_pi): 并在view_account.php中 :(编辑3,整个文件包括@e_i_pi的代码更正):

<?php
ini_set("error_log", "/path/to/error.log");
    require_once("session.php");

    require_once("class.user.php");

    $auth_user = new USER();

    $stmt = $auth_user->runQuery("SELECT * FROM users WHERE consumer-no=:cno");

    $userRow = $stmt->fetch(PDO::FETCH_ASSOC);

    if(!$session->is_loggedin()){
        // session no set redirects to login page
        $session->redirect('index.php');
    }

    if(isset($_POST['submit']) && $_POST['submit'] === 'save') {
        $uname = strip_tags($_POST['full-name']);
        $umob = strip_tags($_POST['mobile']);
        $uaddr = strip_tags($_POST['addr']);
        $uacc = strip_tags($_POST['bank-acc']);
        $id = strip_tags($_POST['id']);
        $upass = strip_tags($_POST['password']);


        if($uname=="") {
            $signuperror[] = "Please Enter Your Full Name!";    
        }
        else if($umob=="")  {
            $signuperror[] = "Please Enter Your Mobile No.!";   
        }
        else if($uaddr=="") {
            $signuperror[] = 'Please Enter Your Address!';
        }
        else if($upass=="") {
            $signuperror[] = "Please Enter a Password!";
        }
        else if(strlen($upass) < 6) {
            $signuperror[] = "Password must be atleast 6 characters";   
        }
        else {
            try {
// I commented out these for some weird reason I can't even rememebr
//                $stmt = $auth_user->runQuery("SELECT id FROM users WHERE id=:id");
//                $stmt->execute(array(':id'=>$id));
//                $row = $stmt->fetch(PDO::FETCH_ASSOC);
                $auth_user->update($id,$uname,$umob,$uaddr,$uacc,$upass);
            }
            catch(PDOException $e) {
                echo $e->getMessage();
            }
        }   
    }

?>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Gas Booking</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <header>
        <h1>gas booking</h1>
        <nav>
            <ul>
                <li><a href="index.php">home</a></li>
                <li><a href="booking.php">booking</a></li>
                <li><a href="payment.php">payment</a></li>
                <li><a href="ticket.php">ticket</a></li>
                <li><a href="view_account.php">view account</a></li>
                <li><a href="user-bank.php">bank</a></li>
                <li><a href="logout.php?logout=true">logout</a></li>
            </ul>
        </nav>
    </header>
    <div class="content">
        <h2>Edit Your Profile Details</h2>

        <form method="post" action="view_account.php">
            <input type="hidden" id="id" name="id" value="<?php echo $_SESSION['id']; ?>">
            <label for="full-name" class="input-info">
                <div class="label">full name</div>
                <input type="text" id="full-name" name="full-name" value="<?php echo $_SESSION['name']; ?>">
            </label>
            <label for="mobile" class="input-info">
                <div class="label">mobile number</div>
                <input type="text" id="mobile" name="mobile" value="<?php echo $_SESSION['mob']; ?>">
            </label>
            <label for="addr" class="input-info">
                <div class="label">address</div>
                <input id="addr" name="addr" value="<?php echo $_SESSION['addr']; ?>">
            </label>
            <label for="bank-acc" class="input-info">
                <div class="label">bank account number</div>
                <input type="text" id="bank-acc" name="bank-acc" value="<?php echo $_SESSION['accNo']; ?>">
            </label>
            <hr>
            <label for="password" class="input-info">
                <div class="label">password</div>
                <input type="password" id="password" name="password">
            </label>
            <button type="submit" name="submit" value="save">
                Save Changes
            </button>
        </form>     
    </div>
</body>
</html>

and my table is as follows: 我的表格如下:

--
-- Table structure for table `users`
--

CREATE TABLE IF NOT EXISTS `users` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `consumerNo` varchar(15) NOT NULL,
  `password` varchar(255) NOT NULL,
  `accNo` varchar(255) NOT NULL,
  `name` varchar(255) NOT NULL,
  `address` varchar(255) NOT NULL,
  `mobile` bigint(10) NOT NULL,
  `balance` bigint(10) NOT NULL,
  `joining_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

I'm sure I've done something stupid. 我敢肯定我做了些蠢事。 I'd really appreciate pointing me in the right direction, I sat with it till 5:00am and am feeling frustrated with myself. 我真的很感激我指向正确的方向,我一直坐到凌晨5点,我对自己感到沮丧。

The connection with the db is working, classes are properly included. 与db的连接正常,类正确包含在内。 Let me know if you need more information. 如果您需要更多信息,请与我们联系。 Thank you! 谢谢!

The project can be downloaded here: https://www.dropbox.com/s/9v69m18l82n1t46/gas.zip?dl=0 . 该项目可以在这里下载: https//www.dropbox.com/s/9v69m18l82n1t46/gas.zip?dl=0 Warning the code's kind of a mess. 警告代码有点混乱。

Update 更新

You seem to be doing the following in view-account.php : 您似乎在view-account.php执行以下操作:

try {
    $auth_user->update($id,$uname,$umob,$uaddr,$uacc,$upass);
} catch(PDOException $e) {
    echo $e->getMessage();
}

Yet you're already try/catch 'ing within your update() method. 但是你已经在update()方法中try/catch I assume it never gets to this as an error in your if/elseif/elseif/else/etc checks is picked up. 我认为它永远不会成为你的if/elseif/elseif/else/etc检查中的错误。 Could you modify it to look like this for testing purposes: 你可以修改它看起来像测试目的:

$errors = [];
if ($uname == "") {
    $errors[] = "Please Enter Your Full Name!";
}
if ($umob == "") {
    $errors[] = "Please Enter Your Mobile No.!";
}
if ($uaddr == "") {
    $errors[] = 'Please Enter Your Address!';
}
if ($upass == "") {
    $errors[] = "Please Enter a Password!";
}
if (strlen($upass) < 6) {
    $errors[] = "Password must be atleast 6 characters";
}
// check errors
if (!empty($errors)) {
    print_r($errors);
    return false;
}
// otherwise try the query:
$obj = $auth_user->update($id, $uname, $umob, $uaddr, $uacc, $upass);

and let us know what comes up! 让我们知道会发生什么!


I assume you'd have an error thrown, something along the lines of; 我假设你有一个错误抛出的东西;

SQLSTATE[HY093]: Invalid parameter number SQLSTATE [HY093]:参数号无效

This is because you're trying to bind on :id twice. 这是因为你试图绑定:id两次。 You have to remember that a users ID is unique and should never change ( right? ). 您必须记住,用户ID是唯一的,不应该更改( 对吗? )。

Modify your query to look like this: 修改您的查询,如下所示:

$stmt = $this->conn->prepare(
    "UPDATE users
     SET
         name = :uname, 
         mobile = :umob,
         address = :uaddr,
         accNo = :uacc, 
         password = :upass
      WHERE id = :id"
);

Notes 笔记

  • You're best to modify your "password change" functionality to have the user confirm their password ( if(PASSWORD == PASSWORD_REPEAT) { .... SET PASSWORD... ) 您最好修改“密码更改”功能,让用户确认其密码( if(PASSWORD == PASSWORD_REPEAT) { .... SET PASSWORD...
  • Don't pass the user ID inside the form. 不要在表单中传递用户ID It's insecure. 这是不安全的。 Since it's in $_SESSION already, simply access it like that within your view-account.php file! 因为它已经在$_SESSION ,所以只需在view-account.php文件中访问它!
    • Why the above you ask? 为什么上面你问? Simple. 简单。 If I inspect your <form... element, I could easily modify that hidden input to be some other users ID , allowing me to change their passwords/information/etc. 如果我检查你的<form...元素,我可以很容易地将该隐藏输入修改为其他用户ID ,允许我更改其密码/信息等。
    • And since it looks like you're dealing with "Bank" related information, I'd suggest doing this asap! 既然看起来你正在处理“银行”相关信息,我建议尽快这样做! Imagine If I could change "Barack Obama's" bank password and access his account. 想象一下,如果我可以更改“Barack Obama”的银行密码并访问他的帐户。
  • Your form also doesn't have any action attribute...so it does nothing.. Best change that to your view-account.php page 您的表单也没有任何action属性...所以它什么也没做。最好将其更改为您的view-account.php页面
  • I suggest removing your use of strip_tags() . 我建议删除你对strip_tags() It could ruin some fields ( ie passwords ). 它可能会毁掉一些字段( 即密码 )。 You're also already binding/preparing your statements ( Props to you on that, good work! ) 你也已经绑定/准备你的陈述( 道具就是你,干得好!
  • While we're at it, you might want to look at your view-account.php file, It could be modified to stop the use of all those if / elseif / elseif / else statements. 虽然我们正在使用它,但您可能需要查看您的view-account.php文件,可以对其进行修改以停止使用所有if / elseif / elseif / else语句。 You're essentially checking all your fields and if it fails, you're adding an error message to an array, but if it passes you're running the query, this is bad practice. 你实际上是在检查你的所有字段,如果它失败了,你就会向一个数组添加一条错误信息,但是如果它通过你正在运行查询,这是不好的做法。 You should look at doing something similar to ( pseudo code ): 你应该看一下类似于( 伪代码 )的东西:

$errors = [];
if (!check_fields()) {
    $errors[] = THE FIELD ERROR MESSAGE;
}

// now check if your errors are empty or not
if(!empty($errors)) {
    // this means we have errors in the form.
    // return the errors array to the front end and handle it appropriately.
    return $errors;
}

// otherwise we can try the query here now!
try {
    // YOUR SQL UPDATE QUERY
} .....`

Righto, you have a few problems with things not matching up etc., which is to be expected if you are starting out. 对你来说,你有一些不匹配等问题,如果你刚开始就会有所期待。

Let's start with the HTML form. 让我们从HTML表单开始。 There are two issues here: 这里有两个问题:

  1. The form has no action property, so it doesn't get submitted anywhere 表单没有action属性,因此不会在任何地方提交
  2. The submit button is given a specific name and no value. 提交按钮具有特定名称,没有值。 (While some will consider this okay, maybe we can try a different approach which is a little more sensible) (虽然有些人会认为这没关系,也许我们可以尝试一种更合理的不同方法)

I would suggest your HTML form be changed to this: 我建议将您的HTML表单更改为:

<form method="post" action="view-account.php">
    <input type="hidden" id="id" name="id" value="<?php echo $_SESSION['id']; ?>">
    <label for="full-name" class="input-info">
        <div class="label">full name</div>
        <input type="text" id="full-name" name="full-name" value="<?php echo $_SESSION['name']; ?>">
    </label>
    <label for="mobile" class="input-info">
        <div class="label">mobile number</div>
        <input type="text" id="mobile" name="mobile" value="<?php echo $_SESSION['mob']; ?>">
    </label>
    <label for="addr" class="input-info">
        <div class="label">address</div>
        <input id="addr" name="addr" value="<?php echo $_SESSION['addr']; ?>">
    </label>
    <label for="bank-acc" class="input-info">
        <div class="label">bank account number</div>
        <input type="text" id="bank-acc" name="bank-acc" value="<?php echo $_SESSION['accNo']; ?>">
    </label>
    <hr>
    <label for="password" class="input-info">
        <div class="label">password</div>
        <input type="password" id="password" name="password">
    </label>
    <button type="submit" name="submit" value="save">
        Save Changes
    </button>
</form>  

Now, once this form is submitted to view-account.php, we want to make sure that the submit button is "save" mode, so we change the first line of view-account.php to this: 现在,一旦将此表单提交到view-account.php,我们要确保提交按钮是“保存”模式,因此我们将view-account.php的第一行更改为:

if(isset($_POST['submit']) && $_POST['submit'] === 'save') {

This approach means we can have different submit buttons on the same form - we may in future want actions for save, delete, archive, etc. 这种方法意味着我们可以在同一表单上使用不同的提交按钮 - 我们将来可能需要保存,删除,存档等操作。

Lastly, I notice that the id field in your database table is declared AUTOINCREMENT . 最后,我注意到数据库表中的id字段被声明为AUTOINCREMENT Great, exactly what you want, database id fields are internal unique identifiers that we let the database determine (in 99% of cases - there are edge cases where we like to define our own UIDs). 很好,正是你想要的,数据库id字段是我们让数据库确定的内部唯一标识符(在99%的情况下 - 有我们喜欢定义我们自己的UID的边缘情况)。 This means that there is a problem with your UPDATE statement. 这意味着您的UPDATE语句存在问题。 You cannot update an auto-incremented field. 您无法更新自动递增的字段。 In your class.user.php file, change the declaration of $stmt to this: 在class.user.php文件中,将$stmt的声明更改为:

$stmt = $this->conn->prepare(
    "UPDATE users
    SET
        name = :uname, 
        mobile = :umob,
        address = :uaddr,
        accNo = :uacc, 
        password = :upass
    WHERE id = :id"
);

This should fix your code issues, I think I got everything. 这应该解决你的代码问题,我想我得到了一切。 BUT , there may be other problems. 但是 ,可能还有其他问题。 If your code still does not work, I would suggest checking your error logs. 如果您的代码仍然无效,我建议您检查错误日志。 If you're not sure where they are, either check your php.ini file to see what the error log location is, or override the default location by putting this at the top of the page you're trying to debug: 如果您不确定它们在哪里,请检查您的php.ini文件以查看错误日志位置,或者通过将其放在您尝试调试的页面顶部来覆盖默认位置:

ini_set("error_log", "/path/to/error.log");

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM