Php PDO登录脚本始终重新定向到标题页
如上所述,我的代码有两个Php PDO登录脚本始终重新定向到标题页,php,pdo,Php,Pdo,如上所述,我的代码有两个header()方法,其中一个重新定向到登录页面,而另一个重新定向到错误页面 我相信就我所知,我的脚本应该根据我的输入重新指向登录页面,这是正确的,但它的行为方式出乎意料它会重新指向错误页面,而不是登录页面。请看一看,告诉我它不起作用的原因?谢谢此外,如果您看到我的代码中有任何缺陷,请随意提出一些批评,因为我希望改进我的自我。非常感谢 我将发布一些比上面的帖子更有用的东西。这里有几个最佳实践可供使用,以使您在编码时的生活更轻松;当然,在你把头缠在他们身上之后 首先也是最重
header()
方法,其中一个重新定向到登录页面,而另一个重新定向到错误页面我相信就我所知,我的脚本应该根据我的输入重新指向登录页面,这是正确的,但它的行为方式出乎意料
它会重新指向错误页面,而不是登录页面。请看一看,告诉我它不起作用的原因?谢谢此外,如果您看到我的代码中有任何缺陷,请随意提出一些批评,因为我希望改进我的自我。非常感谢 我将发布一些比上面的帖子更有用的东西。这里有几个最佳实践可供使用,以使您在编码时的生活更轻松;当然,在你把头缠在他们身上之后 首先也是最重要的一点,这看起来像是您尝试应用程序的身份验证部分。如果用户输入了正确的用户名和密码,则您希望显示正确的页面。我不知道您的应用程序的范围,所以我不会建议进行大规模更改 自动加载 看起来您正在手动包含文件。PHP有这样的功能,如果您遵循(并且您真的应该看一看),这意味着您可以将目录结构映射到类heirachy 1:1,并在请求时自动为您解析类。因此,当你说
newobject
,甚至(在你的例子中)extends-Config
,如果你的Config
类在你继承人的顶层,它将被自动找到并使用。这将涉及到你学习
一旦您了解了名称空间是如何工作的,以及自动加载可以为您节省多少时间(我的意思是从长远来看,这是非常重要的),您就可以使用依赖关系管理工具,如。Composer基本上是您运行的一个脚本,它为您生成自动加载器,然后在应用程序开始时,您需要做的就是require\u once\u DIR\u。“/vendor/autoload.php”
。但是说真的,看看其中的一些——一旦你使用了它们,你就再也不会回去了,基本上你将来编写的每一个应用程序都会使用它们
您也不需要多次键入include
——顺便说一句,如果未找到要包含的文件,则只会抛出警告。看起来这个文件需要配置文件,所以在这种情况下,您应该使用require\u once
,这意味着如果找不到这个文件(这似乎是您想要的),您的代码将致命
哎呀
那么类用户扩展配置有什么问题呢。至少在具有良好的命名约定(类名的大写)方面做得很好。基本上,extends
意味着一种is-a关系。您不仅仅是为了获得额外的功能而进行扩展,这是一种代码味道。这里您是说用户
是配置
。事实并非如此,如果您将来将此代码交给任何其他开发人员,他们会像“WAIT,WTF”。希望能以更好的方式
您的目标是:在类中包含配置变量。因此,将它们传递到课堂中。我不知道你的Config
类中有什么,但是你应该看看;这是一个例子。基本上,您可以通过DI(通过构造函数)传入Config
对象,然后将代码解耦,这样您就可以单独测试每个对象的优劣,而不是模拟其他对象。可测试代码。依赖注入。谷歌
因此,不要扩展Config
。请输入您的配置:
<?php
include "config.php";
class Users extends Config {
public function login($username, $password) {
try {
$this->db->beginTransaction();
$stmt = $this->db->prepare("SELECT `username`, `password` FROM `users` WHERE `username` = ? AND `password` = ? LIMIT 1");
$stmt->execute(array($username, $password));
if($stmt->rowCount == 1) {
while($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
header("Location: index.php?p=loggedin");
exit();
}
} else {
header("Location: index.php?p=false");
exit();
}
$this->db->commit();
} catch(PDOException $ex) {
$this->db->rollBack();
echo $ex->getMessage();
}
}
}
$users = new Users();
?>
另外,还可以查看帮助您编写其他开发人员可以轻松理解和解析的注释代码
交易
您还使用了事务,您实际上不需要将其用于SELECT
。为什么不呢?因为事务允许您执行提交
或回滚
——但当您执行选择时,您不会更改任何数据。因此,执行事务没有意义。因此,删除这些,然后通过选择尝试检索数据
您的标题代码
每个类、每个对象都应该有一个更改的原因。它做的一项任务就是这样。如果您有一些从数据库读取、比较某些字符串并保存到文件的代码,那么您至少应该有3个类:一个从持久性读取、一个执行比较和一个保存到文件。这就是所谓的谷歌,你可以阅读和谷歌
考虑到这一点,这个单独的类不应该负责发送头。返回true
或false
并让使用此选项的类执行此操作。这不是这个类的责任-它应该只处理身份验证
如果你选择了一个框架,你可以在你的控制器
或视图
中这样做,这取决于你对模式的坚持程度——这在严格意义上对于web应用程序来说实际上是不可能的(我把它放在那里是为了那些喜欢分析的人)但实际上,您应该分离您的关注点,并至少在整个代码库中遵守SRP
安全
我绝不是一个安全专家,但你不需要将用户名和密码都传递到数据库。如果您正在散列您的密码(您应该是),您只需通过用户名从数据库中检索用户
,然后计算密码是否与PHP代码中的散列匹配。这样,您就不会将密码发送到数据库,这有助于(尽管只是一点点)防止出现错误。PHP5.5包含一些非常有用的函数,可以在这方面为您提供帮助
class Users
{
/**
* @var Config
*/
protected $config;
/**
* @constructor
*
* @param Config $config The class configuration, duh
*/
public function __construct(Config $config)
{
$this->config = $config;
}
/** Snip **/
}