【问题标题】:making abstract pdo class制作抽象 pdo 类
【发布时间】:2014-09-25 07:18:40
【问题描述】:

我只是从 mysql_* 切换到 PDO,因为我读到 mysql_* 将来会被删除,现在我不知道将我当前的类抽象为 PDO 的插入、更新和删除操作,也许是某个可以指出如何将其转换为基于 PDO 的吗?

这是我的连接类,用于处理所有连接和其他相关功能(我已经制作了这个 PDO,所以没有问题)

<?php
require_once(folder.ds."constants.php");

class MySQLDatabase {

    private $dbh;
    private $host = DB_SERVER;
    private $dbname = DB_NAME;

    private $stmt;
    public $query_terakhir;
    public $error_text;

    function __construct(){
        $this->open_connection();
    }

    public function open_connection(){
        $dsn = 'mysql:host=' . $this->host . ';dbname=' . $this->dbname;
        $options = array(
            PDO::ATTR_PERSISTENT => true, 
            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
        );

        try{
            $this->dbh = new PDO($dsn,DB_USER,DB_PASS,$options);
        }
        catch(PDOException $e) {
            date_default_timezone_set('Asia/Jakarta');
            $dt = time();
            $waktu = strftime("%Y-%m-%d %H:%M:%S", $dt);
            $log = array_shift(debug_backtrace());
            file_put_contents('PDOErrors.txt',$waktu. ": " .$e->getMessage(). ": " .$log['file']. ": line " .$log['line']. "\n", FILE_APPEND);
        }
    }

    public function query($sql){
        $this->stmt = $this->dbh->prepare($sql);
    }

    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 execute(){
        return $this->stmt->execute();
    }

    public function fetchall(){
        return $this->stmt->fetchAll(PDO::FETCH_ASSOC);
    }

    public function fetch(){
        return $this->stmt->fetch(PDO::FETCH_ASSOC);
    }

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

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

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

    public function endTransaction(){
        return $this->dbh->commit();
    }

    public function cancelTransaction(){
        return $this->dbh->rollBack();
    }

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

$database = new MySQLDatabase();

?>

这是我的课程之一,可以帮助我进行保存(创建或更新)、删除和其他操作,使用这个课程我只需要更改表名的 $nama_tabel、我的表字段的 $db_fields 和公共 $xxxxx与我的表字段匹配并且创建、更新和删除功能可以完美运行...

但是对于 pdo,我只是不知道如何使用与上述相同的方法使其用于创建、更新和删除....

<?php
require_once('database.php');

class staff{
    public static $nama_tabel="staff";
    protected static $db_fields = array('id','name','job');

    public $id;
    public $name;
    public $job;

    private function has_attribute($attribute){
        $object_var = $this->attributes();
        return array_key_exists($attribute,$object_var);
    }

    protected function attributes(){
        $attributes = array();
        foreach(self::$db_fields as $field){
            if(property_exists($this, $field)){
                $attributes[$field] = $this->$field;
            }
        }
        return $attributes;
    }

    protected function sanitized_attributes(){
        global $database;
        $clean_attributes = array();
        foreach($this->attributes() as $key => $value){
            $clean_attributes[$key] = $database->escape_value($value);
        }
        return $clean_attributes;
    }

    public function create(){
        global $database;
        $attributes = $this->sanitized_attributes();

        $sql = "INSERT INTO " .self::$nama_tabel." (" ;
        $sql .= join(", ", array_keys($attributes));
        $sql .=")VALUES('";
        $sql .= join("', '", array_values($attributes));
        $sql .= "')";
        if($database->query($sql)){
            $this->id_kategori = $database->insert_id();
            return true;
        }else{
            return false;
        }
    }

    public function update(){
        global $database;
        $attributes = $this->sanitized_attributes();
        $attribute_pairs = array();
        foreach($attributes as $key => $value){
            $attribute_pairs[] = "{$key}='{$value}'";
        }

        $sql ="UPDATE " .self::$nama_tabel." SET ";
        $sql .= join(", ", $attribute_pairs);
        $sql .=" WHERE id=" . $database->escape_value($this->id);
        $database->query($sql);

        return($database->affected_rows() == 1) ? true : false;
    }

