0

データベースにアイテムのインデックスを作成する場合...おそらく管理者用のユーザーのリスト...オブジェクト指向の世界ではこれをどのように行う必要がありますか?

これを非常に基本的な例として取り上げます。

$sql = 'SELECT
            u.id,
            u.name
        FROM
            users AS u
        WHERE
            u.deleted = "0000-00-00 00:00:00"';

echo '<ul>';
foreach ($db->fetch_all($sql) as $row) {
    $url = './edit/?id=' . urlencode($row['id']);
    echo '
        <li><a href="' . html($url) . '">' . html($row['name']) . '</a></li>';
}
echo '<ul>';

今のところ、HTML がロジックに混在しているという事実は無視してください (簡潔にしようとしているだけです)。

現在、一部の開発者は、OOP の世界では、次のような方法で行う必要があると考えているようです。

class user {
    private $id;
    public function __construct($id) {
        $this->id = $id;
    }
    public function name_get() {
        return $this->value_get('name');
    }
    public function admin_url_get() {
        return '/admin/user/edit/?id=' . urlencode($this->id);
    }
    public function age_get() {
        // Calculate from $this->value_get('dob'), using date_diff()
    }
    public function address_billing_get() {
        // i.e. copy returned value onto the order object during checkout
    }
    public function address_delivery_get() {
    }
    private function value_get($field) {

        $db = db_get();

        $sql = 'SELECT
                    u.' . $db->escape_field($field) . '
                FROM
                    user AS u
                WHERE
                    u.id = "' . $db->escape($this->id) . '" AND
                    u.deleted = "0000-00-00 00:00:00"';

        if ($row = $db->fetch($sql)) {
            return $row[$field];
        } else {
            exit_with_error('Cannot return "' . $field . '" for user id "' . $this->id . '"');
        }

    }
}

class user_factory {
    static function get_all() {

        $users = array();

        $db = db_get();

        $sql = 'SELECT
                    u.id
                FROM
                    user AS u
                WHERE
                    u.deleted = "0000-00-00 00:00:00"';

        foreach ($db->fetch_all($sql) as $row) {
            $users[] = new user($row['id']);
        }

        return $users;

    }
}

echo '<ul>';
foreach (user_factory::get_all() as $user) {
    echo '
        <li><a href="' . html($user->admin_url_get()) . '">' . html($user->name_get()) . '</a></li>';
}
echo '</ul>';   

これには、次のようなバリエーションがあります。

  • ORM を使用するため、実際の SQL は記述しません (ただし、それは別の日にします)。

  • user __construct メソッドを SELECT * FROM user WHERE id = X を実行するように変更して、個別の値を毎回 user->value_get() で検索する必要がないようにします。

  • user_factory::get_all() メソッドを取得して SELECT * FROM を実行し、すべての値を個々のユーザー オブジェクトに渡します...ただし、これは (ファクトリではなく) 「ビルダー」パターンと呼ばれると思います。

私には、これはすべて非常に非効率的で、データベースとの間で多くのクエリが行われているように思えます...または必要のないデータを取得しています(SELECT * FROMはあまり良い考えではありません)。

たとえば、ユーザー テーブルに自宅/請求先住所 (それぞれ 1 行目、2 行目、3 行目、町、郵便番号など) などのフィールドがあるとします。この場合、ID と名前。

また、ファクトリ/ビルダー オブジェクトは検索するパラメーターを受け入れることもできるはずだと思います (たとえば、管理者が特定のユーザーを探している場合、このページでは、検索に電子メール アドレス フィールドも含める必要があります)。制限内(たとえば、10,000以上のレコードがおそらくリクエストをタイムアウトさせると推測しているページネーション)。

4

1 に答える 1

1

あなたはあまりにも多くのことを混乱させているので、私は混乱しました... 「OOP の世界」では、現実の世界と同様に、オブジェクトで考えます。私が正しく理解している場合、さまざまな目的でクエリを実行するデータベースにユーザーのリストを作成することを達成しようとしていますか?

まず第一に、関心の分離と呼ばれる原則に従って物事を整理したいと考えています。つまり、アプリケーションをレイヤー/モジュールなどで構造化し、各レイヤーには独自の責任があります。

そのため、永続層はストレージ (データベース) に関連するすべてを処理し、抽象化を公開します。抽象化とは、アプリケーション オブジェクトをデータに、またはその逆に「変換」することを目的とする 1 つまたは複数のオブジェクトです。

あなたの例では、DAL(データアクセスレイヤー)とも呼ばれる永続レイヤーがテーブルとそのすべてを処理します。したがって、通常はテーブルを作成してから、メソッドを持つタスクごとに作成します(もちろん、これはすべて単純化されています)。

したがって、ユーザー (id,Name) のリストだけが必要な場合は、GetUsers() のようなメソッド (関数) を使用して、関連するクエリを送信し、単純な DTO (データ転送オブジェクト) のリストを返します。 ) ID と名前のみが含まれます。

アプリケーションはそのメソッドから結果を取得し、それらを使用してビューを構築します。MVC コンテキストでは、返されるデータはビュー モデルであり、ビューが html を生成するために使用するデータです。

あなたが提示したOOPの例は、OOP以外のすべてです。これは、コンセプトがうまくまとめられていないだけです。

ORM と Factory は、実際にそれらが必要な場合のためのものであり、この例はそのためにはあまりにも単純すぎます。

OOP のアイデアは、アプリケーションをレゴのように設計することです。正確な目的を持つ複数の小さなパーツを組み合わせて、アプリケーションの目的を達成するために一緒に使用できる大きなコンポーネントにすることができます。

于 2013-01-07T15:32:07.003 に答える