开发者

How to merge two doctrine entities in the same object

In my database, the user management is divided into two tables: - One created by the symfony sfDoctrineGuard plugin (sfGuardUser), with the username, 开发者_如何学Gothe password and other information used by the plugin - another one that I created to extend this table with more properties such as the firstname, surname etc...

What I want to do is to gather all the properties of the two tables in a same object to display all the information related to any member on a specific page.

In that purpose I did a join of the two tables like this:

$q = $this->createQuery()
->from('sfGuardUser u')
->leftJoin('u.Mishmember m WITH u.id = ?', $rel['member_id']);

$member = $q->fetchOne();

My problem is that the generated query seems correct since it selects all the attributes of both tables, but in the $member variable, I can only access the properties of the sfGuardUser object.

I want the $member object to encapsulate all the properties of both tables/doctrine objects.

How would you do that?


EDIT1: if I do a

print_r($member->toArray()) 

after the previous code I get a 2 dimensional array containing all the properties of sfGuardUser in a first dimension and the properties of my second table in a second dimension. To be clear the result of print_r is like:

Array (
   [table1-prop1] => value 
   [table1-prop2] => value 
   [table1-prop3] => value 
   [Table2] => Array (
                  [table2-prop1] => value 
                  [table2-prop2] => value 
                  [table2-prop3] => value 
                  [table2-prop4] => value
   )
) 

So to access for example the table2-prop3 property I have to do: $var[Table2][table2-prop3];

Which is not what I want because I want to consider all the properties as part as the sameobjet or array (as if there were only one table.)

If you're still with me the above array should look like:

Array (
   [table1-prop1] => value 
   [table1-prop2] => value 
   [table1-prop3] => value 
   [table2-prop1] => value 
   [table2-prop2] => value 
   [table2-prop3] => value 
   [table2-prop4] => value
   )
) 

Hope that helps to understand my problem.


EDIT2 (answer to DuoSRX and DrColossos)

Thank you both for your interesting answers.

Well, the reason why I'd rather not to have a Mishmember property in my sfGuardUser is that both tables/classes stand for the same entity(the user). Though this fragmentation is inevitable in my database (it wouldn't be wise to edit directly the sfGuardPlugin to add my properties), I'd like that the code of the application would be as if I had one table, because that would be much more sensible and logical to use (imagine that another developer who doesn't know the model would have to work on the controller or the templates...)

What would you think of adding a Doctrine class User that inherits from sfGuardUser and Mishmember (is there multiple inheritance in PHP5?) so that my controller would have only one user class to deal with?

It would make much more sense to me to ask all the attributes of any user without bothering to find out in which table they are stored.

I'm not sure about how doctrine inheritance works but it seem the neatest solution to me (please tell me if I'm wrong!)

I'm not sure I've been clear enough so please don't hesitate to ask anything.


If you don't need objects but just arrays you can do :

$result = $query->fetchArray();
$mishmember = $result['Mishmember'];
unset($result['Mishmember']);
$user = array_merge($result, $mishmember);

That should do the trick, but I think this is too complex. What is the problem with having an multi-dimensional array ?

Edit:

Well then you could use simple or column_aggregation inheritance :

Mishmember:
  inheritance:
    type: simple (or column_aggregation)
    extends: sfGuardUser
  columns:
    myfield: 
      type:integer

And then :

$mishmember = Doctrine::getTable('Mishmember')->find(1);
echo $mishmember->myfield;

See the doctrine documentation for more about inheritance.


This is not really how ORMs work: As you noted, you get a sfGuardUser Object/Array back. Now the Mishmember is nothing more than a property to sfGuardUser (it's an coincindent, that is is an object iteself). So instead of having just a e.g. string property, you have an object/array property.

edit: Of yourse you can merge/combine/re-create the array/object (as the other answer suggests), if you don't like the multi-dimensional aspect. But keep in mind, that these operations can get pretty complex when you have larger amounts of returned data.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