    public function delete(){
        global $database;

        $sql = "DELETE FROM " .self::$nama_tabel;
        $sql .= " WHERE id=". $database->escape_value($this->id);
        $sql .= " LIMIT 1";
        $database->query($sql);

        if(!empty($this->gambar)){
            $target = website .ds. $this->upload_dir .ds. $this->gambar;
            unlink($target);
        }

        return($database->affected_rows() == 1) ? true : false;
    }



}

?>

更新:这是我从 GolezTrol 的更新函数调整后创建函数的方法,但不插入值,而是插入 name=:name 和 content=:content 等等 更新:它已经修复了!这是正确的

public function create(){
    global $database;
    $attributes = $this->attributes();

    $attribute_pairs = array();
    foreach($attributes as $key => $value){
        $attribute_pairs[] = ":{$key}";
    }

    $sql = "INSERT INTO " .self::$nama_tabel." (" ;
    $sql .= join(", ", array_keys($attributes));
    $sql .=")VALUES(";
    $sql .= join(", ", $attribute_pairs);
    $sql .= ")";

    $database->query($sql);

    foreach($attributes as $key => $value){
        $database->bind(":$key", $value);
    }

    if($database->execute()){
        $this->id = $database->lastInsertId();
        return true;
    }else{
        return false;
    }
}

第 2 次更新:我在 while 循环操作中遇到了一些奇怪的事情,我在执行 while 和在 while 内检查此字段 id 是否与我的其他表 id 相同,然后我将显示该 id 名称字段...并显示,但停止我的 while 循环,所以我只得到 1 行 while 循环(它应该显示 40 行)

$database->query($sql_tampil);
$database->execute();
while($row = $database->fetch()){
   $output = "<tr>";
        if(!empty($row['id']))

            $output .="<td><a data-toggle=\"tooltip\" data-placement=\"top\" 
                            title=\"Tekan untuk mengubah informasi kegiatan ini\" 
                            href=\"ubah_cuprimer.php?cu={$row['id']}\"
                            >{$row['id']}</a></td>";
        else
            $output .="<td>-</td>";

        if(!empty($row['name'])){
            $y = "";
            $x = $row['name'];
            if(strlen($x)<=40)
                $y = $x;
            else
                $y=substr($x,0,40) . '...';

            $output .="<td><a data-toggle=\"tooltip\" data-placement=\"top\" 
                            title=\"{$row['name']}\" 
                             href=\"ubah_cuprimer.php?cu={$row['id']}\"
                        > {$y} </td>";
        }else
            $output .="<td>-</td>";

        $wilayah_cuprimer->id = $row['wilayah'];
        $sel_kategori = $wilayah_cuprimer->get_subject_by_id();
        if(!empty($sel_kategori))
           $output .="<td><a href=\"#\" class=\"modal1\"
                            data-toggle=\"tooltip\" data-placement=\"top\" 
                            title=\"Tekan untuk mengubah kategori artikel ini\"  
                            name={$row['id']}>{$sel_kategori['name']}</a></td>";
        else
           $output .="<td><a href=\"#\" class=\"modal1\"
                            data-toggle=\"tooltip\" data-placement=\"top\" 
                            title=\"Tekan untuk mengubah kategori artikel ini\"  
                            name={$row['id']}>Tidak masuk wilayah</a></td>";

        if(!empty($row['content'])){
            $content = html_entity_decode($row['content']);
            $content = strip_tags($content);
            $z = "";
            $v = $content;
            if(strlen($v)<=40)
                $z = $v;
            else
                $z=substr($v,0,40) . '...';

            $output .="<td><a data-toggle=\"tooltip\" data-placement=\"top\" 
                            title=\"{$content}\" 
                             href=\"ubah_cuprimer.php?cu={$row['id']}\"
                        >{$z}</a> </td>";
        }else
            $output .="<td>-</td>";


        if(!empty($row['tanggal']))
            $output .="<td>{$row['tanggal']}</td>";
        else
            $output .="<td>-</td>";

        if(!empty($row['id']))
            $output  .="<td><button class=\"btn btn-default modal2\"
                            name=\"{$row['id']}\" 
                            data-toggle=\"tooltip\" data-placement=\"top\" 
                            title=\"Tekan untuk menghapus layanan ini\" ><span 
                            class=\"glyphicon glyphicon-trash\"></span></button></td>";
        else
            $output .="<td>-</td>";

    $output .="</tr>";

   echo $output;
}

这是我的 $wilayah_cuprimer->get_subject_by_id();功能

public function get_subject_by_id(){
    global $database;
    $sql = "SELECT * ";
    $sql .= "FROM ".self::$nama_tabel;
    $sql .= " WHERE id = :id" ;
    $sql .= " LIMIT 1";

    $database->query($sql);
    $database->bind(":id",$this->id);
    $database->execute();
    $array = $database->fetch();

    return $array; 
}

【问题讨论】:

