4

Lets say I am building an OOP-based user authentication system, and I would like to incorporate the following principles: Direct Injection, Inheritance, Encapsulation, Polymorphism and the Single Responsibility Principle.

My background in programming is has always relied on procedural programming, and thus, am finding it difficult to really put these practices into correct use.

Assume I have these classes:

class Config
{
    public function set($key, $value);
    public function get($key, $default = null);
}

class User
{
    public function __construct(PDO $dbh, $id = null);
    public function setProfile(Profile $profile);
}

class Auth
{
    public function __construct(Config $config);
    public function login($username, $password, $keepLoggedIn = true);
    public function isLoggedIn();
    public function getLoggedInUser();
    public function logout();
    public function register(array $data);
}

class Session
{
    public function start($sessionName = null);
    public function write($key, $value);
    public function read($key, $default = null);
}

class Profile
{
    public function setAddress(Address $address);
    public function setName($name);
    public function setDOB(DateTime $date);
    public function getAge();
}

class Validator
{
    public function validate($input);
}

I have intentionally left off the function bodies to keep things simple.

To the best of my knowledge, I believe I'm using the principles correctly. However, I am still unclear as to how you would connect classes like: the Validator to the User model, the User model to the Auth and the Session to the Auth class. All of which depend on each other.

1 Answer 1

2

You are on the right track. The way these classes connect to each other is called extending. I tend to go towards an MVC setup, meaning Model, View, Controller.

Your logic goes into the controller, all your DB queries and concrete back end methods go in the model. The controller receives requests and returns responses. It's the middleman. It talks to the back end after a request has been made to it, and feeds the front in via response.

So you have a core controller (keep it bare minimal), then each class you make extends the core controller. So your controller is where you tie all this together.

 <?php
//your main core controller, where you load all these things you need avilable, so long as this class is extended
class CoreController {

    public $auth
    public $session;
    public $view;

   function construct__ ()
   {
       $this->auth = instantiateAuthClassHere();
       $this->session = instantiateSessionClassHere();
       $this->view = instantiateViewClassHere();
   }

    public function anotherHelperForSomething(){
        //helper stuff for this method    
    }
}

//index, page, or content controller, depending on how many you need, i.e. if you want a controller for each page, thats fine, e.g indexController, etc..
//this is the middle man, has logic, receives requst, returns response to view.
class Controller extends CoreController {

    public function index (){

        $userModel = new userModel();

        //do something with this
        $session = $this->session;

        $content = 'some html';
        $userInfo = $userModel->getUsers();

        $view = $this->view->render( array(
            'content' => $content,
            'userInfo' => $userInfo,
        ));

        return $view;
    }
}

//Core LIbraries
class Validator {
    //your validator stuff
}

//Core LIbraries
class Session {
    //your validator stuff
}

//Core LIbraries
class Auth {
    //your validator stuff
}

class CoreModel{

    public $validator;

    function __construct(){
        $this->validator = instantiateValidatorClassHere();
    }
}

//a user model  class (back end). you want a model class for each db table pretty much. 
class UserModel extends CoreModel {


// if you need the validator anywhere inside this class, its globally available here inside any class that extends the CoreModel, e.g.  $this->validator->methodName()


    public function getUsers (){
        $sql = 'SELECT * from users';
        $result = $db->get($sql);

        return $result;
    }
}

Notice, on the Controller, this is a generic name for something like indexController, or anything custom. Also, I have the word extends there. It inherits all the objects from the parent that it extends. Inside it, now they will be available via $this->. See my example where I get $this->session.

Try to avoid constructs - you probably don't need them anywhere except for the core, and under special circumstances, which you might then need to check for yourself before you do even that. I dont use constructs much anymore. It can be a bit clunky and unmanageable.

Sign up to request clarification or add additional context in comments.

16 Comments

I like this pattern it simplifies things significantly, but what about the Model? The Model is responsible for validating it's own data.
hi, i added the model in there, on an edit.. ok, i think i see you have a need for the validate class in teh model, not the index controller, so we can also make a core model controller how would that be? ok, i updated that..
Hey, from my point of view, using the MVC pattern would prevent classes from being reused. For example, moving validation logic for the User model into the controller, would also mean I cannot ever reuse the model outside of my application and even to a certain extent, inside my own application.
well, the model is only for your application, not another. this is the applications model.. yes it prevents classes from being rewritten.. yes validation logic for user prob should go in controller, not model. good thinking, your on the correct track. think of it like a business model, only for one buiness.
This has nothing to do with MVC and neither does OPs question. Also you are tightly coupling everything in your classes by instantiating everything inside the classes. You loose encapsulation by making everything public. Your GodModeController instantiates things it might not even need. Your comment about "Try to avoid constructs" makes no sense whatsoever. I feel bad for @NathanBishop that he thinks this answer will actually make his code better in some way.
|

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.