PDO FETCH_INTO 工厂?

发布于 2024-09-25 09:25:55 字数 858 浏览 3 评论 0原文

我有一个名为 ProductFactory 的工厂,

我可以像这样创建一个产品:

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

现在,根据我们获得的产品类型,此函数可能返回 Product 类型的类或后代或产品

但是使用上面的方法,$product 类将负责连接到数据库并检索其数据。


因此,如果我要选择在类别列表中显示 20 个产品,我必须首先获取所有 ID 的列表,然后调用上述函数 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>';
}

I have a factory called ProductFactory

I can create a product like so:

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

Now depending on what type of product we are getting, this function may return a class of type Product or a descendant or Product.

But using the method above, the $product class would be responsible for connecting to the database and retrieving its data.


So if I were to select 20 products to be displayed on a category list, I would have to first get a list of all the ID's then call the above function 20 times. This would be 21 calls to the database.

So I added another function to my factory like so:

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

This does the same thing, except you pass in the data from the database, saving the $product class from having to make the trip. (depending on what data you pass, the factory will return the right type of class).

So now I want to make one call to select all products data and FETCH_INTO my factory to generate a $product object for each row.

How can I do that?

update

Here is what I tried that did not work:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

作死小能手 2024-10-02 09:25:55

可以使用 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 派生的类中执行此操作。

You could use PDO::FETCH_CLASSTYPE for something like

<?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)');
}

which prints

Product
ProductXVal
Product
ProductXVal
Product
ProductXVal

but that seems rather ...odd to say the least.
I'd rather fetch the data as an array and then pass it to a factory that creates the appropriate object. You could do so in a class derived from PDO and/or PDOStatement.

嘿看小鸭子会跑 2024-10-02 09:25:55

根据 PDOStatement->fetch() 页面上的注释部分 ,你应该这样做:

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

所以存在差异

  1. 你将 fetch_ 传递到一个方法而不是现有对象
  2. 你没有执行该语句(至少在你的示例中)
  3. 你没有在你的代码中包含对 fetch() 的调用循环
  4. 你没有克隆对象

现在我不知道它是否可以使用工厂方法而不是现有对象,但调用execute()和fetch()是你至少可以做的:)

According to the comments section on the PDOStatement->fetch() page, you should do this:

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

So differences there are

  1. You're passing fetch_into a method rather than an existing object
  2. You're not executing the statement (in your example, at least)
  3. You didn't include a call to fetch() in your loop
  4. You're not cloning the object

Now I don't know if it'll work with a factory method instead of an existing object, but calling execute() and fetch() is the least you can do :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文