I'm inside a Laravel controller. I only want the init() method to fire once. What actually happens is, it fires every time I run the controller/methods via a browser?
class MyController extends Controller
{
public function __construct()
{
static $init_called = false;
if(!$init_called){
$init_called = true;
$this->init();
}
}
public function init()
{
// initialize code here, execute 'once' only
}
public function routeOne(){}
public function routeTwo(){}
}
One solution is to store a value on session or on database. This value allow you to know if the function has already been called.
Then check the value at the top of the method every time it's is fired.
if it's true you can proceed to the normal instructions else you exit the function.
Since Http is a stateless protocol I'm probably attempting something outside of the realms of possibility. As a workaround, I used the following:-
// Call this route once only
Route::get('/init', [MyController::class, 'init'])->name('initialize');
class MyController extends Controller
{
public function init()
{
MyModel::persistData();
}
}
class MyModel extends Model
{
private $data;
public static function persistData()
{
$data = ['some data'];
MyModel::insert($data);
}
}
Related
class Home extends BaseController
{
var $cache;
public function __contruct()
{
parent::__construct();
$this->cache = \Config\Services::cache();
}
public function reset()
{
$this->cache->clean();
}
}
assume i have create a web cache.
the idea is i dont want to keep assign the same $cache in every method.
So contructor should do the job.
but when i load the page, it shows -> Undefined variable: cache
how to fix my code/this issue?
class Home extends \CodeIgniter\Controller
{
public function __construct(...$params)
{
parent::__construct(...$params);
// Your own constructor code
}
}
looks like codeigniter have already created a constructor method in the BaseController.
Therefore, i just load the function that i wish to preload/initialized in that BaseController.php.
Fixed.
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.
}
}
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()
{
}
}
Here is my controller code
public function index()
{
$this->load->model("mod_home");
$data['avoinics'] = $this->mod_home->getAvoinics();
$data['dir']="home";
$data['page']="index";
$this->load->view('main',$data);
}
for another page
public function about()
{
$this->load->model("mod_home");
$data['avoinics'] = $this->mod_home->getAvoinics();
$data['dir']="home";
$data['page']="about";
$this->load->view('main',$data);
}
But i don't want to send $data['avoinics'] again again. Is there any way to access a data from anypage.
How to use same data in a single view more than time.
foreach($avoinics as $avoinics):
$name=$avoinics->sc_name;
echo '<li>'.$name.'</li>';
endforeach;
if i use it again on same view page it's sowing error...
Yes, you can:
Create a global array
private $data = array();
In constructor
$this->load->model("mod_home");
$this->data['avoinics'] = $this->mod_home->getAvoinics();
Now your function will look like this
public function index() {
$this->data['dir']="home";
$this->data['page']="index";
$this->load->view('main',$this->data);
}
For second part, do not change the variable value
foreach($avoinics as $record){
echo '<li>'.$record['name'].'</li>';
}
$avoinics is intact now. You can use it again until you do not modify it.
A good example you might easily understand is when you need to call certain scripts or css files for a specific controller. You won't call it in every single page but yes in the constructor.
class yourController extends CI_Controller
{
private $data;
public function __construct()
{
$this->data['css'] = array('file1.css', 'file2.css');
$this->data['js'] = array('jquery.min.js', 'jquery-ui.min.js');
}
public function index()
{
$this->load->view('yourView', $this->data);
}
public function about()
{
$this->load->view('yourView', $this->data);
}
}
I recommend you to extend core ci_controller with my_controller and declare there your variable in constructor. Then in your new controllers extend your my_controller where you will have variable declaration.
I know this is MVC structure incompatible but i need to use this technique:
I have a controller and a model.
I'm calling a function in model from controller.
Model called function calles controllers another function. (This is what generates error).
Example below:
Controller:
public function B($ret=false) {
if(!$ret)$this->Model_model->M($ret);
else echo 'ok';
}
Model:
public function M($ret=false) {
$this->N($ret);
}
private function N($ret=false) {
$this->Controller->B(!$ret); //i can't find how can i call this
}
My first trigger function is:
$this->Controller->B(false);
I've moved code in function B of controller to the Model completely and now everything is going in model itself. B function calling another B function in model and at last step model isn't need to call controller; it is calling B function in Model:
Controller:
public function B($ret=false) {
$this->Model_model->B($ret);
}
Model:
public function B($ret){
if(!$ret)$this->M($ret);
else echo 'ok';
}
private function M($ret=false) {
$this->N($ret);
}
private function N($ret=false) {
$this-B(!$ret);
}
My first trigger function is:
$this->B(false);
And my controller is still has short code.