2
\$\begingroup\$

I am working on converting a PHP application to MVC, and have a couple questions!

1) I have a main Model object, that I require a database connection for, as well as a User object that uses a database object also. Is it a bad practice to create a new database object for each of these classes, like the following?

or should I create a $databaseObject variable on the index.php page and pass that same variable in as a construct parameter for both User and Model? What is the difference?

Is there anything else that sticks out as something that I am doing wrong?

class Model {

    function __construct() {        
        $this->user = new User();
        $this->db = new Database( DB_TYPE, DB_HOST, DB_NAME, DB_USER, DB_PASS );
    }
}


class User {

    public function getUserId(){        
        return $this->_userid;  
    }

    public function __construct( ){
        $this->db = new Database( DB_TYPE, DB_HOST, DB_NAME, DB_USER, DB_PASS );
        $this->_userid = 1;     
    }
}

Thanks in advance for the help!

\$\endgroup\$
4
  • 3
    \$\begingroup\$ Yes, this is WET code, bad code. Also consider: How Not To Kill Your Testability Using Statics \$\endgroup\$
    – deceze
    Commented Feb 15, 2013 at 20:52
  • 2
    \$\begingroup\$ Model is a layer, that contains multitudes of different instances from different types, not a class or object. Also, you code completely ignores SOLID principles. Is completely untestable and relays on global state for configuration. \$\endgroup\$
    – tereško
    Commented Feb 15, 2013 at 21:05
  • \$\begingroup\$ so I should pass in the database object into the constructor? \$\endgroup\$
    – user1582882
    Commented Feb 15, 2013 at 21:15
  • 2
    \$\begingroup\$ @user1582882 Yes, it's called dependency injection. Also, pass in the userid to the User object. \$\endgroup\$
    – crush
    Commented Feb 15, 2013 at 21:40

1 Answer 1

2
\$\begingroup\$

In general, using the "new" keyword in any class is bad practice, because you're creating an implicit dependency. Instead, you should follow the "ask, don't look" design philosophy and require that the database object be passed to the class, rather than letting the class fetch it. Dependency injection is a common solve to this problem, and I'd recommend looking at how PIMPLE is used. Here's a good article: "Dependency Injection with Pimple".

Many people, like deceze, will deride you (rightfully so) for doing things like this, because it's one of the easiest (and probably most common) things you can do to kill the possibility of testing your code. If you were to write a unit test for this model, you'd have a database object being constructed with each test. Since the whole point of unit tests is to run code in isolation (to verify the tested code's accuracy), it would be impossible to test this model without a database.

On that note, the JavaScript guru, Misko Hevery, published a really superb article on writing testable code: "Top 10 things which make your code hard to test". While this is specifically in the context of code testing, it's also very good general programming information.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.