PHP DAO classes inherit from a generic DAO classes and only change the table name
If the only difference between subclasses of DAO_DBRecord is the table name I wouldn't use subclasses. I'd just pass the table name to to the constructor of DAO_DBRecord and use different instances for different tables.

If the only difference between subclasses of DAO_DBRecord is the table name I would pass the name of the table to the constructor of the parent class:

class UserDao extends DAO_DBRecord {

    public function __construct($db) {
        parent::__construct($db, 'users');
    }
}


Having different classes improves type safety. In Java you can't pass a UserDao to a method with an ArticleDao parameter(1), it does not compile. I don't know whether this kind of type safety exists in PHP or not, but it could be a good practice and could results more readable code.

(1) Of course except if UserDao is a subclass of ArticleDao



I don't feel that making DAO_DBRecord class abstract would make a big difference. If your clients wants to misuse the class they can create a dummy (non-abstract) subclass for that:

class AnyDao extends DAO_DBRecord {

    public function __construct($db, $tableName) {
        parent::__construct($db, $tableName);
    }
}


If you want to protect DAO_DBRecord from instantiation with unknown table names make its constructor private and create static factory functions for your tables inside the DAO_DBRecord:

class DAO_DBrecord {
        private $db;
        private $tableName;

        private function __construct($db, $tableName) {
            $this-&gt;db = $db;
            $this-&gt;tableName = $tableName;
        }

        public static function createUserDao($db) {
            return new DAO_DBrecord($db, 'users');
        }

        public static function createArticleDao($db) {
            return new DAO_DBrecord($db, 'articles');
        }
        ...
}


So, DAO_DBrecord cannot be used with other tables.



If you use your table names only once creating constants for them looks unnecessary in this case.