MVC Relationships and DRY

2019-09-07 08:24发布

问题:

I am trying to create a user login system.

I have a class/controller called AccessControl which includes all the functions for creating, deleting and logging a user in and out.

I also have a model called Users which has all the database functions in it which are called from the AccessControl class.

My AccessControl class:

include_once('../models/User.php') ;

class AccessControl {
private $_systemKey ;

public function __construct()
{
    $this->_systemKey = 'QA>8fg)@z#t#:E60mj&MzHsm-lUj&b-}R%~<y$|nAuF)C3!r%+rT"Q<r$o?{_XR' ;
}

public function createUser($email, $password, $level)
{           
    $user_salt = $this->randomString() ;

    $password = $user_salt . $password ;
    $password = $this->hashData($password) ;

    if(!is_int($level))
    {
        return false ;
    }

    //Create verification code
    $code = $this->randomString() ;

    //SQL...
    $created = User->insertNewUser($email, $password, $level) ;

    if($created != false){
        return true; 
    }

    return false ;
}
}

And in my model:

class User extends Core {

public function fetchSalt($username)
{
    $result = $this->db->prepare("SELECT saltword FROM users WHERE username = ?") ;
    $result->execute(array($username)) ;
    return $result->fetchColumn() ;
}

public function insertNewUser($email, $password, $level)
{
    //SQL Insert...
}

}

I am not sure if I am doing this the right way, because aren't createUser and insertNewUser identical? How can I change things to make it DRY?


Core is just my PDO connection class, all my models will extend from it. That's the plan anyway.

abstract class Core {
protected $db ;

function __construct()
{
    try{
        $this->db = new PDO("mysql:host=localhost;dbname=database", "user", "pass") ;
        $this->db->exec('set names utf8') ;
                    $this->db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
        $this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
        $this->db->setAttribute(PDO::ATTR_PERSISTENT, TRUE) ;
    }
    catch(PDOEXCEPTION $e)
    {
        echo 'Database error: <i style="color:#993300;">'.$e.'</i>' ;
        die() ;
    }
}

function __destruct()
{
    $this->db = NULL ;
}
}

回答1:

Generally if you want to keep the code duplication to a minimum in this scenario I would advice you to not have each model handle the database work.

Instead you can have a gateway for each model that accepts and returns models. Usually for simple retrieval, inserting, removing and updating the queries will not differ much. All the common code can be in an AbstractGateway all the other Gateways extend from. The specific gateways just handle the model specific things then, like defining the table to use or the model to return.

You also get some added benefits from this. You can easily swap out the database gateway for another storage gateway. That way you can even test your code without having to worry about the database connection.

As for the create and insert user methods I don't see a problem there. From an MVC standpoint the createUser method is a method of the Controller and for the action you are performing it calls a method of the Model.