我是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();

10-07 19:01
查看更多