【问题标题】:What's the best way of sending a PDO between actions in Symfony2?在 Symfony2 中的动作之间发送 PDO 的最佳方式是什么?
【发布时间】:2015-03-29 04:20:09
【问题描述】:

在控制器的操作中,我从数据库加载一个 PDO 对象并将其发送到 twig 模板以呈现数据网格:

/**
 * @Route("/action1", name="action1")
 * @Template()
 */
public function action1Action(Request $request)
{
    $mydata = $this->daoClass->getData();
    return array(
        'mydata' => $mydata
    );
}

$myData 是使用 Doctrine 加载的,它返回一个带有(小)结果数组(PDO 对象)的 PDO 对象。我这样渲染:

<table>
    {% for data in mydata %}
        <tr>
            <td>{{ data.foo }}</td>
            <td>{{ data.bar }}</td>
        </tr>
    {% endfor %}
</table>

所以在 twig 模板中,在包含数据的表格下方,我得到了将数据发送到下一个操作的表单:

<form action="{{ path('action2') }}" method="post">
    <!-- some javascript populated fields -->
    <input type="hidden" id="field1" name="field1">
   ...
</form>

如何让它也发送渲染网格的 PDO 对象(mydata 对象)?

我尝试在第一个操作中将其插入会话中,以便在下一个操作中检索它,但收到消息:“您无法序列化或反序列化 PDO 实例”

有没有更好的方法来做到这一点?

我没有在这个模块中使用 symfony 表单,因为这是一个过于复杂的屏幕,有很多验证和计算字段,使用表单会复杂得多。

【问题讨论】:

  • 为什么不从数据库中再次选择它?
  • 当您说“PDO 对象”时,您是指实体还是实体的结果集?
  • 对面不是更有意义吗?为什么选择两次相同的数据?
  • 性能?您有任何真正的性能问题吗?如果是这样 - 这些问题是什么?哪里有数字?如果是关于性能问题的问题,为什么问题文本中一个字都没有?
  • 所以您正在解决您还没有遇到的问题,并且您认为该解决方案将神奇地匹配您可能遇到的负载模式?你要思考的一件事:即使是 facebook 和 twitter 的工程师也无法预测所有的性能瓶颈。所以他们只是根据新的负载要求来发展他们的架构。你真的认为你能比他们做得更好吗?

标签: php symfony pdo twig


【解决方案1】:

有没有更好的方法来做到这一点?

是的,对于 symfony 表单。

我没有在这个模块中使用 symfony 表单,因为这是一个过于复杂的屏幕,有很多验证和计算字段,使用表单会复杂得多。

随心所欲。使用 symfony 表单进行映射,视图和 symfony 验证是非常强大的工具。无需编写自己的表单以及映射和验证。

在 Symfony2 中的动作之间发送 PDO 的最佳方式是什么?

答案绝对不是将 Doctrine 实体保存到会话或 Memcache 中,原因是:

//从评论中复制

在范围内思考。 PHP 启动、执行、终止。您只能保存范围不受限制的数据。例如,一个简单的字符串没有范围。您只能存储此类数据,但不能存储智能 PDO 对象。例如,教义实体实际上只是一些带有 getter 和 setter 的属性,但教义正在做一些魔术来为它们实现代理模式。因此,它们扩展了一些访问逻辑,如果调用了任何 setter 或 getter,则首先从数据库加载对象。如果您将它们存储并重新加载它们,它们将具有对对象的死引用。

【讨论】:

  • 实际上,我在使用表单处理更复杂的任务时遇到了一些糟糕的经历。我的感觉是有点失控。例如:并非总是出现 javascript 消息,有时表单已提交但未验证,以及其他错误。代码很大而且过于复杂,无法在论坛中寻求帮助,而且我是我公司当地办公室中唯一使用 symfony 编程的人。所以... get I 和 Symfony Forms 在这个时候不走运。 :)
  • @NelsonTeixeira 如果您还不知道如何完成复杂的任务,请不要将 Symfony 用于生产。不可能做你想做的事,而且有充分的理由。
  • 而原因是……?
  • @NelsonTeixeira Symfony2 不允许您将 PDO 保存到会话中。如果他们不允许这样做,那很可能意味着您做错了什么。
  • 在范围内思考。 PHP 启动、执行、终止。您只能保存范围不受限制的数据。例如,一个简单的字符串没有范围。您只能存储此类数据,但不能存储智能 PDO 对象。例如,教义实体实际上只是一些带有 getter 和 setter 的属性,但教义正在做一些魔术来为它们实现代理模式。因此,它们扩展了一些访问逻辑,如果调用了任何 setter 或 getter,则首先从数据库加载对象。如果您将它们存储并重新加载它们,它们将具有对对象的死引用。
【解决方案2】:

首先,不要出于性能原因做你想做的事情。

您正在尝试做的事情称为过早优化,它是not good

这里有人试图做一个very similar thing to what you're doing and they are having a hard time

但是,如果您想将用户信息临时存储到另一个页面,请使用Symfony Sessions

如果你跳过我说的话,让我重复一遍:

警告:不建议将此代码用于 PDO 结果

use Symfony\Component\HttpFoundation\Session\Session;

$session = new Session();
$session->start();

// set and get session attributes
//Controller ExampleMethodAction1()
$Person = new Person();
$Person->setName('John');
$session->set('PersonObject', $Person);


//Then in another controller method
//Controller ExampleMethodAction2()
$Person = $session->get('PersonObject');
$Person->getName(); //returns John

关于性能的另一件事是,购买更多硬件比聘请新的开发人员来优化代码更便宜。

【讨论】:

  • 是的...这就是我试图做的,但 Symfony 不允许 PDO 对象这样做。这就是我问的原因。如果您想了解更多关于我对这种方式的看法,请查看我与@zerkms 的讨论。 :)
  • @NelsonTeixeira 没错,Symfony2 不允许这样做是有原因的。因此,当 Symfony2 告诉您不要这样做时,您就知道自己做错了。只需再次调用数据库即可。
  • @NelsonTeixeira 如果你真的必须忽略所有这些警告。创建一个类,例如new Person,并用数据库中的数据填充它。然后将Person 传递给另一个控制器方法,使用像我上面的例子一样的会话。
  • 我想要的是发送 PDO 对象而不对其进行处理,这正是因为我想简化代码而不是进行另一个数据库调用。如果我必须创建一个循环来重新创建对象数组,那将毫无意义。
  • @NelsonTeixeira 这是获得您想要的东西的唯一方法。无论哪种方式,您都不应该直接使用 PDO,而是应该将您的 Entity 对象映射到另一个类或使用 Doctrine。这样您只需映射一次并让映射类可重用,同时也使您的对象可重用。 Symfony2 中存在Entities 是有原因的,如果你不打算使用你不应该使用 Symfony 的工具。您应该将 Symfony Components 与普通 PHP 一起使用。
猜你喜欢
  • 1970-01-01
  • 2017-01-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-10
  • 1970-01-01
相关资源
最近更新 更多