Mvc For Advanced PHP Developers

MVC for advanced PHP developers

Links, that contain PHP-only materials, are marked with php for easier identification.

You cannot even begin to delve into MVC before you have comprehensive understanding of OOP. That include OOP practices (dependency injection, unit testing, refactoring) principles (SOLID, SoC, CQS, LoD) and common patterns (and no, singleton is not an object-oriented pattern).

MVC is an advanced architectural design pattern, which requires solid understanding. It is not meant for beginners or for tiny "hello world" applications. One uses MVC to add additional constraints to the codebase, when simple adherence to OOP practices becomes too loose to control the codebase.

The best I can suggest for you would be to begin by expanding you knowledge regarding object oriented code:

  • Clean Code I: Arguments
  • Clean Code III: Functions

The two lectures above should cover the basics. And then move on to:

  • Inheritance, Polymorphism, & Testing
  • Unit Testing
  • Global State and Singletons
  • Don't Look For Things!

When you understand all that was explain in this series, you can expand on:

  • Don't be STUPID, Grasp SOLID! php
  • The Principles of Agile Design
  • Advanced OO Patterns (slides) php
  • Beyond Frameworks (slides) php
  • Agility and Quality php
  • Beyond Design Patterns php

Also, I would strongly recommend for you to read (in this order):

  • Design Patterns Explained
  • GUI Architectures
  • Inversion of Control Containers and the Dependency Injection pattern
  • Patterns of Enterprise Application Architecture
  • Domain-Driven Design: Tackling Complexity in the Heart of Software

P.S.: you might also take a look at this book (cautiously, because it has issues): Guide to PHP Design Patterns php

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

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.

Objective oriented design in a PHP MVC Framework

<rant>

If you start out with frameworks that are either direct Rails clones or heavily influenced by Rails architecture, you are not really implementing MVC. Ruby on Rails framework was originally intended to be a purely rapid prototyping framework, which means that they sacrificed most of MVC concepts on "The Altar of Scaffolding".

Rails-based PHP frameworks replace fully functional views with templates, model layer with some collection of active record instance and for the "controller" to deal with all the presentation and application logic.

</rant>

The bases of MVC design pattern is the separation between business logic (contained in model layer) and user interface (managed by presentation layer). These two layers each contains different groups of structure.

The User is not a model. There are no "models" in modern MVC. Instead your User instance is a domain object. Also, it should not be directly exposed to the controllers or other presentation layer structures.

The interaction between presentation layer and model layer should be performed by services. Services in model layer are structures, which are responsible for handling the interaction between domain objects and storage abstractions (either data mappers directly or via repositories and/or units of work).

namespace Controller;

class Authentication
{
// .... snip
public function postLogin( $request )
{
$service = $this->serviceFactory->create('Recognition');
$service->authenticate( $request->getParameter('username'),
$request->getParameter('password') );
}
// .... snip
}

In this case the User instance is somewhere inside the recognition service, which is there to deal with different business-logic aspects of user authentication. And do not confuse it with authorization. For authorization in MVC context there is a bit different recommended approach.

P.S.: if you are just now starting to really delve into OOP, you might find this list useful in your research.

my two cents

Getting started with PHP / MVC

I would suggest you look at the MVC Design Pattern so that you understand it before you start using it.

Ideally, you should already have made some projects where you suffered a little bit because you wanted to change stuff when your project was at least halfway done.(This is one of the main motivators behind a lot of so-called advanced programming techniques. Ease of modification, flexibility and so on).

This is where stuff like what you mentioned (OO,MVC, and I would add TDD, Design Patterns) all come in).

What I do for myself and suggest others do is the following. Look into whatever you want, be it TDD, MVC or any other advanced technique. But wait until you need them.

In my personal opinion, one can much better appreciate the value of OO and MVC when one has gone through a naïve project and suffered from lack of functionality these techniques provide...

The golden rule is.. only start using a new technique when you've understood it and seen what benefits it can bring.

I say that because what I see in real life is that many people use stuff like OO, MVC and even Design Patterns without understanding the why's behind. I don't think that helps at all.

Good luck.

Advance Search in Model (MVC)

Your solution seems to be ok. But you can also use decorator pattern, so you could make the following query:

$shops = new ShopsModel();
$results = $shops->search('name', 'Tadeck')
->order_by('name', 'asc')
->between_dates('2012-02-01', '2012-03-14')
->fetch_all();

PHP MVC Framework Architecture Advice

Well, I'll try to answer the best, I can.

Answer to Q1

Well, that's subjective. If it's how you want to work, then yes it is! What I do different is, that in my htaccess I just pass EVERYTING that's after "http://domain.com/" as a parameter to a get-parameter and then processes the data in my PHP. E.g. like this:

RewriteEngine on

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

RewriteRule (.*) index.php?urlparam=$1 [NC,L,QSA]

And then processes it in PHP:

$_GET['urlparam'];
# Do whatever here. Maybe explode by "/".

This last thing is the routing part. I just make patterns that i match to the URL.

E.g. /advertisements/:id

leads to \Advertisements\Show

Answer to Q2

I am running a load-class, which I call, when I need to load either a view, a model, a plugin or any other file into my controller. In that way I am sure, that the file is only loaded once. The load-model function just returns an object with the model, in that way I have it instantiated and can use it later on.

Answer to Q3

You should probably read some tutorials. I think, that Anant Garg is explaining it very well in this tutorial: http://anantgarg.com/2009/03/13/write-your-own-php-mvc-framework-part-1/

But there is a lot of them "out there":

E.g. this one: http://www.phpro.org/tutorials/Model-View-Controller-MVC.html

Or this one that gives 12 different approaches: http://www.ma-no.org/en/content/index_12-tutorials-for-creating-php5-mvc-framework_1267.php

Hope this helps you a little in the right direction,

Have a nice evening. :)



Related Topics



Leave a reply



Submit