Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting familiar with MVC - how do I work with session logic, additional classes and background logic

While coding PHP, I decided to move from spaghetti code and try to implement MVC. To implement the MVC framework, I vent to this article Article gave a good start and I managed to create my site, and develop the front-end. Now, I am trying to implement the back-end using sessions and other member-area features. My brain is boiling with new information and I have more questions than answers.

I don't know how to implement additional classes, user class for example. For example, without MVC I could create new user.php class file in my includes directory, then include it, instantiate it, and assign appropriate values to the object and place objest into session.

I would like to ask for an expret advise.

I am confused about many things:

  • where do I add the user class
  • how do I add and include user class to my MVC
  • how do I carry user class around my application (I understand in session, but session must have an acees to user object
  • how do I perform login / logout logic and perform required actions that are taking place in the backgroud

It is probaly a common problem that is not complex once it has been done before. I also apologize for not very good defined question, but I appreciate your help in advance.

like image 266
Andrew Avatar asked Dec 01 '22 19:12

Andrew


2 Answers

User, context of MVC, is a domain object. However the session is a form of storage medium (just like cache, db or file-system). When you need to store data from User instance there, you use some type of data mapper to do it.

$user = $this->domainObjectFactory->build('user');
$user->setName('Korben')
     ->setSurname('Dallas');

if ( some_condition )
{
    $mapper = $this->dataMapperFactory->create('session');
    $mapper->store($user);
}

This code should provide an extremely simplified example for interaction between session and user.

Where do I add the user class?

As a domain object, the User instances should be used inside services and initialized using factories. In context of MVC, the services are structures in model layer, which deal with application logic. They manipulate and facilitate the interaction of domain object and storage abstractions.

How do I add and include user class to my MVC?

All of your classes should be added using autoloader. You should read about use of spl_autoload_register(), preferably while using namespaces.

The initialization of instance itself should be done by a factory. That lets you decouple your code from the class name of said instance.

How do I carry user class around my application?

You don't.

PHP applications do not persists. You have an HTTP request, yo do all the things you need with it, the response is sent and application is destroyed. The instances of User class will all be short-lived.

To recover the current user between requests you store an identifier in session. Do not dump whole objects in session. Instead, after you fetch user's identifier from session, you can recover the rest of user account details from other forms of storage (if you even need it).

This whole process should be preformed and managed by some sort of "recognition service" or "authentication service" from your model layer.

How do I perform login / logout logic and perform required actions?

The login request is at first handled by controller:

public function postLogin( $request )
{
    $service = $this->serviceFactory->create('recognition');
    $service->authenticate( $request->getParameter('username'),
                            $request->getParameter('password') );
}

The service tries to verify the user's credentials, which alters the state of model layer. The view instance then looks up that state and either redirects you to the landing page as authenticated user, or redirects you back to login page with an error message.

The service themselves would be shared between model controller and view via the factory. Which means that they would initialize each service only once and then just reuse it. Something along the lines of:

class ServiceFactory
{
    private $cache = array();

    public function create( $name )
    {
        if ( array_key_exists($name, $this->cache) === false )
        {
            $this->cache[$name] = new $name;
        }
        return $this->cache[$name];
    }
}

Just keep in mind that his is an extremely simplified example.

For further reading I would recommend you to go through this collection of links. Also, you might find these 3 posts somewhat useful: this, this and this.

like image 163
tereško Avatar answered Dec 28 '22 04:12

tereško


So you've got a lot of questions here, let's review them briefly:

  • where do I add the user class
  • how do I add and include user class to my MVC
  • how do I carry user class around my application (I understand in session, but session must have an acees to user object
  • how do I perform login / logout logic and perform required actions that are taking place in the background

As you can imagine we can not answer those questions technically on Stackoverflow. There would not be much use for future users of your question and also we just don't want to give simple answers.

But if you look through the list of your questions there are some prominent points you ask about:

  • Where are objects created?
  • How are objects passed through my application?

And also already an answer: "In the Model" (not to these two points I just listed, but for some of your questions).

So first of all, the Model is a layer in MVC. And a layer is a specific area in your application taking care of (normally a more high-level) job in it's flow. In your example, the User is part of the Model. See the Pasta Theory of Software for a description how you can organize code in a software program, this should make clear why to use layers - apart from MVC in specific. But in MVC, the answer is clear: in the Model.

As this answer is that obvious, it makes me wonder a little how the tutorial you've followed could have missed that. And has you left alone with such elementary questions of software design like:

  • Where are objects created?
  • How are objects passed through my application?

Because these two questions are pretty existential for any software that uses objects, not even those that are specifically object-oriented.

So let's just keep it straight forward and answer those two questions: For MVC you might create yourself some high level routines that form a framework you build your application in. Basically this means, you are creating a library. A library is used by someone. That someone should decide where objects are created. The framework / library should not dictate where to create objects nor should it create objects for the user. So this questions needs to be answered by the consumer of your framework not by the framework author. So to handle this properly you need to split yourself in two and on the one hand take the role of the coder of the library and on the other hand take the role of the coder writing an application with the library.

I can only stress this very simple but fundamental point: When you write some library software / framework, do not dictate where to create objects. Just provide tests that proof your library working without any application around and then when you write the application just include the library and use it.

The second questions you ask is How are objects passed through my application?. Taking a quick look into the tutorial you've linked you can already see that my general advice given above is not followed (which is crucial to rapid development btw. so don't get yourself misguided by the tutorial's title: with such complicated code it offers, only the very first hour has gone quick and it has paved the road to complicated development only) but also that the tutorial's example code are not a helpful example in showing an answer to the question how to pass objects around in an application. It misses to explain a very simple but effective method to do that: Dependency Injection.

So don't just take a single tutorial for granted. The one you've chosen merely shows the following things:

  • The author thinks it is worth to re-invent URL parsing. This is plain code-masturbation because PHP has this build-in.
  • The author thinks it is worth to not validate input values and is shortsighted to even think about the importance of preventing code injection. This is really sad.

And as the last point is a total no-go, I highly suggest you to drop anything you've taken so far from these examples and try the next one. Just keep in mind that a libraries user need to decide where and when to create objects (that means the librarie(s) used need to allow this, always) and that you use dependency injection to pass objects through the object graph you use in your application.

like image 20
hakre Avatar answered Dec 28 '22 04:12

hakre