PHP MVC. Am I doing it right?

I created a simple ServiceFactory class that starts other service classes and stores and receives instances. The same ServiceFactory object is used for both the View object and the Controller object.

The controller changes the state of the service:

class User extends Controller
{
    public function index($user)
    {
        $userService = $this->service->run('User');

        $userService->index($user);
    }
}

      

The View receives data from the Service and decides which template to use:

class User extends View
{
    public function index()
    {
        $userService = $this->service->get('User');

        $this->data = $userService->data;

        $this->template = 'user/index'; // render
    }
}

      

Am I doing it right?

In this answer, tereΕ‘ko said that: "The Controller is responsible for changing the state of both the View and the Model." My controller has nothing to do with the view. I would like to see some examples of how Controller and View (Model2 MVC) should work.

+3


source to share


2 answers


Am I doing it right?

Sorting.

Let's start with extends

. When you use extends

, you mean an is-a relationship , so when you say User

extends Controller

, you say User

a Controller

. This is true? Not. Maybe you can rename to UserController

and it will make sense in context.

$userService = $this->service->get('User');

      

This is called a service locator and is well known as an anti-pattern . Why is it an anti-pattern? Because in object-oriented programming, every public method of an object is an API to use it, and you should be able to fully see the requirements for objects from its constructor and method signatures.

With your code, the developer has to read everything to see "oh, so here where I use another object" and further "here where I use another".

Your code should look like this:

public function index(UserService $userService)
{
    $user = $userService->getData();
}

      



With this code change, developers can see which external objects your object should use - and now it can be checked (not that you would check your controllers that do not contain logic - this is just a "glue" for your code, already tested ).

You should inject components and a view into the controller:

class UserController extends Controller
{
    public function index(UserService $userService, View $view)
    {
        /** This or something similar **/
        return $view->render($userService->getData());
    }
}

      

Some people type View

, some people type TemplateEngine

like a twig and call render

that with data. It is up to you, you can get into particulars given your current scenario.

If you're wondering how you would inject your custom service into the index action, then defining a dependency injector like Auryn that uses reflection to read the constructor of objects or method signatures to determine what to create before automatically injecting them into your controllers.

Laravel stole this idea and now it's implemented for their controllers, hopefully Symfony will follow soon.

Final note. Don't try to stick strictly to "MVC" - this is not possible in the classic sense for PHP with a request -> response -> dead cycle. Instead, focus on separating the associated concerns and making your code usable, testable, and easy to read.

+2


source


There is a problem in client-server architecture to implement the "original" MVC idea. In theory, the Controller should modify the Model. Than the model should like, for example, an event with the "Refresh" view.



Example: I am changing the state of a user eg. first button press. This results in an action in the controller that updates the User-Model (the domain model that lives in the model layer). The model should now "create" the view to update the first username. You can use the "commet" architecture ( https://en.wikipedia.org/wiki/Comet_%28programming%29 ) to link the model to the view. Thus, updating the User-Model will update the view.

0


source







All Articles