    标签: php mysql pdo


    【解决方案1】:

    很高兴您过渡到 PDO。最好现在就做,等有一天发现你不能升级 PHP,因为它会破坏你的应用程序。

    据我所知,$database-&gt;query($sql); 只准备了一个声明。这是第一步,但之后您还需要执行它。你已经有了 $database-&gt;execute() 方法,但是你没有在你的插入、更新和删除函数中调用它。

    除了这个问题,如果您也使用绑定参数进行更新会更好,并将转义字符串留给数据库。

    很难完整地测试您的课程,但我希望这能给您一些想法。我添加了 cmets 来描述这些步骤。

    public function update(){
        global $database;
    
        // Don't need 'clean' attributes if you bind them as parameters.
        // Any conversion you want to support is better added in $database->bind,
        // but you don't need, for instance, to escape strings.
        $attributes = $this->attributes();
    
        // Place holders for the parameters. `:ParamName` marks the spot.
        $attribute_pairs = array();
        foreach($attributes as $key => $value){
            $attribute_pairs[] = "{$key}=:{$key}";
        }
    
        $sql ="UPDATE " .self::$nama_tabel." SET " .
              join(", ", $attribute_pairs) .
              " WHERE id = :UPDATE_ID";
        $database->query($sql);
    
        // Bind the ID to update.
        $database->bind(':UPDATE_ID', $this->id);
    
        // Bind other attributes.
        foreach($attributes as $key => $value){
            $database->bind(":$key", $value);
        }
    
        // Execute the statement.
        $database->execute();
    
        // Return affected rows. Note that ->execute also returns false on failure.
        return($database->affected_rows() == 1) ? true : false;
    }
    

    【讨论】:

    • 哇,谢谢您的帮助,它适用于更新方法,但是当我尝试实现创建功能时,它会像名称一样将输入输入到我的字段中,然后它会显示在表“name=:name”中你指出我哪里弄错了? (我更新了我的问题以展示我的插入方法)
    • 插入语法的语法略有不同,您写的是INSERT INTO TABLE(Field1, Field2) VALUES (Value1, Value2)。因此,占位符Field1=:Field1 不起作用。幸运的是,MySQL 知道另一种插入语法,即INSERT INTO Table SET Field1=Value1, Field2=Value2。这与更新语法非常相似,因此如果您使用该语法,您可以使用几乎相同的代码。见MySQL Insert Syntax
    • 哦,好吧,我已经修好了...现在我开始更改 while 循环,但遇到了一些奇怪的事情...我做了一个 while 循环并在 while 循环内检查此行位置字段id 与我的位置表中的 id 相等,然后它将显示位置名称并显示!但在那之后我的while循环停止......所以它只显示1行数据......我将在帖子中添加我的代码
    • 同时这是您的第三个问题。也许你应该为此提出一个新问题,这样它也会得到其他人的新关注。从现在开始,我不再是你的私人导师。如果您因为我只回答了前两个而不接受答案,那就这样吧。我只是回报了这个人情(我认为你的问题不再是“好”了)并且不会为此失眠。
    • 哇,对不起,我不知道为什么你的答案不被接受......但感谢你的帮助,我已经通过在我的 sql 查询中使用 join 找到了解决方案哈哈哈。 .....
    猜你喜欢
    • 2016-01-09
    • 1970-01-01
    • 1970-01-01
    • 2011-03-17
    • 1970-01-01
    • 2011-09-06
    • 1970-01-01
    • 2017-11-27
    • 1970-01-01
    相关资源
    最近更新 更多