I’d put them in a new directory called /dao. Thus you’ll always now where they are, you’ll keep your controllers and models “thin” (and if you ever recreate them, there will be only a few lines to carry over) and they’ll be as reusable as you whish.
Go to the /config/main.php and add the new directory to the import section.
In theory your daos shouldn’t inherit from anything… it’s custom code. They should be called from the controllers and they’ll use the models to access the db. As you have more and more daos i guess you’ll have some common functionality you will want to extract to a super class. Or maybe you will use some functionality provided by a yii class so you’ll end up inheriting from it, but it’s completely up to you.
There’s no theory against inheriting (although object composition is preferred to inheritance according to software gurus). A DAO is just a layer to abstract from a DB access concrete API. AFAIK, the DAO pattern should be something like this:
interface UserDao
{
public function saveUser( $user );
}
class UserDaoImpl implements UserDao
{
public function saveUser( $user )
{
$user->save();
}
}
And lately I’m becoming a big fan of factories: they allow for easy switching between implementations, so I’d go on with something like this:
// This can be implemented as a singleton or make the methods static.
// I usually go for the former: static methods are tougher to change
class DaoFactory
{
// I'd implement the factory as a singleton. I'll avoid such a code.
static public function getFactory()
{
(...)
}
/**
* @returns UserDao THIS METHOD SHOULD RETURN THE INTERFACE
*/
public function getUserDao()
{
// You can use a singleton too if you whish,
// or return a new instance every time it's invoked
return new UserDaoImpl;
}
}
And finally in your controller
public function actionCreate()
{
$user = new User;
$user = $_POST['user'];
$userDao = DaoFactory::getFactory()->getUserDao();
$userDao->saveUser( $user );
}
It’s just some simplified code, but I think you can get the idea…
Yii DAO mainly consists of the following four classes:
CDbConnection: represents a connection to a database.
CDbCommand: represents an SQL statement to execute against a database.
CDbDataReader: represents a forward-only stream of rows from a query result set.
CDbTransaction: represents a DB transaction.
DAO stands for Database Access Object, so any code that serves for that purpose may be considered a DAO. Of course Yii has it’s own methods to do it, but the aim of applying a DAO pattern is to abstract your code from Yii’s (or any particular framework) methods. In my previous code, if you ever change your framework or you want to use the methods from CDbCommand, CDbConnection and so on instead of CActiveRecord methods, changing the code in YOUR daos will be enough, instead of changing any Yii custom methods scattered around your code.