0

__get()マジックメソッドの種類の機能を実装する方法があるかどうかを確認しますが、新しいクラスをインスタンス化しようとする場合。

私の目標は

$foo = new Cat();

最終的には、汎用オブジェクトが作成されます。

new Mammal('Cat');

これ$fooはクラスのインスタンスでありMammal、呼び出されたクラス名('Cat')が引数としてMammalのコンストラクターに渡されます。


注:LithiumまたはCakePHPに精通している人にとって、私が念頭に置いている最終的なゲームは、異なるデータベーステーブルごとに多数のクラスを定義する必要がないようにすることです。もしそうなら、ほとんどは単に空であり、基本的なCRUD操作が必要なすべてです。さらに、これらすべてのインクルードとクラス定義は、オーバーヘッドに最適ではありません。私の考えは、単一の「モデル」クラスを使用してほとんどのジェネリック関数を処理することです。特定のデータベーステーブルに対してより高度な機能が必要な場合は、いつでもサブクラスを作成できます。

4

4 に答える 4

2

クラスのインスタンス化メカニズムを使用して、必要なことを達成するための簡単でハッキーでない方法はないと思います。

工場を使用することをお勧めします:

$tableFactory->createTable('Cat');

その後、舞台裏で何をする必要があるかがわかります。これには、Catに独自のクラスが必要であると判断した場合に、ファクトリを変更するだけで、それを使用しているコードを変更する必要がないという利点もあります。

于 2010-07-08T21:22:14.393 に答える
0

まあ、それは少しハッキーですが、クラスのオートローダーを悪用する可能性があります...

したがって、ローダーをハイジャックしてクラス「Cat」をチェックし、存在しない場合は、存在を評価します...

if (!$foundClass) {

    $code = 'Class '.$class.' extends Mammal { 
        public function __construct() { parent::__construct("'.$class.'");}
    }';
    eval($code);
}

ハッキーだと言いました...しかし、これを実行したいクラスをいつでもホワイトリストに登録できます...さらに、クラスを変更したい場合は、そのクラスのしっかりしたインスタンスを作成するだけでよいという利点があります。

しかし、もう一度、私は個人的に別の解決策を見つけるでしょう。私にnew Cat()は、まったく読めません。これは2つの理由によるものです。1つ目はそれが何であるかについての文脈上の手がかりがなく、2つ目はクラスCatを見つけることができません...私がすることはJaniが提案したことと似ています:$table = DatabaseTable::getInstance('cat');...私はそれをはるかに読みやすくします(より多くのキャラクターですが)...

于 2010-07-08T22:23:56.107 に答える
0

Cakeで覚えているのは、コントローラークラスの上にモデルを定義してから、$this->Modelnameを使用することです。これは、次のように簡単に実装できます。

public function __get($prop)
{
    if(in_array($prop, $this->uses)) {
        return new $prop;
    }
}

存在しないプロパティを呼び出すたびに、クラスはプロパティ名が配列$ usedに存在するかどうかを確認し、存在する場合は$propがクラス名であると想定してインスタンス化します。インスタンスをフェッチするたびに再インスタンス化されないように、インスタンスをどこかに保存することをお勧めします。

new Klassこれは、Klassを他のものと交換するのが難しくなるため、あちこちに書くよりもいくらかきれいです。次に、それをコントローラーに配線します。避けたい依存関係です。そうは言っても、 Symfonyの依存性注入フレームワークを見てみたいと思うかもしれません。

于 2010-07-08T22:26:11.040 に答える
0

これは今では古い質問ですが、今日でも多くの人に関係があります。

この正確なシナリオを克服する私の方法は、すべての基本的なテーブルの相互作用を保持するベースモデラーを持つことです。

<?php
    class base {

        /**
         * @name        $table_values
         * @description This holds all data about the table including the field names and data for the record loaded.
         * @example     {
         *                  "primary_keys"  :   [],
         *                  "table_data"    :   {
         *                                          "name"  :   "value",
         *                                          "name"  :   "value"
         *                                      }
         *              }
         */
        private $table_values = array();

        /**
         * @name        __get
         * @param       $name   The name of the property to return.
         * @description The PHP magic getter.
         */
        public function __get($name) {
            $keys = array_keys($this->table_values['table_data']);
            if (in_array($name, $keys)) {
                return $this->table_values['table_data'][$name];
            }
        }

        /**
         * @name        __set
         * @param       $name   The name of the property to set.
         * @param       $value  The value to assign to the property.
         * @description The PHP magic setter.
         */
        public function __set($name, $value) {
            $this->table_values['table_data'][$name] = $value
        }

        /**
         * @name        table_name
         * @description Must override in child class. Should return the name of the table to use.
         */
        public function table_name() {}

        /**
         * @name        load
         * @param       $ids    int|array   Can be a single primary key or an assoc array of primary keys depending on the table with the keys for the array being the field names.
         * @description This method handles loading a single record from the table and storing it as a PHP object.
         */
        public function load($ids) {
            // Use the primary key(s) to find and load the record into $table_values from the database.
        }

        /**
         * @name        save
         * @description Saves the record in the database
        public function save() {
            // Use the primary key(s) to find and either insert or update the database table record.
        }
    }
?>

基本クラスを次のように使用します。

<?php
    class person extends base {
        public function table_name() {
            return "person";
        }
    }

    class car extends base {
        public function table_name() {
            return "car";
        }
    }
?>

オートローダーを使用して、クラスを自動的にロードし、テーブルにクラスが存在しない場合に処理します。

<?php
    spl_autoload_register(function($class_name) {
        $filename = "/path/to/class/{$class_name}.php";
        if (class_exists($class_name)) {
            // Do nothing.
        } elesif (file_exists($filename)) {
            require_once($filename);
        } else {
            // Check if the class name exists in the database as a table.
            if ($database->table_exists($class_name)) {
                $class_def = "
class {$class_name} extends base {
    public function table_name() {
        return \"{$class_name}\";
    }
}";
                eval($class_def);
            }
        }
    });
?>

基本クラスには、さらに多くの機能を含めることができます。また、子をオーバーライドして、ロードと保存の前後に処理を実行したり、同じデータを含む重複レコードをチェックしたりする機能もあります。

于 2016-10-11T10:38:43.567 に答える