Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/neo4j/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP5.3中的抽象静态函数_Php_Design Patterns - Fatal编程技术网

PHP5.3中的抽象静态函数

PHP5.3中的抽象静态函数,php,design-patterns,Php,Design Patterns,我是PHP的新手,我正在寻找实现一些数据库访问代码的最佳方法。我试图创建一些简单的数据库访问对象——每个表都有自己的类,类的每个实例代表表中的一行,您知道这个钻取 我有一些代码似乎在工作,但我在网上看到的一些东西让我担心我的方法可能是错误的。既然“我能做到这一点吗?”和“我应该做到这一点吗?”是两个不同的问题,我希望一些PHP老手能插话 我当前的策略是创建一个包含所有公共代码的基本抽象表类,然后让每个表示单个表的类对其进行扩展 我主要关注的是以下代码: abstract class Table

我是PHP的新手,我正在寻找实现一些数据库访问代码的最佳方法。我试图创建一些简单的数据库访问对象——每个表都有自己的类,类的每个实例代表表中的一行,您知道这个钻取

我有一些代码似乎在工作,但我在网上看到的一些东西让我担心我的方法可能是错误的。既然“我能做到这一点吗?”和“我应该做到这一点吗?”是两个不同的问题,我希望一些PHP老手能插话

我当前的策略是创建一个包含所有公共代码的基本抽象表类,然后让每个表示单个表的类对其进行扩展

我主要关注的是以下代码:


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)";
正如您所看到的,关键是我访问这些
静态抽象
函数的方法是在它们前面加上
静态::
。据我所知,它正在发挥作用

但是,对的公认答案表明,
抽象静态
函数在5.3中仍然是不允许的


所以,我想知道该怎么做。答案错了吗?
抽象静态
函数现在被认为是完全合法的PHP代码吗?我是否在代码中做了一些不可取的事情?还有另一种方法我应该考虑吗?

< P>抽象函数在任何语言中都不会是静态的。

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

抽象函数不提供任何函数性

从逻辑上讲,您不能使用抽象的静态函数,因为抽象的静态函数将永远提供函数性


B扩展A

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

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

下面是您的示例

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();
如果删除此处的静态关键字,您实际上会得到有用的(也是一种标准的操作方式)代码:


所以,对于我是否在做一些不可取的事情这个问题,这将是一个“是”的回答。你对PHP为什么会让我逍遥法外有什么见解吗?或者你对另一种不那么自相矛盾的方法有什么建议吗?你使用的对象范例是错误的。我同意abstract关键字,但这3个函数总是在实例上工作,它们不应该是静态的。为什么它们不应该是静态的?用户对象的字段列表将在所有用户对象中保持一致;它不依赖于实例。类似地,我认为我应该能够调用类上的“insert”或“select”,而不是实例化的对象。如果永远不会调用(也永远不会调用)静态插入函数,为什么要将其放在上下文中?因为该插入函数的代码在所有B类中基本相同——所有更改都是表名和字段名。在这里,继承模型对我来说非常有意义。你觉得我忽略了一个更合理的方法吗?如果你说“你知道交易”,我可以肯定一件事:交易是不使用静态函数。如果您认为是这样的话,那一定是null checkers协议,因为静态函数不能很好地处理您喜欢使用的继承。此外,我建议你读一读诗集,我是说,你知道这本书的内容,对吧?@hakre:这种敌意和屈尊从何而来?“你知道演练”是指一种相当标准的数据库内容建模方法,我认为这种方法不值得重复。请提供参考,说明你所描述的是一种相当标准的方法。PHP有很多ORM框架,包括(但不限于)和。这是一个非常复杂的轮子;你确定要重新发明它吗?@凤凰城:老实说?主啊,没有。但我的选择令人不快;我们没有一个适合生产服务器的系统管理员,而PHP安装就在那里。。。我会很好地称之为“功能灯”。安装任何有趣的东西对我来说都太白痴了。我宁愿自己做轮子,尽管它可能不完美,也不愿在雪橇上拖拉。嗯,为什么里面有明显多余的
新的
——你只需要一根绳子,例如
$t='ConcretTable'为什么不让它依赖于使用
\uuuu函数\uuuu
常量读取的某个函数名?或者更常见的情况是:将表名添加为受保护的属性(或SQL查询)?邀请一个接口到参与方似乎给了我想要的行为,而没有任何逻辑悖论干扰我的代码。我向你表示感谢。:-)@hakre:new
只是一个名为类()的Java habitget,它可以代替命名类所代表的表的需要。因此,您可以有一个getTableName(),它返回get_,称为_class(),可以由单个类重写以自定义表名
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();