2014-09-25 4 views
0

Я просто переключаюсь с mysql_ * на PDO, так как я читал, что mysql_ * будет удален в будущем, и теперь у меня нет идеи абстрагировать мой текущий класс для операции вставки, обновления и удаления в PDO , может быть, кто-то может указать мне, как перевести его на 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, но не подставлять значение вместо этого вставить имя =: имя и содержание =: контента и т. д. Обновлено: его уже исправлено! здесь является правильного

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; 
    } 
} 

второго обновление: я испытываю некоторые странные вещи в то время как операции петли, где я делал в то время как и внутри время я проверить, если это поле идентификатор равно с моим другим идентификатором таблицы, то я покажу что поле имени идентификатора ... и показать, но останавливая мое время цикла, так что я только получить 1 строку в то время как цикл (он должен показывать 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; 
} 

ответ

1

Хорошо, что вы делаете переход к PDO. Лучше сделать это сейчас, а затем узнать, что вы не можете обновить PHP, потому что это нарушит ваше приложение.

Насколько я могу судить, $database->query($sql); только готовит заявление. Это первый шаг, но после этого вам также нужно выполнить его. У вас уже есть метод $database->execute(), но вы не вызываете его в своих функциях вставки, обновления и удаления.

Помимо этой проблемы, было бы даже лучше, если бы вы также использовали параметры привязки для обновлений, и оставьте escape-строки в базе данных.

Трудно проверить свой класс в целом, но я надеюсь, что это даст вам некоторые идеи. Я добавил комментарии для описания шагов.

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; 
} 
+0

вау спасибо за вашу помощь, она хорошо работает для метода обновления, но когда я пытался реализовать для создания функции она Gve вклад в мое поле, как имя, то это показывает в таблице «имя =: имя» вы можете указать мне, где я ошибался? (я обновил свой вопрос, чтобы показать мой подход для вставки) – PUCUK

+0

Синтаксис вставки имел несколько иной синтаксис, и вы пишете 'INSERT INTO TABLE (Field1, Field2) VALUES (Value1, Value2)'. Из-за этого, placeholder 'Field1 =: Field1' не работает. К счастью, MySQL знает альтернативный синтаксис Insert, который является «INSERT INTO Table SET Field1 = Value1, Field2 = Value2'. Это очень похоже на синтаксис обновления, поэтому, если вы используете его, вы можете использовать почти тот же код. См. [Синтаксис вставки MySQL] (http://dev.mysql.com/doc/refman/5.6/en/insert.html) – GolezTrol

+0

oh okay Я уже исправил это ... и теперь я перехожу к изменению цикла while, но испытываю какую-то странную вещь ... Я делаю цикл while и внутри цикла while Я проверяю, равен ли этот идентификатор поля этой строки id в моей таблице местоположения, тогда он покажет название местоположения и покажет! но после этого мой цикл while останавливается ... поэтому он показывает только данные по 1 строке ... я добавлю свой код в сообщение – PUCUK