简体   繁体   中英

PHP object oriented database access

I'm new to using the object oriented paradigm with PHP, so I may have missed something obvious.

I have a class Question , with multiple subclasses for different styles of question, instances of which can either be created from the MySQL database or created by the user in a form. However if it's created by the user it won't yet have any of the auto-incrementing IDs that are attached to it in the database.

What's the best way to go about this? I'm unfortunately somewhat stumped.

Should I use a different class for the user-created Question until it's been added to the database? Should I have them be the same class, but with different methods to instantiate them depending on the source? Something else?

First of all, your Question classes should have nothing to do with the database in the first place. They should purely be dumb domain objects, which just hold data and maybe enforce a bit of data validation on it:

class Question {

    protected $title;
    protected $body;

    ...

    public function setTitle($title) {
        if (strlen($title) == 0) {
            throw new InvalidArgumentException(...);
        }
        $this->title = $title;
    }

    public function getTitle() {
        return $this->title;
    }

    ...

}

Depending on your requirements, you make some of these attributes required by requiring them in the constructor. By doing that you ensure that if you have an instance of Question , it has at least the minimal attributes that make it a valid question:

public function __construct($title) {
    $this->setTitle($title);
}

Again, notice that this object has absolutely no concept of what a database is. That's the responsibility of some other class, which has access to a database connector and can read from Question objects to store them in the database and create new Question objects from database data:

class QuestionStore {

    protected $db;

    public function __construct(PDO $db) {
        $this->db = $db;
    }

    public function getQuestion(...) {
        $data = $this->db->query('SELECT ...');

        $question = new Question($data['title']);
        $question->setBody($data['body']);
        return $question;
    }

}

(You can debate about separating those responsibilities further into factories etc, but you get the basic idea.)

How to handle ids then becomes pretty trivial. Either you just make the id one of the non-required attributes of your Question class, so some Question instances have ids and others don't while they haven't yet been saved in the database. Or, if it's somewhat important to your code to distinguish between those two types of questions more easily, make a subtype out of it:

class StoredQuestion extends Question {

    protected $id;

    public function __construct($id, $title) {
        $this->setId($id);
        parent::__construct($title);
    }

    ...

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM