【问题标题】:PHP: Prepared Statements inside a OOP based projectPHP:基于 OOP 的项目中的准备好的语句
【发布时间】:2017-09-13 11:38:03
【问题描述】:

我对 PHP 中的 Prepared Statements 有点困惑,我一直在 youtube 上观看以下教程:https://www.youtube.com/watch?v=aN5KqxK1slc

在我收到以下关于我当前 Mysqli 源代码的说明后:

您对 SQL 注入非常开放,应该真正使用 Prepared 语句而不是连接您的查询。特别是因为 你根本没有逃避用户输入!

我的问题:

我将如何准备语句,因为我在 register 类 中为语句创建语法,并且只将语句传递给我的 database 类 以使用它执行它execute_query 函数?

我是否只需准备 execute_query 函数中的语句并检查它是格式为 INSERT 还是 SELECT 的语句,然后准备值?

感谢任何形式的建议和反馈。

我当前的代码如下所示:

注册类:

<?php
    class register extends database
    {
        function __construct($username, $password, $email)
        {
            $this->username = $username;
            $this->password = password_hash($password, PASSWORD_DEFAULT);
            $this->email = $email;
            $this->activation_id = $this->generateActivationId();
            $this->sender_email = 'support@url.com';
            $this->activation_link = 'http://url.com/folder/activate.php?id=' . $this->activation_id;
            $this->database = new database();
        }

        function generateActivationId()
        {
            $generator = bin2hex(random_bytes(10));
            return $generator;
        }

        function registerAccount()
        {
            $this->database->connect();
            $user_lookup = $this->database->execute_query("SELECT * FROM users WHERE username = '" . $this->username . "'");

            if (mysqli_num_rows($user_lookup) > 0)
            {
                return false;
            }
            else
            {
                $this->database->execute_query("INSERT INTO users (username, password, email, activation_id) VALUES ('" . $this->username . "', '" . $this->password . "', '" . $this->email . "', '" . $this->activation_id . "')");
                $user_lookup_comfirm = $this->database->execute_query("SELECT * FROM users WHERE username = '" . $this->username . "'");

                if (mysqli_num_rows($user_lookup_comfirm) > 0)
                {
                    $this->sendRegisterEmail();
                    return true;
                }
                else
                {
                    return false;
                }
            }
        } 

        function sendRegisterEmail()
        {
            $subject = 'Registration - Activate your account';
            $message = 'Thank you for registering. Please activate your account by visiting the following site: <a href="' . $this->activation_link . '">Website link</a>';
            $headers = 'From: ' . $this->sender_email . "\r\n" .
                'Reply-To: ' . $this->sender_email . "\r\n" .
                'X-Mailer: PHP/' . phpversion();

            mail($this->email, $subject, $message, $headers);
        }
    }
?>

数据库类:

<?php
    class database
    {
        function __construct()
        {
            $this->dBusername = 'xxx';
            $this->dBpassword = 'xxx';
            $this->dBhost = 'localhost';
            $this->dBdatabase = 'xxx';
            $this->dBcharset = 'utf8';
        }

        function connect()
        {
            $mysqli = new mysqli($this->dBhost, $this->dBusername, $this->dBpassword, $this->dBdatabase);

            if ($mysqli->connect_errno)
            {
                $this->_mysqli = false;
            }
            else
            {
                $mysqli->set_charset($this->charset);
                $this->_mysqli = $mysqli;
            }
        }

        function execute_query($sql)
        {
            if($results = $this->_mysqli->query($sql))
            {
                return $results;
            }
            else
            {
                return false;
            }
        }
    }
?>

【问题讨论】:

  • database什么都不做。摆脱它,直接使用mysqli或PDO实例。
  • 所以我应该创建一个完整的数据库处理程序类来创建一个 mysqli 实例,然后在那里准备语句并从注册类调用这些函数?
  • 您应该直接使用 MySQLi 或 PDO 接口。您不需要包装器,在大多数情况下,它最终会导致比它解决的问题更令人头疼的问题。
  • 所以应该这样做:pastebin.com/uPptjRep 我只会调用其他类的函数对吗?
  • 将每次出现的$this-&gt;database-&gt;... 替换为$this-&gt;mysqli-&gt;...。现在清除吗?

标签: php prepared-statement


【解决方案1】:
<?php

class Config{

    private function Db(){
        $db = null;

        $dsn = UR DSN;
        $user = UR USER;
        $pass = UR PASS;
        try{
            $db = $pdo = new PDO($dsn, $user, $pass, array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,PDO::ATTR_TIMEOUT => "10"));
            return $db;
        } catch(Exception $e){
            var_dump($e);
        }
       return null;
    }

    function execPreparedStatement($sql , Array $param = null){

            try{
            $db = $this->Db();
            if($db != null && ($db instanceof PDO)){

                $db->beginTransaction();
                $stm = $db->prepare($sql);
                for ($i = 0 ; $i < count($param) ; $i++){
                    $stm->bindValue($i + 1,$param[$i]);
                }

                $dat = $stm->execute();
                $db->commit();
                $stm = null;
                $db = null;
                return $dat;
            }
        } catch (PDOException $e) {
            $db->rollBack();
            var_dump("<br><br>Error: ".$e->getMessage().' in '.$e->getFile().' on line '.$e->getLine(), $sql, $param);
        }

    }


    function getPreparedStatement($sql , Array $param = null,$type = null) {

        $db = $this->Db();
        if($db != null && ($db instanceof PDO)) {
                $stm = $db->prepare($sql);

                if(!empty($param)){
                    for ($i = 0 ; $i < count($param) ; $i++){
                        $stm->bindParam($i+1, $param[$i]);
                    }
                }

            try {

                $stm->execute();                
                if($type) {
                    $dat = @$stm->fetchAll(PDO::FETCH_ASSOC);
                } else { 
                    $dat = @$stm->fetchAll();
                }

                $stm = null;
                $db = null;
                return $dat;

            } catch (Exception $e){                 
                var_dump("<br><br>Error capturado: ".$e->getMessage().' in '.$e->getFile().' on line '.$e->getLine(),$sql,$param);
            }
        }
    }
}

这是一个 PDO 类,你可以使用它

<?php
$db = new Config();
// This is for an update
$db->execPreparedStatement('update table set a = ?, b = ? where id = ?)', array(value1, value2, id));
// Select With out filter
$data = $db->getPreparedStatment('select * from table');
// With Filter.
$data = $db->getPreparedStatment('select * from table where id = ?',  array(id));

这只是示例,如果您需要,我可以给您更多反馈。但我认为有了这个你可以自己做

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-16
    • 2015-06-27
    • 1970-01-01
    相关资源
    最近更新 更多