2012-05-09 7 views
1

私はPHP for MySQLでデータベースインタラクション層を作成しています。しかし、これは一般的なOOPの質問だと思います(最後の行を参照)。多くのパラメータを持つ関数の継承を処理する方法は?

私は基本的なdbTablesクラスを持っています。 そして、それは

public static function getBy($method='name', $value) { 
     // Gets flat table array of db Tables matching by $method == $value 
     // later could implement some lookup tables. 
     $allowed = array('name'); 
     $query_format = SHOW TABLES LIKE '%s'"; 
     if(in_array($method,$allowed)) { 
      dbConnection::connect(MAIN_DB); // makes db connection 
      $safe_value = mysql_real_escape_string($value); 
      // MAY want to change this query to a SCHEMA query in CHILD classes 
      $sql = sprintf($query_format,$safe_value); 
      // e.g. $sql = "SHOW TABLES LIKE '$safe_value'"; 
      $result = mysql_query($sql); 
      if($result === false) { 
       debug::add('errors', __FILE__, __LINE__, __METHOD__,"Query Error for query '$sql'. MySQL said: " . mysql_error()); 
      } 
      while($row = mysql_fetch_row($result)) { 
       $db_table = new static($row[0]); // creates instance of $this class 
       $object_array[] = $db_table; // add to $object_array for return value 
      } 
     } else { 
      debug::add('errors',__FILE__, __LINE__, __METHOD__, ' - Wrong method: ' . $method . '. Currently allowed: ' . print_r($allowed,true)); 
      return false; 
     } 
    return $object_array; 
    // END public static function getBy($method='name', $value) 
    } 

しかし、子クラスの情報を取得するだろう別のクエリを持っています。彼らは検索のために他の許可された$メソッドを持っています。

私の解決策ですが、それが良い練習であるかどうか、後でもっと苦痛につながるかどうかはわかりません。すべての子クラスでこの関数をオーバーライドするのではなく、関数の修飾子として機能するプライベート静的プロパティのセットを作成できます。そのよう

protected static $get_by_methods = array('name'); // array('name','id','frontend_name'…) in CHILDREN 
    protected static $get_by_query_format = "SHOW TABLES LIKE '%s'"; // for sprintf. Changes in children 
    protected static $get_by_handles_arrays = false; // true in CHILDREN 
    protected static $get_by_query_format_array = " SELECT * FROM %s` WHERE `$method` IN ($safe_values)"; // used in CHILDREN ONLY 

    public static function getBy($method, $value) { 
     $allowed = self::$get_by_methods; 
     $query_format = self::$get_by_query_format; 
     $handle_arrays = self::$get_by_handles_arrays; // false here,,, true in children 
     $query_format_array = self::$get_by_query_format_array; // used in children 
     if(is_array($value) && $handle_arrays === true) { 
      return false; // in child class, $handle_arrays can be set to true outside of function 
       // without rewriting function. just change the static property 
     } 
     if(in_array($method,$allowed)) { 
      dbConnection::connect(MAIN_DB); 
      if(!is_array($value)) { // handle string values 
       $safe_value = mysql_real_escape_string($value); 
       $sql = sprintf($query_format,$safe_value); 
      } else { 
       // arrays used only in children 
e.g. 
$safe_values = mysql_real_escape_string(implode(',',$value)); // convert to string 
       $sql = sprintf($query_format_array,$safe_values); // used in children 
      } 
      $result = mysql_query($sql); 
      if($result === false) { 
       debug::add('errors', __FILE__, __LINE__, __METHOD__,"MySQL Error num " . mysql_errno() . " for query [$sql] - MySQL said: " . mysql_error()); 
      } 
      while($row = mysql_fetch_row($result)) { 
       $db_table = new dbTables($row['name']); 
       $object_array[] = $db_table;   
      } 
     } else { // if bad method chosen above 
      debug::add('errors',__FILE__, __LINE__, __METHOD__, ' Wrong method: ' . $method . '. Must use one of these: ' . print_r($allowed,true)); 
      return false; 
     } 
    return $object_array; 
    // END public static function getBy($method='name', $value) 
    } 

をまとめると、これを実行すると、私はgetBy()メソッドをオーバーライドすることはありませんすることができます。私はそれに伴う保護された静的プロパティをオーバーライドするだけです。 DRY(自分自身を繰り返さないでください)では、これは良いようです。私は20 +の代わりに4行のコードを繰り返し書く必要があります。しかし、私はこれで初めてで、これが他の何らかの理由で恐ろしい間違いになるかどうかは分かりません。

継承をメソッドからオーバーライドしてヘルパープロパティに入れるのは安全ですか?

答えて

0
$allowed = array('name'); 
$query_format = SHOW TABLES LIKE '%s'"; 

は、クラスのプロパティに属しているように見えます。これは、子クラスでこれにアクセスしてその動作を上書きする必要があるためです。

とあなたの子供のクラスで、あなたは行動を上書きすることができたり、今許さ$が親から継承された値を持つことになります

$allowed = parent::$allowed; 

のように親のキーワードを使用して、同じを使用することができます。

同じ方法になります。親メソッドを呼び出す場合は、parentキーワードを使用します。

parent :: getBy();あなたの子供のクラスで。 DRY(自分自身を繰り返さない)の原則を常に覚えています。あなたのケースでは、あなたの親クラスと子クラスのコードを繰り返しています。代わりに、親クラスを使用して子クラスの親メソッドを呼び出します。たとえば、あなたの子供のクラスで

public function getBy() 
{ 
    parent::getBy(); 
} 

今度は、子getBy()は親から継承されます。あなたが上書きすべき唯一のものはクラスプロパティです。

+0

私は主な質問はまだ立っていると思います。継承をメソッドからオーバーライドしてヘルパープロパティに入れるのは良い方法ですか? – xCander

+0

ここで問題となるのは、子クラスのコードの繰り返しです。たとえば、親クラスの派生クラスが10個ある場合は、コードを維持する大きな騒動になります。ロジックが変更されると、すべてのファイルですべてのコードが変更されるためです。したがって、それを避けて、親クラスのすべての共通の関数とプロパティを確実に入れておくとよいでしょう。メソッドのオーバーライドを介して子クラスの動作をオーバーライドします。 –

+0

"をオーバーライドし、メソッドのオーバーライドを介して子クラスの動作をオーバーライドします。実際は、メソッドgetBy()をオーバーライドする必要があります。しかし、私のバージョン#2では、いくつかのプロパティをオーバーライドするだけでよく、次にchildClass :: getBy()をそのまま使うことができます。 parent :: getBy()を参照する必要はありません。 –

関連する問題