7

我将 Doctrine 1.2 与 Symfony 1.4 一起使用。假设我有一个 User 模型,它有一个 Profile。这些定义为:

用户:

  • ID
  • 用户名
  • 密码
  • created_at
  • 更新时间

轮廓:

  • ID
  • 用户身份
  • 地址
  • 城市
  • 邮政编码

我通常会得到这样的数据:

$query = Doctrine_Query::create()
    ->select('u.id, u.username, p.first_name, p.last_name')
    ->from('User u')
    ->leftJoin('Profile p')
    ->where('u.username = ?', $username);
$result = $query->fetchOne(array(), Doctrine_Core::HYDRATE_ARRAY);
print_r($result);

这将输出如下内容:

Array (
    "User" => Array (
        "id" => 1,
        "username" => "jschmoe"
    ),
    "Profile" => Array (
        "first_name" => "Joseph",
        "last_name" => "Schmoe"
    )
)

但是,我希望用户包含“虚拟”列(不确定这是否是正确的术语),以便 Profile 中的字段实际上看起来像是 User 的一部分。换句话说,我希望print_r语句看起来更像:

Array (
    "User" => Array (
        "id" => 1,
        "username" => "jschmoe",
        "first_name" => "Joseph",
        "last_name" => "Schmoe"
    )
)

有没有办法通过我的 schema.yml 文件或通过我的 Doctrine_Query 对象来做到这一点?

4

4 回答 4

6

做你想做的事情的方法是使用自定义 Hydrator

class Doctrine_Hydrator_MyHydrator extends Doctrine_Hydrator_ArrayHierarchyDriver
{
    public function hydrateResultSet($stmt)
    {
        $results = parent::hydrateResultSet($stmt);
        $array = array();

        $array[] = array('User' => array(
            'id'         => $results['User']['id'],
            'username'   => $results['User']['username'],
            'first_name' => $results['Profile']['first_name'],
            'last_name'  => $results['Profile']['last_name'],
        ));

        return $array();
    }
}

然后向连接管理器注册 hydrator:

$manager->registerHydrator('my_hydrator', 'Doctrine_Hydrator_MyHydrator');

然后你像这样补充你的查询:

$query = Doctrine_Query::create()
    ->select('u.id, u.username, p.first_name, p.last_name')
    ->from('User u')
    ->leftJoin('Profile p')
    ->where('u.username = ?', $username);

 $result = $query->fetchOne(array(), 'my_hydrator');
 print_r($result);

/* outputs */
Array (
    "User" => Array (
        "id" => 1,
        "username" => "jschmoe",
        "first_name" => "Joseph",
        "last_name" => "Schmoe"
    )
)

您可能需要对 hyrdator 逻辑进行一些微调才能获得所需的确切数组结构。但这是做你想做的事的可接受的方式。

于 2011-02-15T23:47:00.933 回答
1

您的示例并不完全正确:如果您从上面指定的 DQL 中获取,您将只获得一个用户对象,而不是一个包含用户和配置文件的数组。如果您想访问配置文件,则必须通过在您的用户中设置的关系来完成,如果您在架构中指定了一个。

不过,有一个解决您的问题的方法。在 DQL 中,如果您在选择事物时使用列别名,则在返回的每个实例中都可以访问别名列,就好像它们是模型的一部分一样。因此,假设您执行以下操作:

$query = Doctrine_Query::create()
    ->select('u.id, u.username, p.first_name as prof_first_name, p.last_name as prof_last_name')
    ->from('User u')
    ->leftJoin('Profile p')
    ->where('u.username = ?', $username);

$result = $query->fetchOne();

在这种情况下,结果将是一个用户对象,其中包含用户的所有属性以及 2 个额外属性:prof_first_name 和 prof_last_name。请注意,虽然我使用“prof_”作为前缀,但它没有语义意义,我也可以使用其他任何东西。因此,您应该能够执行以下操作:

echo "User " . $result->username ."'s first name is " . $result->prof_first_name;
于 2011-02-15T23:08:56.210 回答
0

我不使用阵列水合,所以也许我没有注意到,但我可以发誓你正在寻找的结构是由以下产生的:

Doctrine_Query::create()
  ->select('u.id, u.username, p.first_name, p.last_name')
  ->from('User u')
  ->leftJoin('Profile p')
  ->where('u.username = ?', $username);
于 2011-02-03T19:59:58.470 回答
0

请改用 setHydrationMode(Doctrine_Core::HYDRATE_SCALAR)。

它以矩形方式获取结果,并使用表的别名作为前缀,使用列的别名作为名称。因此,所有列都可以通过 tableAlias_columnAlias 访问。

于 2011-02-15T04:42:27.387 回答