php - 与默认方法 PHP 的接口(interface)

标签 php oop

我正在尝试创建 php 类来处理与我的数据库的所有交互。此时每个类都代表我数据库中的一个表,我想创建一个接口(interface)或类来扩展,其中包含所有表共享的方法。

public static function find_by_sql($sql){
  global $database;
  $response = $database->query($sql);
  $object_array = array();
  while($next = $database->fetch_array($response)){
    $object_array[] = self::instantiate($next);
  }
  return !empty($object_array) ? $object_array : false;
}


private static function instantiate($result_array){
  $object = new static;
  foreach($result_array as $attribute=>$value){
    if($object->has_attribute($attribute)){
      $object->$attribute = $value;
    }
  }
  return $object;
}

我的问题是实例化方法需要与其子类的属性进行交互。我习惯于使用 java,我可以在接口(interface)中定义抽象的 getter 和 setter 方法以及完成此操作的默认方法。我可以在 php 中做类似的事情吗?

更进一步,我还希望能够包含以下方法:
public static function find_by_id($id){
  $sql = "SELECT * FROM users WHERE id=\"{$id}\" LIMIT 1";
  $result_array = parent::find_by_sql($sql);
  return !empty($result_array) ? array_shift($result_array) : false;
}

我从已实现的方法或其他可通过 php 获得的函数调用(例如 get_class() 函数)获取表名。

最佳答案

经过一些实验,我还发现具有后期静态绑定(bind)的抽象类与使用特征具有相同的效果。这是解决我的问题的两种方法:

从抽象类开始:

abstract class Table{

  abstract protected static function get_table_name();

  public static function find_all(){
    $table_name = static::get_table_name();
    $result_array = static::find_by_sql("SELECT * FROM {$table_name}");
    return !empty($result_array)? $result_array : false;
  }

  public static function find_by_id($id){
    $table_name = static::get_table_name();
    $sql = "SELECT * FROM {$table_name} WHERE id=\"{$id}\" LIMIT 1";
    $result_array = static::find_by_sql($sql);
    return !empty($result_array) ? array_shift($result_array) : false;
  }

  public static function find_by_number($number){
    $table_name = static::get_table_name();
    $sql = "SELECT * FROM {$table_name} WHERE number=\"{$number}\" LIMIT 1";
    $result_array = static::find_by_sql($sql);
    return !empty($result_array) ? array_shift($result_array) : false;
  }

  public static function find_by_sql($sql){
    global $database;
    $response = $database->query($sql);
    $object_array = array();
    while($next = $database->fetch_array($response)){
      $object_array[] = static::instantiate($next);
    }
    return !empty($object_array) ? $object_array : false;
  }

  private static function instantiate($attempt_array){
    $class_name = get_called_class();
    $object = new $class_name;
    foreach($attempt_array as $attribute=>$value){
      if($object->has_attribute($attribute)){
        $object->$attribute = $value;
      }
    }
    return $object;
  }

  private function has_attribute($attribute) {
    $object_vars = get_object_vars($this);
    return array_key_exists($attribute, $object_vars);
  }
}

这里使用static替换关键字self以及 get_called_class() has_attribute() 中的方法允许抽象表功能。

特质也让我能够完成我想要完成的所有事情。 php documentation中的用户贡献说明很好地描述它们:

The best way to understand what traits are and how to use them is to look at them for what they essentially are: language assisted copy and paste. If you can copy and paste the code from one class to another (and we've all done this, even though we try not to because its code duplication) then you have a candidate for a trait.



这是trait我创建了可以被我的许多类使用的:
trait Table {

  abstract static function get_table_name();

  public static function find_all(){
    $table_name = self::get_table_name();
    $result_array = self::find_by_sql("SELECT * FROM {$table_name}");
    return !empty($result_array)? $result_array : false;
  }

  public static function find_by_id($id){
    $table_name = self::get_table_name();
    $sql = "SELECT * FROM {$table_name} WHERE id=\"{$id}\" LIMIT 1";
    $result_array = self::find_by_sql($sql);
    return !empty($result_array) ? array_shift($result_array) : false;
  }

  public static function find_by_sql($sql){
    global $database;
    $response = $database->query($sql);
    $object_array = array();
    while($next = $database->fetch_array($response)){
      $object_array[] = self::instantiate($next);
    }
    return !empty($object_array) ? $object_array : false;
  }

  private static function instantiate($attempt_array){
    $object = new static;
    foreach($attempt_array as $attribute=>$value){
      if($object->has_attribute($attribute)){
        $object->$attribute = $value;
      }
    }
    return $object;
  }

  private function has_attribute($attribute) {
      $object_vars = get_object_vars($this);
      return array_key_exists($attribute, $object_vars);
    }
}

关于php - 与默认方法 PHP 的接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38932756/

相关文章:

c++ - Qt:信号和槽 vs C++:消息传递

c# - 当需要设计模块化架构时,对象转换是现实的必然吗?

oop - 接口(interface)实现(接口(interface)隔离原则)

php - 如何在 $_SESSION 中序列化/保存 DOMElement?

php - 我该如何修复这个 MySQL 错误?

php - 如何输出 MySQL 表的所有行并包含一个用于计算重复项的列?

php - 如何修复 fatal error : Class 'Google_Service_Drive_ParentReference' not found?

c# - 如何验证工厂方法?

java - 如何在 Java 中给定键字符串创建特定类的对象?

php - 为什么多次上传没有插入数据库