PDO FETCH_INTO Фабрика? - PullRequest
       11

PDO FETCH_INTO Фабрика?

0 голосов
/ 01 октября 2010

У меня есть фабрика под названием ProductFactory

Я могу создать продукт, подобный так:

$product = ProductFactory::getProduct($id);

Теперь, в зависимости от того, какой тип продукта мы получаем, эта функция может возвращать класс типа Product или его потомка, или Product.

Но, используя описанный выше метод, класс $product будет отвечать за подключение к базе данных и извлечение ее данных.


Таким образом, если бы я выбрал 20 продуктов для отображения в списке категорий, мне сначала нужно было бы получить список всех идентификаторов, а затем вызвать вышеуказанную функцию 20 раз. Это будет 21 вызов в базу данных.

Итак, я добавил еще одну функцию на свой завод, например:

$product = ProductFactory::createProduct($data);

Это делает то же самое, за исключением того, что вы передаете данные из базы данных, избавляя класс $product от необходимости совершать поездку. (в зависимости от того, какие данные вы передаете, фабрика вернет правильный тип класса).

Итак, теперь я хочу сделать один вызов, чтобы выбрать все данные о товарах, и FETCH_INTO моя фабрика, чтобы сгенерировать объект $ product для каждой строки.

Как я могу это сделать?

обновление

Вот что я попробовал, чтобы не получилось:

$stmt->setFetchMode(PDO::FETCH_INTO,ProductFactory::createProduct);
foreach($stmt as $product)
{
    echo get_class($product) . '<br>';
}

Ответы [ 2 ]

1 голос
/ 01 октября 2010

Вы могли использовать PDO :: FETCH_CLASSTYPE для чего-то вроде

<?php
$pdo = new PDO('mysql:host=localhost;dbname=test', 'localonly', 'localonly');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
initDemo($pdo);

$result = $pdo->query("SELECT IF(x,'Product','ProductXVal'), id, x FROM soTest");
while ( $obj=$result->fetch(PDO::FETCH_CLASS | PDO::FETCH_CLASSTYPE) ) {
  echo get_class($obj), "\n";
}

class Product {
  public function id() { return $this->id; }
}

class ProductXVal extends Product {
  public function x() { return $this->x; }
}

function initDemo($pdo) {
  $pdo->exec('CREATE TEMPORARY TABLE soTest (id int auto_increment, x int, primary key(id))');
  $pdo->exec('INSERT INTO soTest (x) VALUES (1),(NULL),(2),(NULL),(3),(NULL)');
}

который печатает

Product
ProductXVal
Product
ProductXVal
Product
ProductXVal

но это кажется довольно ... странным, если не сказать больше.
Я бы предпочел получить данные в виде массива и затем передать их фабрике, которая создает соответствующий объект. Вы можете сделать это в классе, производном от PDO и / или PDOStatement.

0 голосов
/ 01 октября 2010

Согласно разделу комментариев на странице PDOStatement-> fetch () , вы должны сделать это:

$stmt->setFetchMode(PDO::FETCH_INTO, new myClass());
$stmt->execute();
while ($object = $stmt->fetch())
{
  $result[] = clone $object;
}

Таким образом, существуют различия

  1. Вы передаете fetch_in в метод, а не в существующий объект
  2. Вы не выполняете оператор (по крайней мере, в вашем примере)
  3. Вы не включили вызов fetch () в вашем цикле
  4. Вы не клонируете объект

Теперь я не знаю, будет ли он работать с методом фабрики вместо существующего объекта, но вызовом execute() и fetch () - это наименьшее, что вы можете сделать:)

...