Подтвердить что ты не робот

Абстрактная статическая функция в PHP 5.3

Я относительный новичок в 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();

Идея состоит в том, что каждый реализующий класс будет определять имена полей, первичный ключ (ы), имя таблицы и т.д., а затем класс таблицы будет использовать эти функции для заполнения конкретных пробелов, например:


    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 все еще не разрешены в 5.3.

Итак, я пытаюсь понять, что с этим делать. Является ли ответ неправильным - функции abstract static теперь считаются вполне законным PHP-кодом? Я делаю что-то нецелесообразное в своем коде? Есть ли другой подход, который я должен рассмотреть?

4b9b3361

Ответ 1

Вот ваш пример

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

Ответ 2

Абстрактная функция никогда не будет статичной, на любом языке.

Статическая функция обеспечивает функциональность, даже если нет экземпляра.

Абстрактная функция не предоставляет никакой функциональной функции.

Логически, вы не можете использовать абстрактную статическую функцию, которая будет --ALWAYS AND NEVER - обеспечивать функциональность.


B продолжается A

Когда вы вызываете статическую функцию в контексте B, она будет запущена в контексте A (причина статического состояния).

Но в контексте A эта же функция является абстрактной, вы не можете называть ее.