我正在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(不要重复自己),这似乎很好。我只需要一遍又一遍地编写4行代码而不是20行代码。但我是新手,不知道这可能是出于其他原因的可怕错误。
将继承覆盖在方法之外并将其放入辅助属性中是否安全且良好的做法?
答案 0 :(得分:0)
$allowed = array('name');
$query_format = SHOW TABLES LIKE '%s'";
似乎属于class属性,因为您需要在子类中访问它,以覆盖行为。
在您的子类中,您可以覆盖行为,也可以使用父关键字
来使用相同的行为$allowed = parent::$allowed;
现在$ allowed将具有从父级继承的值。
同样适用于该方法。如果要调用父方法,请使用父关键字。
父:: getBy();在你的孩子班。永远记住DRY(不要重复自己)的原则。在您的情况下,您正在重复父类和子类中的代码。所以改为使用parent来调用子类中的父方法。例如,在您的子课程
public function getBy()
{
parent::getBy();
}
现在,子getBy()将从父级继承。你唯一应该覆盖的是class属性。