在 Doctrine 中向当前表添加虚拟列?

发布于 2024-10-16 01:54:17 字数 1221 浏览 2 评论 0原文

我正在使用 Doctrine 1.2 和 Symfony 1.4。假设我有一个用户模型,其中有一个配置文件。这些定义为:

用户:

  • id
  • 用户
  • 名 密码
  • 创建的_at
  • update_at

配置文件:

  • id
  • user_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"
    )
)

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

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

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

I'm using Doctrine 1.2 with Symfony 1.4. Let's say I have a User model, which has one Profile. These are defined as:

User:

  • id
  • username
  • password
  • created_at
  • updated_at

Profile:

  • id
  • user_id
  • first_name
  • last_name
  • address
  • city
  • postal_code

I would normally get data like this:

$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);

This would output something like the following:

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

However, I would like for user to include "virtual" columns (not sure if this is the right term) such that fields from Profile actually look like they're a part of User. In other words, I'd like to see the print_r statement look more like:

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

Is there a way to do this either via my schema.yml file or via my Doctrine_Query object?

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

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

发布评论

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

评论(4

む无字情书 2024-10-23 01:54:17

做你想做的事情的方法是使用 定制水化器

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();
    }
}

然后向连接管理器注册您的水化器:

$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"
    )
)

您可能需要稍微微调水化器逻辑才能获得您想要的确切数组结构。但这是做你想做的事情的可接受的方式。

The way to do what you want is to use a custom 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();
    }
}

Then register you hydrator with the connection manager:

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

Then you hydrate your query like this:

$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"
    )
)

You might have to fines the hyrdator logic a little to get the exact array structure you want. But this the acceptable way to do what you want.

大海や 2024-10-23 01:54:17

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

不过,您的问题有一个解决方案。在 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();

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

echo "User " . $result->username ."'s first name is " . $result->prof_first_name;

Your example is not entirely correct: if you fetch from the DQL you specified above, you will only get a User object, not an array with a User and a Profile. If you want to access the profile, you will have to do it through the relationship set up in your User, if you specified one in the schema.

Nevertheless, there is a solution to your problem. In DQL, if you use column aliases when selecting things, the aliased columns will be accessible in every instance returned as if they were part of the model. So let's say you do the following:

$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();

In this case the result will be a single User object, with all the properties of a user plus 2 extra properties: prof_first_name and prof_last_name. Please note that while I used "prof_" as a prefix, it has no semantic meaning, I could have used anything else as well. So you should be able to do the following:

echo "User " . $result->username ."'s first name is " . $result->prof_first_name;
无所谓啦 2024-10-23 01:54:17

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

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

I dont use array hydration much so maybe i havent noticed but i could have sworn the structure youre looking for is whats produced by:

Doctrine_Query::create()
  ->select('u.id, u.username, p.first_name, p.last_name')
  ->from('User u')
  ->leftJoin('Profile p')
  ->where('u.username = ?', $username);
日暮斜阳 2024-10-23 01:54:17

使用 setHydrationMode(Doctrine_Core::HYDRATE_SCALAR) 代替。

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

Use setHydrationMode(Doctrine_Core::HYDRATE_SCALAR) instead.

It fetched results in rectangular manner and uses aliases of tables as prefixes and aliases of column as name. So all colunm would be accesible trough tableAlias_columnAlias.

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