2016-08-13 15 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で行うことができる何か類似ですか?

この撮影小さなステップをさらに私はまた、次のような方法を含むことができるようにしたい:私は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; 
} 

get_class()関数のようなものです。

+2

'abstract'クラスを使用します。これは通常のクラスで、 'new'キーワードでインスタンス化することはできません。また、標準クラスを使用してそれらから拡張することもできます。あなたが達成したいことに依存します。 'Interfaces'は、何が存在する必要があるのか​​を定義する一種の' meta'情報ですが、実装されたメソッドはありません。 –

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

ここhas_attribute()selfなどget_called_class()方法に代わるstaticキーワードを使用すると、表の機能を抽象化することができます。

形質も私が達成しようとしていたすべてを行うことができました。 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); 
    } 
} 
関連する問題