10 months ago by: matt

This is a continuation/update from my Phalcon PHP route model binding post. My pull request has since been merged and made its way into Phalcon 3.0.0. This is taken from the documentation I wrote for this feature here.


From 3.0.x onwards the dispatcher comes with an option to handle this internally for all models passed into a controller action.

use Phalcon\Mvc\Dispatcher;

$dispatcher = new Dispatcher();

$dispatcher->setModelBinding(true);

return $dispatcher;

It also introduces a new interface Phalcon\Mvc\Controller\BindModelInterface which allows you to define the controllers associated model to allow model binding in base controllers.

For example, you have a base CrudController which your PostsController extends from. Your CrudController looks something like this:

use Phalcon\Mvc\Controller;
use Phalcon\Mvc\Model;

class CrudController extends Controller
{
    /**
     * Show action
     *
     * @param Model $model
     */
    public function showAction(Model $model)
    {
        $this->view->model = $model;
    }
}

In your PostsController you need to define which model the controller is associated with. This is done by implementing the Phalcon\Mvc\Controller\BindModelInterface which will add the getModelName() method from which you can return the model name.

use Phalcon\Mvc\Controller\BindModelInterface;
use Models\Posts;

class PostsController extends CrudController implements BindModelInterface
{
    public static function getModelName()
    {
        return Posts::class;
    }
}

By declaring the model associated with the PostsController the dispatcher can check the controller for thegetModelName() method before passing the defined model into the parent show action.

If your project structure does not use any parent controller you can of course still bind the model directly into the controller action:

use Phalcon\Mvc\Controller;
use Models\Posts;

class PostsController extends Controller
{
    /**
     * Shows posts
     *
     * @param Posts $post
     */
    public function showAction(Posts $post)
    {
        $this->view->post = $post;
    }
}
Currently the dispatchers internal model binding will only use the models primary key to perform afindFirst() on. An example route for the above would be /posts/show/{1}