2016-08-13 101 views
1

我试图创建php类,它将处理与我的数据库的所有交互。在这一点上,每个类代表我的数据库中的一个表,我想创建一个接口或类来扩展,其中包含所有表共享的方法。使用默认方法的接口PHP

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来处理接口中的抽象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()函数。

+2

使用'abstract'类。这是一个普通的类,不能用'new'关键字自己'实例化'。您也可以使用标准类并从中扩展。取决于你想完成什么。 “接口”只是一种定义需要存在的“元”信息,但它本身没有任何方法实现。 –

+0

这个解决方案的唯一问题是,我无法从正在扩展抽象类的类静态调用find_by_sql(),因此在'instantiate()'中使用'static'不再有效。 – user2789116

+1

也许[traits](http://php.net/manual/en/language.oop5.traits.php)? – Alex

回答

1

经过一番尝试后,我也发现一个具有晚静态绑定的抽象类与使用特征具有相同的效果。这里是解决我的问题的两种方式:

与抽象类开始:

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以及在has_attribute()get_called_class()方法允许的表功能抽象。

特质还让我做了我想要完成的一切。在php documentation用户贡献注释描述得好:

最好的方式来了解什么特质,以及如何使用它们的是看他们有什么本质上它们是:语言辅助复制和粘贴。如果您可以将代码从一个类复制并粘贴到另一个类中(并且我们都已经完成了这项工作,即使我们尽量不去因为它的代码重复),那么您就有了一个特征候选人。

这是我创建的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); 
    } 
}