I am new into Phalcon framework. I just got the basic idea about it. Every controller has methods with multiple specific actions. I wrote a huge indexAction method but now I want to break it down with multiple private method so that I can reuse those functionality. But when I try to create any method without action suffix, it returns error(Page Not Found). How can I break it down into multiple methods?
<?php
use Phalcon\Mvc\Controller;
class PostsController extends Controller
{
public function indexAction()
{
$this->someMethod();
}
public function someMethod()
{
//do your things
}
}
Controllers must have the suffix “Controller” while actions the suffix “Action”. A sample of a controller is as follows:
<?php
use Phalcon\Mvc\Controller;
class PostsController extends Controller
{
public function indexAction()
{
}
public function showAction($year, $postTitle)
{
}
}
For calling another method, you would use it straight forward
<?php
use Phalcon\Mvc\Controller;
class PostsController extends Controller
{
public function indexAction()
{
echo $this->showAction();
}
private function showAction()
{
return "show";
}
}
Docs.
What exactly do you want? The answer seems trivial to me.
class YourController extends Phalcon\Mvc\Controller
{
// this method can be called externally because it has the "Action" suffix
public function indexAction()
{
$this->customStuff('value');
$this->more();
}
// this method is only used inside this controller
private function customStuff($parameter)
{
}
private function more()
{
}
}
Related
I have multiple controllers, with multiple methods, which all return views.
class PageController extends Controller {
public function index()
{
// do lots of stuff
return view('view.name', $lotsOfStuffArray);
}
public function list()
{
//...and so on
}
I now have the need to create an API, which performs much of the same logic as the methods above, but returns a JSON output instead:
class PageApiController extends Controller {
public function index()
{
// do lots of the same stuff
return $lotsOfStuffCollection;
}
public function list()
{
//...and so on
}
What is the best way to accomplish this without having to copy and paste code from one controller to the other?
I've tried placing a lot of the logic into traits and using them in my Eloquent models, but that still requires that I copy and paste code from controller to controller. I should also note its not viable to check expectsJson() and return a response accordingly as I have many, many methods.
Is it a good idea to have the logic stored in a parent class and then create a child controller that responds with a view and a child controller that responds with JSON?
You could abstract the logic to a service class. I have answered a similar question.
You have PageController, PageAPIController and PageService.
class PageService {
public function doStuff()
{
return $stuff;
}
}
class PageController extends Controller {
public function index()
{
$service = new PageService();
$stuff = $service->doStuff();
return $stuff;
}
}
class PageAPIController extends Controller {
public function index()
{
$service = new PageService();
$stuff = $service->doStuff();
return $stuff->toJSON();
}
protected function toJSON(){
//You could also abstract that to a service or a trait.
}
}
contrller:News.php
This is my controller News
<?php class News extends CI_Controller {
public function __construct()
{
}
public function getShowIN_News()
{
return $result;
} } ?>
contrller:Category.php
This is my controller Category
<?php class Category extends CI_Controller {
public function __construct()
{
}
public function category()
{
require('news.php');
$test = new News();
$data["headlines"] = $test->getShowIN_News();
} }?>
By using an empty constructor, you're making it so that CI_Controller::__construct() isn't called, and that's where everything in the framework is initialized.
I know you've put it there to hack it so you can call one controller from another, but it is very intentionally made that way, exactly so you don't do this.
My question is, how can I inherit Controllers action in YII, like:
class MainController extends FController
{
public function ActionIndex()
{
$this->render("index"); //the view;
}
}
--------------------------------------------
class SecondController extends FController
{
public function ActiondIndex()
{
MainController::ActionIndex();
}
}
Actually in my case the SecondController is the DefaultController of a sub-module. I want to make single code based webpage.
Since PHP does not support multiple inheritance, you may access the base class via the parent keyword.
class MainController extends FController
{
public function ActionIndex()
{
$this->render("index"); //the view;
}
}
class SecondController extends FController
{
public function ActionIndex() // Note: you mistyped the name of this action in your example
{
parent::ActionIndex();
}
}
Although you cannot reach the grandparent's ActionIndex method directly, you have to create a workaround for that.
I have this route: Route::controller('/', 'PearsController'); Is it possible in Laravel to get the PearsController to load a method from another controller so the URL doesn't change?
For example:
// route:
Route::controller('/', 'PearsController');
// controllers
class PearsController extends BaseController {
public function getAbc() {
// How do I load ApplesController#getSomething so I can split up
// my methods without changing the url? (retains domain.com/abc)
}
}
class ApplesController extends BaseController {
public function getSomething() {
echo 'It works!'
}
}
You can use (L3 only)
Controller::call('ApplesController#getSomething');
In L4 you can use
$request = Request::create('/apples', 'GET', array());
return Route::dispatch($request)->getContent();
In this case, you have to define a route for ApplesController, something like this
Route::get('/apples', 'ApplesController#getSomething'); // in routes.php
In the array() you can pass arguments if required.
( by neto in Call a controller in Laravel 4 )
Use IoC...
App::make($controller)->{$action}();
Eg:
App::make('HomeController')->getIndex();
and you may also give params
App::make('HomeController')->getIndex($params);
You should not. In MVC, controllers should not 'talk' to each other, if they have to share 'data' they should do it using a model, wich is the type of class responsible for data sharing in your app. Look:
// route:
Route::controller('/', 'PearsController');
// controllers
class PearsController extends BaseController {
public function getAbc()
{
$something = new MySomethingModel;
$this->commonFunction();
echo $something->getSomething();
}
}
class ApplesController extends BaseController {
public function showSomething()
{
$something = new MySomethingModel;
$this->commonFunction();
echo $something->getSomething();
}
}
class MySomethingModel {
public function getSomething()
{
return 'It works!';
}
}
EDIT
What you can do instead is to use BaseController to create common functions to be shared by all your controllers. Take a look at commonFunction in BaseController and how it's used in the two controllers.
abstract class BaseController extends Controller {
public function commonFunction()
{
// will do common things
}
}
class PearsController extends BaseController {
public function getAbc()
{
return $this->commonFunction();
}
}
class ApplesController extends BaseController {
public function showSomething()
{
return $this->commonFunction();
}
}
if you were in AbcdController and trying to access method public function test() which exists in OtherController you could just do:
$getTests = (new OtherController)->test();
This should work in L5.1
I have two controllers which have some actions that are really the same.
How do I refer to the identical action in another controller?
class UserController extends Zend_Controller_Action {
public function listAction() {
//do something here
}
}
class AdminController extends Zend_Controller_Action {
public function listAction() {
//how to call UserController::listAction here?
}
}
What do I put in AdminController::listAction above so that I only have to write the code in UserController::listAction?
thanks
I would use a controller action helper, that way if you ever have to do the same thing again you can reuse it.
class My_Controller_Action_Helper_Whatever
{
public function direct()
{
return $this;
}
public function doSomething($paramA, $paramB)
{
// code
return $whatever;
}
}
Then implement in your controllers:
class UserController extends Zend_Controller_Action
{
public function someAction()
{
$this->getHelper('Whatever')->doSomething($a, $b);
}
}
class AdminController extends Zend_Controller_Action
{
public function anotherAction()
{
$this->getHelper('Whatever')->doSomething($a, $b);
}
}
You could do:
class baseController extends Zend_Controller_Action {
// common controller actions
public function listAction() {
// do stuff
}
}
class AdminController extends baseController {
// admin controller specific actions
}
class UserController extends baseController {
// base controller specific actions
}
You could also forward the request to the other controller by using:
class AdminController extends Zend_Controller_Action {
public function listAction() {
$this->_forward('list','user');
}
}
or if you would prefer the URL to change:
class AdminController extends Zend_Controller_Action {
public function listAction() {
$this->_redirect('/user/list');
}
}
You can forward to another action - simply specify the action, controller, module and params.
Parameters default to values of the current request, i.e. if you're in the default module, the code below will redirect to the listAction of UserController in the default module.
class AdminController extends Zend_Controller_Action {
public function listAction() {
//call UserController::listAction
return $this->_forward('list', 'user');
}
}