0

not sure if I'm asking too many questions on stackoverflow lately but I feel that the Zend Framework documentation is appalling. It seems like the examples are very vague and nothing like what is used in the real world. They encourage use of framework for tidy and organised code and then don't mention how it should be followed :D

So anyway! In the old application that I'm currently migrating across to Zend, I'd have a function called register like:

function register($username, $password, $email, $etc) {
    // Do stuff
    // Insert $email and other stuff into `user_profile` table
    // Insert $username and $password into the `user` table
}

But now with Zend... I've been following their Guestbook tutorial for getting started and I have the following models: User, UserMapper. And I have DbTables for every single table in my database like so: User, UserProfile.

So I like the functionality of when you register, you build up a User object and then call save on the mapper which writes the object to the database but the thing is, some of those user pieces go into the user profile table. The example on the guestbook application is that within UserMapper you only pull in the one table (User) and write to that... well I mean I could just do something like:

// Insert or Update data to user table
$this->getDbTable()->insert($user_data);
// Insert or Update User Profile data
$this->setDbTable('UserProfile');
$this->getDbTable()->insert($user_profile);

But that just seems a bit.. hacky. What is the actual recommended way of dealing with multiple tables?

Also, if I have custom queries... am I meant to put them into the created DbTable class or into the UserMapper class? I'm not really seeing what extending the DbTable is actually for. All the guide says is to do it and it doesn't really explain the benefits/reason/uses as to why you're doing it.

Thanks, Dom

Aurelio De Rosa
  • 21,856
  • 8
  • 48
  • 71
creamcheese
  • 2,524
  • 3
  • 29
  • 55
  • ["Favor 'object composition' over 'class inheritance'." (Gang of Four 1995:20)](http://en.wikipedia.org/wiki/Design_Patterns) – vascowhite Oct 23 '11 at 23:04
  • So I'm guessing you mean rather than having User->save() only grabbing and dealing with one DbTable 'User', that it should be using multiple tables within the one function? So I do what I was saying felt a little hacky. Set dbtable('user') and update that and then Set dbtable('userprofile') and do stuff – creamcheese Oct 24 '11 at 09:10
  • What sort of things do you do with your custom queries? – ChrisA Oct 24 '11 at 11:47

2 Answers2

1

Firstly, you cannot ask too many questions on SO. That's what the site exists for, no questions = no answers = no SO. :)

Your usermapper class could have $user and $userProfile properties and a register() method. The register method then accesses the methods it needs from these tables. The example code below is basic and won't work as is, but it gives you the genearal idea.

Rather than inheriting the properties and methods of one class this uses composition to give access to multiple classes. In other words this class 'has' Zend_Db_Tables rather than 'is a' Zend_Db_Table. Hopefully the difference is clear and you can see some advantage to working this way.

In your controller:-

public function indexAction() {
    $userMapper = new Application_Model_Usermapper();
    $userMapper->register($username, $password, $email, $etc);
}

In your model (I haven't got around to using name spacing yet, sorry):-

class Application_Model_Usermapper
{
    private $user;
    private $userProfile;

    public function __construct()
    {
        $config = array(
            'name'      => 'userTable',
            'primary'   => 'userid'
        );
        $this->user = new Zend_Db_Table($config);

        $config = array(
            'name'      => 'userProfileTable',
            'primary'   => 'userid'
        );
        $this->userProfile = new Zend_Db_Table($config);
    }

    public function register($username, $password, $email, $etc)
    {
        $this->user->insert($userdata);
        $this->userProfile->insert($userProfileData);
    }  
}
vascowhite
  • 18,120
  • 9
  • 61
  • 77
  • Cool, thanks for that. I created new instance sof the Application_Model_DBTable things I made instead. Does this cover my transactional queries etc? I spent alot of time in my old application making sure everything worked like that and feel like I'm backtracking if it doesn't :/ – creamcheese Oct 31 '11 at 21:29
  • [Have a look at this](http://framework.zend.com/manual/1.11/en/zend.db.adapter.html#zend.db.adapter.transactions) – vascowhite Nov 01 '11 at 20:20
0

Your Mapper Class needs to talk to multiple tables, so you need multiple set/getDbTable methods, eg:

public function setUserDbTable($dbTable) {}    
public function getUserDbTable() {}

public function setUserProfileDbTable($dbTable) {}    
public function getUserProfileDbTable() {}

Then in your other methods, you can use the appropriate table, eg:

$this->getUserDbTable()->insert($userData);
$this->getUserProfileDbTable()->insert($userProfileData);

And similar for the other interactions in the other methods.

ChrisA
  • 2,091
  • 1
  • 14
  • 23