I like the Implicit model binding provided by laravel 5.2, after some work , found could implement this way: route file:
$router->add('/tags/{tag:[0-9]+}/item/{file:[0-9]+}','tags::showItem')->setName('tags.showItem');
for TagsController.php:
public function showItemAction(Tags $tag,Files $file)
{
$this->view->mytag = $tag;
$this->view->page = $tag->getShowItemPage($file);
$this->view->file = $file;
$this->view->form = myForm::buildCommentForm($file->getTaggable($tag)->getFirst());
}
In order to get this, I found the way like this : in dispatch.php
$eventsManager = new \Phalcon\Events\Manager();
$eventsManager->attach("dispatch:beforeDispatchLoop", function($event, \Phalcon\Mvc\Dispatcher $dispatcher){
try{
$reflection = new ReflectionMethod($dispatcher->getControllerClass(), $dispatcher->getActiveMethod());
$actionParams = [];
foreach($reflection->getParameters() as $parameter){
$objectId = $dispatcher->getParam($parameter->name);
if(null == $objectId && $parameter->isDefaultValueAvailable()) $objectId = $parameter->getDefaultValue();
if($parameter->getClass()){
// $className = RouterFacade::getProvider($parameter->getClass()->name);
$className = $parameter->getClass()->name;
if($objectId){
if(is_subclass_of($className,\Phalcon\Mvc\Model::class)){
/** @var \Phalcon\Mvc\Model $className */
$actionParams[$parameter->name] = $className::findFirst($objectId);
}else{
$actionParams[$parameter->name] = new $className($objectId);
}
}else{
$actionParams[$parameter->name] = new $className;
}
}else{
$actionParams[$parameter->name] = $objectId;
}
}
if(count($actionParams)){
$dispatcher->setParams($actionParams);
}
} catch(\Phalcon\Exception $e) {
var_dump($e);
die();
}
});
$dispatcher = new \Phalcon\Mvc\Dispatcher();
$dispatcher->setEventsManager($eventsManager);
return $dispatcher;
It just works like in laravel, if you want to bind interface to some class, you could substitue " $className = $parameter->getClass()->name;" by some function you defined.
What do you think of this method? If you have a better idea, pls comment!