面向对象的PHP登录脚本与mysql数据库

问题描述 投票:-5回答:3

大家好,很抱歉如果我在我的代码中犯了很多错误,但我是PHP中面向对象编程的新手,因为我听说它很容易阅读并组织代码。

我正在尝试使用mysql数据库处理登录脚本的第一个项目。

问题是我已经编写了我的函数,但似乎可以使它工作,我没有得到任何错误用于调试。以下是我的代码。

我有一个包含大多数功能的database.php文件

class Database 
{
    //Database conn properties

    private $host   = 'localhost';
    private $user   = 'root';
    private $pass   = 'password';
    private $dbname = 'rtmdb';

    private $dbh;
    private $error;
    private $stmt;

    public function __construct() 
    {
        //Function for database connection
        //Set DSN

        $dsn = 'mysql:host='. $this->host . ';dbname'. $this->dbname;

        //Set Options include persistent connection

        $options = array(
            PDO::ATTR_PERSISTENT    => true,
            PDO::ATTR_ERRMODE       => PDO::ERRMODE_EXCEPTION
        );

        //Create new PDO Instance

        try
        {
            $this->dbh = new PDO($dsn, $this->user, $this->pass, $options);
        }
        catch(PDOException $e) 
        {
            $this->error = $e->getMessage();
        }
    }

    public function query($query)
    {
        //@param function for executing insert, select, update

        $this->stmt = $this->dbh->prepare($query);

        if(!$this->stmt)
        {
            echo $this->dbh->lastErrorMsg();
        }
        else
        {
            return $this->stmt = $this->dbh->prepare($query);
        }
    }

    public function bind($param, $value, $type = null) 
    {
        if(is_null($type))
        {
            switch(true)
            {
                case is_int($value):
                    $type = PDO::PARAM_INT;
                    break;
                case is_bool($value):
                    $type = PDO::PARAM_BOOL;
                    break;
                case is_null($value):
                    $type = PDO::PARAM_NULL;
                    break;
                    default;
                    $type = PDO::PARAM_STR;
            }
        }
        $this->stmt->bindValue($param, $value, $type);
    }

    public function clean_str($data)
    {
        $data = trim($data);
        $data = stripslashes($data);
        $data = htmlspecialchars($data);
        $data = str_replace("'", "’", $data);
        return $data;
    }

    public function execute()
    {
        return $this->stmt->execute();
    }

    public function lastInsertId() 
    {
        $this->dbh->lastInsertId();
    }

    public function resultset()
    {
        $this->execute();
        return $this->stmt->fetchAll(PDO::FETCH_ASSCO);
    }

    public function registerAdmin($fname, $lname, $oname, $uname, $email, $idnumber, $pass, $profimg, $status)
    {
        $email = $this->clean_str($email);
        $lname = $this->clean_str($lname);
        $email = $this->clean_str($oname);
        $lname = $this->clean_str($uname);
        $email = $this->clean_str($email);
        $lname = $this->clean_str($idnumber);
        $email = $this->clean_str($pass);
        $lname = $this->clean_str($profimg);
        $email = $this->clean_str($status);

        $database->query('INSERT INTO admin (fname, lname, oname, uname, email, idnumber, pass, profimg, status) VALUES(:fname, :lname, :oname, :uname, :email, :idnumber, :pass, :proofimg, :status)');

        $database->bind(':fname', $fname);
        $database->bind(':lname', $lname);
        $database->bind(':oname', $oname);
        $database->bind(':uname', $uname);
        $database->bind(':email', $email);
        $database->bind(':idnumber', $idnumber);
        $database->bind(':pass', $pass);
        $database->bind(':profimg', $profimg);
        $database->bind(':status', $status);

        $database->execute();

        if(!$database->lastInsertId())
        {
            die('Yawa Don Gas: ' . $this->dbh->lastErrorMsg());
        }
        $this->dbh->close();
    }
    public function loginAdmin($uname, $pass)
    {
        $uname = $this->clean_str($uame);
        $pass = $this->clean_str($pass);

        $database->query('SELECT * FROM admin WHERE uname = :uname AND pass = :pass');

        $database->bind(':uname', $uname);
        $database->bind(':pass', $pass);

        $results = $database->execute();
        $count = mysql_num_rows($results);

        if ($count == 1)
        {
            $rows = $database->resultset();

            foreach($rows as $row)
            {
                $id = $row['id'];
                $uname = $row['uname'];
                $pass = $row['pass'];
            }
            if(!isset($uname) or empty($uname))
            {
                echo 'Invalid Usernmae';
            }
            elseif(!isset($pass) or empty($pass))
            {
                echo 'Invalid Password Details';
            }
            else
            {
                echo 'Good';
                $set = $this->crossEncryption(ENCRYPT_KEY, 10).$id;
                setcookie('itravel', $set, time()+COOKIE_EXPIRE, COOKIE_PATH);
            }
            return;
             $this->dbh->close();
        }
    }

    public function crossEncryption($key,$length)
    {
        $characters = $key;
        $randomString = '';
        for ($i = 0; $i < $length; $i++) {
            $randomString .= $characters[rand(0, strlen($characters) - 1)];
        }
        return $randomString;
    }

    public function logout()
    {
        if(isset($_SESSION['uname']))
        {
            unset($_SESSION['uname']['id']);
            session_destroy();
            header('Location: index.php');
        }
    }
}

我有另一个travelapis.php文件

<?php
require_once 'database.php';

class travelapis
{
    public function __construct() 
    {
        $this->dbh = new Database;
    }

    public function login()
    {
        if(isset($_POST['uname']))
        {
            $uname = $_POST['username'];
            $pass = $_POST['password'];

            if(empty($uname) || empty($pass))
            {
                echo 'Please Fill in all Fields';
            }
            else
            {
                $this->dbh->login($uname, $pass);
            }
        }
    }
}

