我现在已经把头发拉出这个问题大约整整一天了。我正在开发我的第一个应用程序我实际上相当远(几周前建立了登录页面,工作得很好)。昨晚,我运行了我的应用程序,它运行得很好。我将它备份到我的闪存驱动器,再次测试它,然后关闭我的笔记本电脑过夜。
今天早上我打开了应用程序以开始文档处理 - 这是我的顶点的项目所以我必须每周记录/视频结果 - 突然我的测试人员帐户无法进行身份验证。我尝试通过应用程序注册一个新的,并且它不会将数据发布到数据库。当然,我认为数据库/服务器有问题并联系了我的主机;在一个长达两个小时的过程中,他们验证了数据库是否正常工作,并且它只是在我的代码中,它从前一天晚上完全运行后才被触及。
我已经读过,这有时会通过FireBase(我相信这就是所谓的)和OAuth进行身份验证。我既不使用也不只是做基本的数据库读/写。我没有找到任何关于通过谷歌做什么的有用信息,可能是因为问题对于快速搜索来说太复杂了......或者我只是不知道如何正确地说出来。
<?php
$connection = mysqli_connect("localhost", "SENSORED", "SENSORED", "SENSORED");
$username = $_POST["username"];
$password = $_POST["password"];
$statement = mysqli_prepare($connection, "SELECT * FROM user WHERE username = ? AND password = ?");
mysqli_stmt_bind_param($statement, "ss", $username, $password);
mysqli_stmt_execute($statement);
mysqli_stmt_store_result($statement);
mysqli_stmt_bind_result($statement, $user_id, $name, $username, $email, $company_id, $phone, $password, $leaveTime, $sickTime, $rateOfPay);
$response = array();
$response["success"] = false;
while(mysqli_stmt_fetch($statement)){
$response["success"] = true;
$response["user_id"] = $user_id;
$response["name"] = $name;
$response["username"] = $username;
$response["email"] = $email;
$response["company_id"] = $company_id;
$response["phone"] = $phone;
$response["password"] = $password;
$response["leaveTime"] = $leaveTime;
$response["sickTime"] = $sickTime;
$response["rateOfPay"] = $rateOfPay;
}
echo json_encode($response);
?>
我确实设置了一个连接测试,它验证了PHP确实连接到数据库并查询它。它可以告诉我有多少个表,例如,我在用户表中有多少个用户名。但是,当我输入:
"SELECT * FROM user WHERE username = 'test'"
因为有一个只是'test'的用户名,所以无法找到匹配项。但是,我可以从数据库中看到测试确实是用户名并且确实存在于该表中。
我目前没有通过PHP获得任何结果。但是,如果我通过PHPmyadmin查询,它会显示包含'test'作为用户名的行。显然,我的编码是正确的,但我不确定什么可能会干扰从PHP中选择它,因为它正在建立连接并从数据库中读取。更不用说当它没有保留时,它不想将注册信息写入数据库。
我一直在寻找解决方案,因为创建一个具有不同凭据等的全新数据库并收到相同的问题。谷歌一直没有帮助寻找答案,我也没有在这里找到类似的问题/问题。
任何想法如果工作数据库连接和读/写能力如何在不被一夜之间编辑的情况下完全消失?
答案 0 :(得分:-1)
这就是我要做的。正如我所说,我多年没有使用MySqli所以我不得不做一些谷歌搜索,我不是100%肯定一切都是正确的,因为我无法真正测试它。
但是这里有。
//turn on output buffering - useful for debugging
ob_start();
//I would use the object interface
$mysqli = new mysqli("localhost", "SENSORED", "SENSORED", "SENSORED");
//your not checking the connection success
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
$username = $_POST["username"];
//are you storing passwords in plain text?
$password = password_hash($_POST["password"]);
/*
I would not pick the password from the DB, the DB is case insensitive,
unless you use collation UTF8_bin or such.
Also it's harder to debug, as you don't know if the user exists or the
password matching is wrong.
*/
$stmt = $mysqli->prepare($connection, "SELECT * FROM user WHERE username = ?");
//bind the inputs
$stmt->bind_param("s", $username);
//execute the query
$res = $stmt->execute();
//fetch results as an associative array
$row = $res->fetch_assoc();
//set default
$response["success"] = false;
/*
We expect exactly 1 row be returned. More then 1 should
be impossible if your username is unique (which is should be)
but just in case any issues happen we should check that it's exactly
1 return row, no more no less.
*/
if($res->num_rows() != 1) {
//always be cordial in your error messages to users
$response['message'] = "We're sorry we could not find user {$username}";
return $response;
}
//check the password hash using an approved crypto-logically safe method
if(!hash_equals($password, $$row['password']) {
$response['message'] = "Unfortunately the password you entered is incorrect";
return $response;
}
//remove the password / we no longer need it.
//security is paramount, no need to risk exposing it, even when its hashed
//eg. I just spent the weekend fixing 5 wordpress sites that were hacked
unset($row['password']);
$response['message'] = "Success!";
//put the contents of the buffer into debug. only do this on localhost
//you could switch this using the HOST or server IP
$response['debug'] = ob_get_clean();
//combine the row with the response
//caution if key matched in rows exists in response value in row
//will be replaced with that of response ( it shouldn't be a problem in this case )
$response += $row;
//set the correct content type, this allows browsers to
//know this is json, and prevents having to do JSON.parse() in some cases
header('Content-type:application/json');
//encode the responce
echo json_encode($response);
我在那里放了一些笔记,比如这个
//always be cordial in your error messages to users
曾经有一位年轻的网络开发人员抱怨客户抱怨他的错误消息是“冷”。但是,这位年轻的网络开发人员对他的客户进行了批评,并记住对最终用户来说总是特别好。 (那是2009年左右)。也就是说,它没有改善我的拼写。
我在重构时遇到的一件事是,我注意到你没有加密密码。我不知道这是错误还是设计。
ob_start
和ob_get_clean
允许您在不违反echo
响应的情况下print_r
或JSON
之间的内容。通常,如果您创建输出,那么它将在您的json数据之外
here is some output
{"success" : false}
这会导致客户端出错。使用输出缓冲,上面的内容将如下所示
{"debug" : "here is some output", "success" : false}
我认为它是可选的,但它是执行JSON甚至HTML之外的任何内容类型的正确方式,包括(或特别)文件下载。
希望它有所帮助。即使你不能使用这种形式的代码,它可能有助于看到它以不同的方式编写。有时你可以接近问题并忽略一些简单的错误。以另一种格式看待它并且必须处理它的逻辑,可以揭示你错过的东西。