PHP 5.3中的抽象静态函数

时间:2012-05-24 14:55:56

标签: php design-patterns

我是PHP的新手,我正在找出实现某些数据库访问代码的最佳方法。我正在尝试创建一些简单的数据库访问对象 - 每个表都有自己的类,类的每个实例代表表中的一行,你知道这个练习。

我的代码似乎有效,但我在网上看到的一些内容让我担心我的方法可能会以某种方式出错。因为“我可以这样做吗?”并且“我应该这样做吗?”是两个不同的问题,我希望一些PHP兽医可以插入。

我当前的策略是创建一个包含所有公共代码的基类抽象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::函数来访问这些abstract static函数。据我所知,它正在发挥作用!

但是,this question接受的答案表明5.3中仍然不允许使用abstract static功能。

所以,我正在试图弄清楚要做什么。答案是错的 - {{1}}函数现在被认为是完全合法的PHP代码吗?我在代码中做了哪些不可取的事情?还有其他方法我应该考虑吗?

2 个答案:

答案 0 :(得分:17)

这是你的例子

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停止支持后期静态绑定(我认为这是PHP特性),您确信它也能正常工作。

编辑:两个答案都表明,抽象类引入接口以及从中扩展的类是未知的。遵循模板模式,即使使用静态函数,这在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();

如果你在这里删除静态关键字,你实际上将获得有用的(和标准的做事方式)代码:

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

答案 1 :(得分:6)

抽象函数永远不会是任何语言的静态函数。

静态函数提供功能,即使没有实例。

抽象函数不提供任何功能。

从逻辑上讲,你不能使用一个抽象的静态函数,它会 - 并且永远不会 - 提供一个函数。


B延伸A

当你在B上下文中调用静态函数时,它将在A上下文中运行(导致静态)。

但是,在A上下文中,这个相同的函数是抽象的,你不允许调用它。