然后还有一个login.php文件来执行该功能

<?php

require_once "travelapis.php";

$api = new travelapis;

$api->login();

这用于表单操作。由于某些原因我真的不明白,这似乎不起作用。任何帮助都会因为我需要用PHP包围OOP

php mysql
3个回答
2
投票

我可以发现的主要问题,没有特别的顺序:

  • 你没有真正的面向对象设计。你有一个单一的Database类可以完成所有事情。它主要是程序代码,其中Database扮演index.php的角色。我希望每个不同概念的类都涉及:数据库连接,数据库结果,管理员......以及一些有助于应用程序流的设计模式(例如模型 - 视图 - 控制器)。当您需要实施时,您会做什么?联系表格?为您的巨型类添加新方法?
  • 您正在积极阻止正确的错误处理:尝试/捕获连接以隐藏异常,die()在无处中间
  • 方法是不可预测的:它们返回内容或打印到stdout(通常是两者)而没有提示。
  • 你有一些硬编码的全局变量在某些方法中突然冒出来(例如login()
  • clean_str()没有理由存在。如果你想保留它,给它一个更好的名字,如randomlyCorruptInputData()
  • 与使用原始PDO相比,该类的数据库功能实际上没有任何优势。它实际上变得更难,因为您需要学习新的API并且某些PDO功能变得不可用。

2
投票

尽管下面我的所有评论,看起来你正在学习OO。继续努力。我不一定会为你找到你的错误,而是推动你前进。在修改了一些代码来处理下面的内容后,错误可能会消失。

在设计OO代码时要考虑的事情:

  • 它不应该是薄层。 (否则,为什么要这么麻烦?)
  • 它应该将实现端与业务端隔离开来。
  • OO包的用户不一定需要了解底层流程。

与最后一项相关:

  • 考虑从travelapis::login内部做travelapis::__construct
  • 调用者不必理解prepare-bind-execute-inserted_id - 看看你是否可以将它们组合成一个调用。
  • 最终,业务端甚至不应该知道存在什么“表”,更不用说存在多少“表”。它应该说这些东西“放入/取出”进出数据库。然后包将处理JOINing表,迭代等;从而将模式隐藏在业务端。
  • 选择脚本应该只返回一个结果数组。也许有两个版本 - 一个数组数组与一个哈希数组(关联数组)。

现在对于一些挑选/错误......

  • 不要准备两次。
  • 不要用条;它们已经消失了(除非你错误地加倍添加)。
  • 除了立即放入HTML之外,不要htmlspecialcharacters。
  • 考虑扩展PDO而不是总是说$this->dbh->
  • 考虑添加一些东西为什么在可以从查询执行返回时(例如)模仿inserted_id。
  • 如果你可以轻松做mysql_num_rows,请不要打扰count($rows)
  • 有很多$lname=$email=的bug
  • clean_str可能完全没用。也许trim很有用; bind做mysql需要的东西;其余的是“错误的”。
  • return;之后有一些代码?
  • empty检查isset

2
投票

首先,所有以前的答案都有真正有效和建设性的评论。

我将假设你是php和OOP的新手。这就是说,这不是你只需要花一夜编码就可以完成的事情。

但是,您仍然需要从头到尾编写登录脚本。然后,您需要评估您的项目并确定您遇到问题的位置或努力完成某项任务。然后你需要想出一种更好的方法,这通常只是更简化和结构化逻辑的结果。

让我们从登录系统的角度来看这个。如何记录某人,你需要做什么。让我们来看看你真正在做什么。

保持简单,你将处理:

  • 用户
  • 密码
  • 验证
  • 格式化
  • 错误

提示 - 这些中的每一个最终都会成为处理这些事情的类。这些课程不仅会处理这些内容,而且会专门处理这些类别,并且只要您需要执行上述任何操作,就会调用它们。

我将向您展示一个非常简单的例子。当您创建登录表单时,您很可能会有两个输入,即用户名和密码。您将要针对一些事情验证这些输入。例如,用户名和密码是空白的,或者足够长。

因此,您将创建一个包含将检查和验证这些条件的函数的验证类。像这样:

 class Validate{

    public function __construct(){

    }

//Just testing to see if it is empty.  You can add any other criteria to this that you want.
public function userName($userName){

  if(isset($userName) && $uerName){

    return TRUE;

  }else{

    return FALSE;

  }

}


//Just testing to see if it is empty.  You can add any other criteria to this that you want.
public function password($password){

  if(isset($password) && $password){

    return TRUE;

  }else{

    return FALSE;

  }

}


}

现在使用它只需调用类Validate并传递您的用户名和密码以检查它们是否有效。

$valid = new Validate();

if(!$valid->userName($_POST['username'])){

  echo 'Sorry, There is something wrong with your username.';

}

if(!$valid->password($_POST['password'])){

  echo 'Sorry, There is something wrong with your password.';

}

这里的课程非常酷。最终,您需要验证许多不同的东西,电子邮件,电话号码,姓名,地址等等。只需在Validate类中添加一个新功能,只要您想验证您,只需调用您的类和您需要的功能,像valid->email()

更好的是,您确切知道代码的位置,当您意识到需要更改某些内容的验证时,您可以在一个函数中对类进行编辑,并且它可以在整个代码库中运行。

就像我之前说过的那样,你将为所有这些类别制作一个单独的课程。我想在经过修补之后你会看到这是多么巨大的优势。

另一件事是不要气馁。它被称为学习..你会犯错误,你将从这些错误中获利。重要的是要保持编码。

希望这对你有所帮助。祝好运!

© www.soinside.com 2019 - 2024. All rights reserved.