2016-05-15 5 views
0

私はWeb開発クラスです。 PDOを使ってMySQLデータベースに接続し、クラス内でPDO接続にアクセスするためのいくつかのメソッドを作成する方法を教えています。私は、高度なPHPプログラマーが、私は知っていると同じくらいには程遠いですPDOプレースホルダを使用するかどうかを指定するMySQLの `prepared statements '

<?php 
require_once "db_model.php"; 

class ArticlesModel extends DB { 
    function getAll() { 
     $statement = $this->executeQuery("SELECT * FROM articles"); 
     return $statement->fetchAll(PDO::FETCH_ASSOC); 
    } 

    function getArticle($id) { 
     $statement = $this->executeQuery("SELECT * FROM articles WHERE id = " . $id); 
     return $statement->fetchAll(PDO::FETCH_ASSOC); 
    } 

    function insertArticle($article) { 
     $this->executeQuery("INSERT into articles (title, body, image) values ('".$article["title"]."', '".$article["body"]."', '".$article["file"]."');"); 
     return $this->db->lastInsertId(); 
    } 

    function updateArticle($article) { 
     $statement = $this->executeQuery("UPDATE articles SET title ='".$article["title"]."',body = '".$article["body"]."' WHERE id =".$article["id"]); 
     return $statement->rowCount();  
    } 

    function deleteArticle($article) { 
     $statement = $this->executeQuery("DELETE FROM articles WHERE id =".$article["id"]); 
     return $statement->rowCount(); 
    } 
} 

db_model.php

<?php 
class DB { 
    protected $db; 
    function __construct() { 
     $this->db = new PDO("mysql:host=localhost;dbname=blog", "root", ""); 
    } 

    function executeQuery($query) { 
     $statement = $this->db->prepare($query);  
     $statement->execute(); 
     return $statement; 
    } 
} 

articles_model.phpは良い練習が本当の準備を使用することであるということですSQLステートメントでPHP変数を連結しただけでなく、プレースホルダを使用したステートメントがあるので、私はこれに来ました:

db_model.php

どの方法10
<?php 

define('DB_NAME', 'blog'); 
define('DB_HOST', 'localhost'); 
define('DB_USER', 'root'); 
define('DB_PASS', ''); 
define('DB_CHAR', 'utf8'); 

class DB { 
     protected $db; 
     function __construct() { 
       $opt = array(
         PDO::ATTR_ERRMODE   => PDO::ERRMODE_EXCEPTION, 
         PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, 
         PDO::ATTR_EMULATE_PREPARES => TRUE 
       ); 
       $dsn = 'mysql:host='.DB_HOST.';dbname='.DB_NAME.';charset='.DB_CHAR; 
       $this->db = new PDO($dsn, DB_USER, DB_PASS, $opt); 
     } 

     function executeQuery($query) { 
       $statement = $this->db->prepare($query); 
       $statement->execute(); 
       return $statement; 
     } 
} 

articles_model.php

<?php 

require_once 'db_model.php'; 

class ArticlesModel extends DB { 
     function getAll() { 
       $statement = $this->executeQuery('SELECT * FROM articles'); 
       return $statement->fetchAll(PDO::FETCH_ASSOC); 
     } 

     function getArticle($id) { 
       $statement = $this->executeQuery('SELECT * FROM articles WHERE id = :id'); 
       $statement->bindParam(':id', $id, PDO::PARAM_INT); 
       return $statement->fetchAll(PDO::FETCH_ASSOC); 
     } 

     function insertArticle($article) { 
       $statement = $this->executeQuery('INSERT into articles (title, body, image) values (:title, :body, :image)'); 
       $statement->bindParam(':title', $article['title'], PDO::PARAM_VAR); 
       $statement->bindParam(':body', $article['body'], PDO::PARAM_VAR); 
       $statement->bindParam(':image', $article['file'], PDO::PARAM_VAR); 
       return $statement->lastInsertId(); 
     } 

     function updateArticle($article) { 
       $statement = $this->executeQuery('UPDATE articles SET title = :title, body = :body WHERE id = :id'); 
       $statement->bindParam(':title', $article['title'], PDO::PARAM_VAR); 
       $statement->bindParam(':body', $article['body'], PDO::PARAM_VAR); 
       $statement->bindParam(':id', $article['id'], PDO::PARAM_INT); 
       return $statement->fetchColumn(); 
     } 

     function deleteArticle($article) { 
       $statement = $this->executeQuery('DELETE FROM articles WHERE id = :id'); 
       $statement->bindParam(':id', $article['id'], PDO::PARAM_INT); 
       return $statement->fetchColumn(); 
     } 
} 

使用する方が正しい/安全なのですか?私が間違っている?私は、より洗練されたコードを使用することができましたが、私のコードを教師のコードにできる限り近づけたいと思っていました。 (例えばないbindparam()を使用してどこでもしかしexecute(array())

EDIT:

<?php 

require_once 'db_model.php'; 

class ArticlesModel extends DB { 
     function getAll() { 
       $statement = $this->executeQuery('SELECT * FROM articles'); 
       return $statement->fetchAll(PDO::FETCH_ASSOC); 
     } 

     function getArticle($id) { 
       $statement = $this->executeQuery('SELECT * FROM articles WHERE id = :id'); 
       $statement->bindParam(':id', $id, PDO::PARAM_INT); 
       return $statement->fetchAll(PDO::FETCH_ASSOC); 
     } 

     function insertArticle($article) { 
       $params = [ 
         ':title' => $article['title'], 
         ':body' => $article['body'], 
         ':image' => $article['file'] 
       ]; 
       $statement = $this->executeQuery('INSERT into articles (title, body, image) values (:title, :body, :image)', $params); 
       return $statement->lastInsertId(); 
     } 

     function updateArticle($article) { 
       $params = [ 
         ':title' => $article['title'], 
         ':body' => $article['body'], 
         ':id' => $article['id'] 
       ]; 
       $statement = $this->executeQuery('UPDATE articles SET title = :title, body = :body WHERE id = :id', $params); 
       return $statement->fetchColumn(); 
     } 

     function deleteArticle($article) { 
       $params = [':id' => $article['id']]; 
       $statement = $this->executeQuery('DELETE FROM articles WHERE id = :id', $params); 
       return $statement->fetchColumn(); 
     } 
} 
+1

'ArticlesModel'クラスのすべてのメソッドでは、最初に' executeQuery() 'メソッドにクエリを送信してから、パラメータをバインドします。これは間違っています。まず、クエリを準備してからすぐに実行してから、パラメータをバインドしてください。正しい順序は、**準備**、**バインド**、*は、**実行**です。 –

+0

あなたが正しいです、私は引数として引数を送信し、それらを正しくバインドする必要があります、私はそれを忘れて、私は多くの私の先生のメソッドを変更したくないでした。 – bsteo

+0

上記のコードは、先生の欠陥のあるメソッドでは機能しません。 –

答えて

0

それが彼らからの真のメリット、プリペアドステートメントを使用することがはるかに安全ですが:

私は適切だと思いますSQLステートメントのユーザー入力に適用されると、SQLインジェクション攻撃からコードが保護されます。 SQLステートメントに直接値を入力する場合、これらの利点は実現されないため、準備されたステートメントは厳密には必要ではありません。しかし、依然としてクエリを再利用できるというメリットがありますが、これは準備済みのステートメントの別の利点です。

は言われて、全体で統一された方法を使用するのは良いプログラミングの練習で常に準備されたステートメントを使用すると、2次SQLインジェクション攻撃を防ぐことができますこと。

関連する問題