11

私はPHPに比較的慣れていないので、データベースアクセスコードを実装するための最良の方法を考えています。いくつかの単純なデータベースアクセスオブジェクトを作成しようとしています。各テーブルは独自のクラスを取得し、クラスの各インスタンスはテーブル内の行を表します。ドリルをご存知でしょう。

私は機能しているように見えるコードを持っていますが、オンラインで見たもののいくつかは、私のアプローチがどういうわけか間違っているのではないかと心配しています。そして「これはできますか?」と「私はこれをすべきですか?」2つの異なる質問ですが、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)";

ご覧のとおり、重要なのは、これらの関数の前に。を付けてこれらのstatic abstract関数にアクセスしていることですstatic::。そして、私が知る限り、それは機能しています!

ただし、この質問に対する受け入れられた回答はabstract static、5.3では機能がまだ許可されていないことを示しています。

だから、私はこれをどうするかを考えようとしています。答えは間違っていabstract staticますか?関数は完全に合法的なPHPコードと見なされていますか?私は自分のコードで何かお勧めできないことをしていますか?私が考慮すべき別のアプローチはありますか?

4

2 に答える 2

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();
于 2012-05-24T17:10:07.500 に答える
6

抽象関数は、どのような言語でも静的になることはありません。

静的関数は、インスタンスがない場合でも機能を提供します。

抽象関数は機能を提供しません。

論理的には、抽象静的関数を使用することはできません。これは、常に機能を提供します。


BはAを拡張します

Bコンテキストで静的関数を呼び出すと、Aコンテキストで実行されます(静的状態が原因)。

ただし、Aコンテキストでは、これと同じ関数は抽象的であり、呼び出すことはできません。

于 2012-05-24T14:59:53.290 に答える