0

重複の可能性:
データベース接続/オブジェクトをPHPの関数に取り込むための最良の方法は何ですか?
PHPでのデータベースとOOPの実践

OOPショッピングカートを作成しようとしています。

現在、それは半分のOOPであり、半分の手続き型です...例:

function removeFromCart() { 
    require_once('/.../.../connectPDO.php');
    $db = connectPDO();

    $sql = 'DELETE FROM Quotes WHERE User = :user and ProductId = :pid';
    $stmt = $db->prepare($sql); 
    $stmt->execute(array(':user' => $user, ':pid' => $pid));
}

私の問題は、カートに追加したい場合、関数addToCartで、db接続を再度要求する必要があることです。

すべての関数に次のものが含まれている必要があることを考えると、これは完全な無駄のようです。

    require_once('/.../.../connectPDO.php');
    $db = connectPDO();

これは完全に非効率的であることを認識しており、上記の接続を使用してDBに接続するスケルトンOOPカートクラスを作成するのを誰かが手伝ってくれるかどうか疑問に思っていましたか?

これはコンストラクターに入りますか?ユーザーがフロントエンドで1つのページから別のページに移動しても、これは存続しますか?

私はOOPに不慣れで、完全に迷子になっています。

よろしくお願いします。

4

2 に答える 2

4

次のようなものがあなたを始めるはずです:

$pdo = new PDO('your dsn');
$cartData = new CartData($pdo);
$cart = new Cart($cartData);

class CartData
{
    private $dbConnection;

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

    public function removeItem($userId, $productId) { 
        $sql = 'DELETE FROM Quotes WHERE User = :user and ProductId = :pid';

        $stmt = $this->dbConnection->prepare($sql);
        $stmt->execute(array(':user' => $userId, ':pid' => $productId));
    }
}

class Cart
{
    private $cartData;

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

    public function removeItem($userId, $productId) { 
        $this->cartData->removeItem($userId, $productId);
    }
}

Cartある時点で別のデータベースエンジンにスワップするのが困難/不可能になるだけなので、実際のクラスからデータベース呼び出しを削除したことに注意してください。または、データを保存する完全な別の方法(ahumユニットテスト)を導入することもできます。また、依存性注入を使用して、クラスが担当するものを実行できるようにするために必要なオブジェクトをクラスに提供していることにも注意してください。

注入されるクラスオブジェクトにタイプヒントを使用しましたが、クラスを他のクラスに簡単に交換できるため、インターフェイスに対してタイプヒントを使用する方が適切でした。そして、私はあなたがインターフェースを使うことを強くお勧めします(私が上で書いたものは単にアイデアを得るための例です)。これにより、コードの単体テストを非常に簡単に作成することもできます。

于 2012-12-29T22:47:06.180 に答える
1

すべてのページ要求で、新しいデータベース接続を確立します。リクエスト間で接続を共有することはできません。

これを処理するためのいくつかの異なるデザインパターン(ベストプラクティス)があります。それらすべてについて、DB抽象化レイヤー(PDO、Doctrine DBALなど)が必要です。

依存性注入(推奨)

これを処理するために最もよく使用されるデザインパターンは、依存性注入です。

class Foo
{
    /**
     * @var DatabaseAbstractionLayer
     */
    private $dbal;

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

    public function methodThatUsesTheDbal()
    {
        $this->dbal->query(...);
    }
}

$db = new DatabaseAbstractionLayer();
$foo = new Foo($db); // constructor injection

$bar = new Bar();
$bar->setDbal($db); // setter injection

$baz = new Baz();
$baz->dbal = $db; // property injection (almost never used)

これを簡単に処理するためにサービスコンテナを使用できます(例:にきび):

$container = new Pimple();
$container['db'] = $container->share(function ($c) {
    return new DatabaseAbstractionLayer();
});
$container['foo'] = function ($c) {
    return new Foo($c['db']);
};

$foo = $container['foo']->methodThatUsesDbal();

シングルトン

class DatabaseAbstractionLayer
{
    private static $_instance;
    // ...

    private function __construct()
    {
        // ...
    }

    // ...

    public static function getInstance()
    {
        if (null === self::$_instance) {
            self::$_instance = new static();
        }

        return self::$_instance;
    }
}

class Foo
{
    public function methodThatUsesDbal()
    {
        $db = DatabaseAbstractionLayer::getInstance();
        // ...
    }
}

登録

Registery::set('db', new DatabaseAbstractionLayer());

class Foo
{
    public function methodThatUsesRegistery()
    {
        Registery::get('db');
        // ...
    }
}
于 2012-12-29T22:47:30.920 に答える