Php MVC + ajax

Thanks for everyone’s input on this! It helped understand implementing ajax better.

I think the main issue i was having was trying to understand the logic of the implementation, and thinking that there was some sort of “standard” or best practice, or that there was a sort of implementation strategy or method that i wasn’t aware of.

Since in the application i am working on, there will be the option to add posts, comments, replies, view posts, etc, and there will be a sort of mixture of them (for example, while viewing the post list, you could click on a button that will load the post form above the list of posts), i think it would be a better approach to have for example one controller for comments, that handles all comments functionalities, including regular and ajax requests.

This is something that has been suggested to me a few times but i guess i was just having a hard time understanding it because i thought that there should be something more than that in order to implement ajax.

The approach to having all ajax requests in a dedicated controller (not 1 controller per method, but all ajax methods inside the same controller) seems in my case like a lot of the same code in multiple places, unless in each method i instantiate the “regular” controller, and use methods from that controller, but i don’t think that’s very efficient, at least in my case.

So, i think i finally understood it! Unless i didn’t…

Thanks for the help with this!

2 Likes

Bringing up this topic again as i am thinking about rewriting my view rendering part of the framework.

Since i want to load full pages as well as partial pages (full page = a page including header, footer, body, etc., partial pages = short html codes e.g. a form, a button), would it be wise to create 2 “rendering” methods?

What i mean by that is something like this (names are examples):

  1. a method called render() = renders the full page
  2. a method called load() = loads just a piece of code from a file (the partial page i mentioned)

The reason i am thinking about doing this is because at the moment i have a renderView() method, and this method loads a full page, what this method also does is to retrieve data for the template (user details, sub nav data, etc.), but for loading just pieces of code, this data is not needed.

So i could either send a setting to the renderView() method saying if this is a full page request or just a piece of a code, and have an if statement in the method that checks this, and based on that decide if to get the template data or not (this is the current set up i have), or i could just have 2 separate methods, one loads a full page, the other loads just a file with html.

Any recommendation on which is better or if there is a solution i’m not thinking of?

It really shouldn’t do that, that’s not its responsibility. What you could do instead is create in interface for some sort of variable loader that could add variables to be added to the variables received for the template.

Something like:

interface VariablesLoader
{
    public function getVariables(): array;
}

class NavVariablesLoader implements VariablesLoader
{
    private $database;

    public function __construct(Database $database)
    {
        $this->database = $database;
    }

    public function getVariables(): array
    {
        $nav = load_nav_from_database($this->database);
        return ['nav' => $nav];
    }
}


class Renderer
{
    private $variableLoaders;

    public function __construct(array $variableLoaders)
    {
        $this->variableLoaders = $variableLoaders;
    }

    public function render(string $template, array $data): string
    {
        foreach ($this->variableLoaders as $variableLoader) {
            $data = array_merge($data, $variableLoader->getVariables());
        }

        ob_start();
        include $template;
        return ob_get_clean();
    }
}

So the renderer has some sort of notion that additional variables may be loaded, but it doesn’t know how, nor should it need to. It probably varies from project to project anyway, so you don’t want to limit it to a known set - it’s prone to change.

Sorry, i may not have been clear about this since two methods have the same name.

renderView($viewData) in the base controller does this:
This method is called by any custom controller that needs to render a view, it receives an array of data from the custom controller that it will pass on the the actual view class.
This is the method that retrieves the template data and user data and adds it to the $viewData array. Then it just instantiates a new View class and passes the $viewData on to it.

render() in the View Class does:
Receives the $viewData array from the controller, which includes which ever file should be loaded, saves that array to its object so that the actual template file can access the data, and then it just includes what ever file needs to be included.

Is this not an efficient way of doing things?

Also, you wrote this:

The way i do it is i just include the actual template file directly in to the render method in the view class, is this wrong? Also, where would you be returning the ob_get_clean() to?

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.