我是PHP的新手,并且正在寻找实现某些数据库访问代码的最佳方法。我正在尝试创建一些简单的数据库访问对象-每个表都有自己的类,该类的每个实例都代表表中的一行,您知道该钻了。
我的代码似乎正常工作,但是我在网上看到的一些内容使我担心我的方法可能会出错。而且由于“我可以这样做吗?”和“我应该这样做吗?”有两个不同的问题,我希望一些PHP vert 可以加入。
我当前的策略是创建一个包含所有通用代码的基层抽象Table类,然后让代表单个表的每个类对其进行扩展。
我主要关心的是以下代码:
abstract class Table {
protected abstract static function get_fields();
protected abstract static function get_primary_key();
protected abstract static function get_table_name();
这个想法是,每个实现类都将定义字段名称,主键,表名称等,然后Table类将使用这些函数来填充特定的空格,如下所示:
static function insert($values) {
$field_list = array();
$value_list = array();
foreach (static::get_fields() as $field_name) {
if (isset($values[$field_name])) {
$field_list[] = $field_name;
$value_list[] = self::escape($values[$field_name]);
}
}
$field_string = join(", ", $field_list);
$value_string = "'" . join("', '", $value_list) . "'";
$sql = "insert into " . static::get_table_name() . " ($field_string) values ($value_string)";
如您所见,关键是我正在通过给它们添加
static abstract
来访问这些static::
函数。据我所知,它正在工作!但是,对this question的可接受答案表明5.3中仍然不允许使用
abstract static
函数。因此,我试图弄清楚该怎么做。答案是否正确?
abstract static
函数现在被认为是完全合法的PHP代码吗?我在代码中做了一些不可取的事情吗?我还应该考虑另一种方法吗? 最佳答案
这是你的例子
abstract class Table implements iTable {
public static function insert() {
$class = get_called_class();
$sql = 'INSERT INTO '.$class::get_class_name();
echo $sql;
}
}
interface iTable {
static function get_class_name();
}
class ConcreteTable extends Table
{
public function ConcreteTable() {}
static function get_class_name() {
return 'ConcreteTable';
}
}
$t = new ConcreteTable();
$t::insert();
此示例尊重对象范例,并且即使PHP停止支持后期的静态绑定(bind)(我认为这是PHP的特殊性),您也可以肯定它会起作用
编辑:这两个答案都表明,未知的是,抽象类也为从其扩展的类引入了接口(interface)。按照模板模式,即使在使用静态函数的情况下,PHP也可以做到这一点(尽管有充分的理由为您提供严格的标准警告)。概念证明:
abstract class Table
{
abstract static function get_class_name();
public static function insert() {
printf('INSERT INTO %s', static::get_class_name());
}
}
class ConcreteTable extends Table
{
public static function get_class_name() {
return 'ConcreteTable';
}
}
ConcreteTable::insert();
如果您在此处删除static关键字,则实际上您将获得有用的(和标准的处理方式)代码:
abstract class Table
{
protected $table = NULL;
public function insert() {
printf('INSERT INTO %s', $this->table);
}
}
class ConcreteTable extends Table
{
protected $table = 'ConcreteTable';
}
$table = new ConcreteTable();
...
$table->insert();