Creating a model record for a database I'm trying to expand my use of classes and better understand how/when to use them. Please review the code and let me know if I'm on the right track or where I need to make improvements. For example, should I remove the database call from the class, why or why not?

&lt;?php
class Model{

    private $_db;

    private $first;
    private $last;
    private $gender;
    private $birthYear;
    private $agency;
    private $picture;

    public function __construct($db){
        $this-&gt;_db = $db;
    }

    public function __get($property) {
        if (property_exists($this, $property)) {
            return $this-&gt;$property;
        }
    }

    public function __set($property, $value) {
        if (property_exists($this, $property)) {
            $this-&gt;$property = $value;
        }

        return $this;
    }

    public function add_model(){
        $statement = $this-&gt;_db-&gt;prepare("insert into models (first_name, last_name, gender, birth_year, agency, picture) values (:first, :last, :gender, :birth_year, :agency, :picture)ON DUPLICATE KEY UPDATE gender = VALUES(gender), birth_year=VALUES(birth_year), agency=VALUES(agency), picture=VALUES(picture)");

        $statement-&gt;bindParam(':first', $this-&gt;first);
        $statement-&gt;bindParam(':last', $this-&gt;last);
        $statement-&gt;bindParam(':gender', $this-&gt;gender);
        $statement-&gt;bindParam(':birth_year', $this-&gt;birthYear);
        $statement-&gt;bindParam(':agency', $this-&gt;agency);
        $statement-&gt;bindParam(':picture', $this-&gt;picture);

        $result = $statement-&gt;execute();
        if ($result){
            return true;
        } else {
            return false;
        }
    }

}
?&gt;
Your model should not know anything about how it gets created, that is what a repository is for. What if at some point in the future you changed from a database to a REST API? Now all of your models are invalid. If you use a repository, you could just add a new repository for the new API and the models are none-the-wiser. 

So your model should just be this (notice I changed the name of the class, you should use descriptive names):

class PersonModel{

    private $first;
    private $last;
    private $gender;
    private $birthYear;
    private $agency;
    private $picture;

    public function __get($property) {
        if (property_exists($this, $property)) {
            return $this-&gt;$property;
        }
    }

    public function __set($property, $value) {
        if (property_exists($this, $property)) {
            $this-&gt;$property = $value;
        }
        return $this;
    }
}


And then you have a repository:

class PersonRepository {

    private $_db;

    public function __construct($db){
        $this-&gt;_db = $db;
    }

    public function create($person){
        $statement = $this-&gt;_db-&gt;prepare("insert into models (first_name, last_name, gender, birth_year, agency, picture) values (:first, :last, :gender, :birth_year, :agency, :picture)ON DUPLICATE KEY UPDATE gender = VALUES(gender), birth_year=VALUES(birth_year), agency=VALUES(agency), picture=VALUES(picture)");

        $statement-&gt;bindParam(':first', $person-&gt;first);
        $statement-&gt;bindParam(':last', $person-&gt;last);
        $statement-&gt;bindParam(':gender', $person-&gt;gender);
        $statement-&gt;bindParam(':birth_year', $person-&gt;birthYear);
        $statement-&gt;bindParam(':agency', $person-&gt;agency);
        $statement-&gt;bindParam(':picture', $person-&gt;picture);

        $result = $statement-&gt;execute();
        if ($result){
            return true;
        } else {
            return false;
        }
    }

    public function read($id) {
        //...
    }

    public function list() {
        //...
    }

    public function update($person) {
        //...
    }

    public function delete($person) {
        //...
    }
}


This keeps your database layer separate from your data layer and separate from your presentation layer. The more separation you can do here, the better off you are going to be when it comes to updating and maintaining this code.

I would recommend a good read through SOLID principles to get an idea.