2016-08-13 114 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); 
    } 
} 
相關問題