0

これは、しばらくの間 PHP で私を悩ませてきたものであり、どうすればよいのかまだわかりません。基本的に現時点では、SQL クラスの結果を配列にダンプし、それらをオブジェクトに変換して、次のようにしています。

$first_post = $Post->find(1);

(構文を $Post::find(1); のようにすることも試みましたが、それはまったく別の、純粋に審美的な問題です)

そして、次のように first_post を使用できます。

$first_post->title;

これは、次の$post->find(1)ように の内容をオブジェクトに変換するだけで実行できます。

$first_post = (object) array("title" => "blah");

それが新しいSTDClassをインスタンス化することは知っていますが、メソッドをSTDClassのその新しいインスタンスにバインドする方法がわかりません。それは主に次のようなことができるようにするためです。

$posts = $Post->all();
$last_post = $posts->last();
$specific  = $posts->find("name" => "hello");

PHPにこのようなことをさせる方法はありますか?

4

5 に答える 5

1

StdClassJavaScript でメソッドを動的に追加できるため、メソッドを にバインドすることはできません。

必要なメソッドでクラスを作成する必要があります。(異なるクラスに共通のメソッドがある場合はextends、 orを使用できます。)trait

例えば:

class Post
{
    static function find()
    {
        $post = new Post();
        $array = array('title' => 'First Post');
        foreach ($array as $key => $value)
        {
            $post->$key = $value;
        }
        return $post;
    }

    public function do_something()
    {
        echo $this->title;
        return $this;
    }
}
于 2012-06-18T14:09:14.610 に答える
1

(構文を $Post::find(1); のようにすることも試みましたが、それはまったく別の、純粋に審美的な問題です)

スコープ解決演算子を使用する場合、静的メソッドや定数にアクセスしています。これらは、クラスのインスタンスではなくクラスで機能するメソッドです。例えば:

// the find method retuns a new Post instance and 
// does not try to access $this
$post = Post::find(1);  

配列から投稿用のオブジェクトを作成する場合は、独自のクラスを作成してそれに応じて入力するか、テーブル データをやPostなどの配列ではなくオブジェクトとして返すデータベース関数のいずれかを使用することをお勧めします。mysqli_result::fetch_objectmysql_fetch_object

独自の Post クラスを作成する場合は、データベース情報を配列に格納し__call()__get()および__get() Magic メソッドを使用してそのデータにアクセスできます。例えば:

class Post() {
    protected $data;

    public function __construct($data) {
        $this->data = $data;
    }

    // access data with a getFoobar() style call
    public function __call($name, $args) {
        if (substr($name, 0, 3) == 'get') {
            $key = strtolower(substr($name, 3));
            if (array_key_exists($key, $this->data)) {
                return $this->data[$key];
            }
        }

        $class = get_class($this);
        throw new Exception("Call to undefined method $class::$name");
    }

    // access data like a class property
    public function __get($key) {
        if (array_key_exists($key, $this->data)) {
            return $this->data[$key];
        }

        throw new Exception("Attempt to access non-existant property $class::$name");
    }

    // set the data like a class property
    public function __set($name, $value) {
        $this->data[$name] = $value;
    }
}
于 2012-06-18T14:12:41.110 に答える
0

Postクラスを作成できると思います

インスタンス化すると、すべての投稿を取得して配列として保存できます。

指定されたクエリのすべての投稿を検索する find メソッドを持つことができます。

また、それぞれ最後の項目または最初の項目を取得する last メソッドと first メソッドを持つこともできます。

メソッドを使用してクラス プロパティを動的に作成できると思います__get。これはプロパティ名を受け入れます。投稿の配列を検索し、存在する場合は値を返すことができます。

PHP でインスタンス プロパティを動的に作成できますか?

于 2012-06-18T13:57:11.603 に答える
0

できますが、インスタンス化ごとに毎回行う必要があります。

$obj = new stdClass();
$obj->myMethod = function($name) {echo 'Hello '.$name;};

上記は機能しません...私はドキュメントからこのアプローチを成功裏に使用しましたが、これは同じ行に沿っていました: http://uk3.php.net/manual/en/reserved.classes.php#105404

于 2012-06-18T13:55:58.843 に答える
0

PDOデータベースからデータを取得するために使用している場合は、このメソッドを見てくださいPDOStatement::setFetchMode。を使用して、結果の各行に対して新しいクラスをインスタンス化するように PDO に指示できますPDO::FETCH_CLASS。正確なメソッド定義は次のようになります。

bool PDOStatement::setFetchMode ( int $PDO::FETCH_CLASS , string $classname , array $ctorargs )

そしてそれをあなたの文脈に入れるには:

namespace My\Web;

class Post {
    public function __construct($arg) {
        var_dump($arg);
    }

    public function getTitle() {
        return $this->title;
    }

    public function getFormatedContent() {
        return whatever($this->content);
    }
}

オブジェクトの取得:

$stmt = $conn->query($sql);
$posts = $stmt->setFetchMode(PDO::FETCH_CLASS, 'My\Web\Post', array(rand()));
print_r($posts);
// print array of My\Web\Post objects, each will print some random number in it's constructor.

だから私があなたに見せようとしているのは、プロパティの配列を stdClass に変換してからいくつかのメソッドをバインドする必要がないということです。
必要に応じてクラスを作成し、PDO にそのクラスでクエリ結果をラップさせることができます。

ちなみに、最新の Doctrine DBAL でも動作します (PDO の上に構築されているため)。

于 2012-06-18T14:28:54.237 に答える