5

First off, I do not have anything against OO programming (I'd be mad if i believed so). But I was thinking on some sort of procedural MVC pattern with PHP; let me explain better.

As we all know, variable scopes, unless they are taken from $_SESSION (, database, redis, etc.) are never global and only refer to a singular execution of a script. For example:

class Car {
  this->name = "foo";
  function setName($name) { ... }
  function getName() { return $this->name; }
}

Where obviously in a more common situation, this data will be taken from the DB, otherwise any object car, per execution, would have the same name.

Now, is it not possible to apply MVC pattern on procedural code for simplicity purpose? Imagine a really simple social network like application; I could have a structure like this

*views
  -profileview.php
  -messageview.php
  -loginview.php
  -notloggedin.php
*models
  -user.php
  -message.php
- profile.php
- messages.php
- login.php

where profile, messages and login.php work as controllers and route to the right view; and user and message.php work as the classes, that contain all the functions that are eventually needed by the controllers, such as getUserById($id), postMessage($id, $meesage), etc.

I have simplified it a lot but I think you can sort of understand my point.

What would you think of such implementation on the long run, and why?

0

4 Answers 4

3

I won't argue with Stephen, even though I could. ;)

Basically, if you want to go with MVC on your own, you'll need at least a request dispatcher and probably a view resolver along with some configuration facilities.

As procedural PHP has no real support for types, coupling problems will probably be a PITA.

In a most basic scenario you could just have a request mapping like

$mapping = array(
    "show_profile" => "profile.php:showProfile",
    "edit_profile" => "profile.php:editProfile",
    "etc" => "whatever.php:doEtc"
);

and then just retrieve the correct setting and explode it to $fileToInclude and $functionToCall. There you'll have your controller-problem sorted out (passing some generalized $request parameter to them or so).

As for a very simple run, your controller could do whatever it should and then explicitly inlcude the view file or return some data so that the view resolver can be invoked with the identifier (e.g. file path or mapping key) of the view to render and the data to display.

There are serveral approaches, and the above one is not even close to an elegant solution (heck, we're talking about procedural code :D) but this is the most simple clean-ish variation I can think of; you can extend on it as you please.

Keep in mind that you want to keep your code as decopuled and maintainable as possible. (A hard way would be to create a framework with which you could use arbitrary code as controller with arbitrary functions and parameters; the easiest one is simply a matter of some explicit includes)

PS.: I'd suggest using existing frameworks for that matter, but the only publicly available PHP frameworks that are viable are all OO and mixing up OOP with procedural code would be a terrible practice; even worse than reinventing your wheels. Actually, if you don't have to stay procedural at all cost, you better switch to OO.

Good luck with your project!

0

It's very subjective, but why would you choose to do it "this way" rather than adopt a real framework for the purpose? If it's just to learn something new, I can see the value in it, but there's been hundreds if not thousands of man-hours invested into developing the current crop of PHP MVC frameworks, and even the worst of them is likely to be better than doing it this way.

As a stepping stone towards using a real framework, this is a good start - because it encourages the separation of concerns - but as an end result? It's awful.

2
  • you are absolutely right, but what I meant to say is something more "general", so let me make an absurd proposal: suppose codeingniter guys decide to go procedural. with the elements that I am considering in my question, would that be programming suicide or there might also be good sides on using procedural?
    – john smith
    Commented Jan 24, 2013 at 12:50
  • What you're proposing could work, but would require more babysitting and a lot more effort than the alternative MVC framework-based solution. I've had to work with a lot of procedural code in the past, some of it particularly awful in places, and I'm not going back :)
    – Steve Hill
    Commented Jan 24, 2013 at 13:38
0

You can build a house out of mud but it's much easier when you have boards, nails, and other useful domain objects available.

To expand on this a bit, the reasons object oriented programming is better suited for this task than procedural programming are the same reasons object oriented programming is better at most tasks:

  • Reuse.
  • Polymorphism increases expressiveness.
  • It better models the real world and human thought processes.
  • Increases cohesion.
  • Reduces coupling.
  • Better mechanisms for encapsulation and information hiding.

All of these are debatable but none of them are especially new.

-1

There is no benefit to doing it this way, there is only pain and suffering. The MVC paradigm was largely invented to move away from doing it in a linear one-way-street fashion. What you'll wind up with is a tangled mess that fast approaches zero flexibility as you add to it over time.

If you're making your own framework, consider:

  • Having a front-controller
  • Representing the request as a singleton
  • Representing controllers as singletons
  • Delegating work to subcontrollers
  • Have your controllers return a View back up the call chain, allowing each controller to modify (or replace) it.

This strategy will grant you some mega flexibility with very little code.

The following is a very basic proof of concept. You would obviously want to flesh out the controllers to account for 404's, sanitize $_SERVER['REQUEST_URI'], etc.

abstract class Request {
    public $tokens;
    final private function __construct() { } // static singleton
}

abstract class View {
    abstract function render();
}

class MyView extends View {
    function render() {
        echo 'Hello, world.';
    }
}

class MyTheme extends View {
    public $content; // nested View
    function render() {
        echo '<h1>Themed</h1>';
        $this->content->render();
    }
}

abstract class Controller {
    final private function __construct() { } // static singleton
    abstract static function route(); // inspect the request and handle it locally,
                               // or send it to a subcontroller
}

abstract class FrontController extends Controller {
    static function route() {
        // inspect current(Request::$tokens) and decide to send it elsewhere
        next(Request::$tokens);
        $themed = new MyTheme();
        $themed->content = MySubController::route();
        return $themed;
    }
}

abstract class MySubController extends Controller {
    static function route() {
        return new MyView();
    }
}

/* in the script that invokes your front controller */
Request::$tokens = explode('/',$_SERVER['REQUEST_URI']);
FrontController::route()->render();

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.