I have a model class ModelHome that is a child of Model ie:
class ModelHome extends Model
Model is a variable of the Controller class ie:
class Controller {
public $model;
public function __construct () {
$this->model = new Model;
}
}
Is it possible to access a method within the Controller class from within a method inside the ModelHome class?
I've tried parent:: and calling the class by name ie Controller::method but I can't seem to find the right scope to access the method I need.
Thanks.
-Vince
First of all, you must have an instance of ModelHome. If you make an instance of Model, that has not automatically been extended by ModelHome just because ModelHome exists. So, i guess your Controller::__construct() should be:
public function __construct () {
$this->model = new ModelHome;
}
However, your ModelHome does not know about your Controller class/instance. You could make a __construct in ModelHome that takes a parameter with a link to the controller. Like this:
class ModelHome extends Model {
public $controller;
public function __construct ($controller) {
$this->controller = $controller;
}
}
class Controller {
public $model;
public function __construct () {
$this->model = new ModelHome($this);
}
}
Now, your ModelHome knows about the controller by using $this->controller
Related
Suppose I have two child controllers of MY_Controller,say Child_1 & Child_2.In MY_Controller I have two methods method_1 & method_2 as
abstract class MY_Controller extends CI_Controller
{
public function __construct()
{
parent::__construct();
}
public abstract function method_1();//children will give custom implementation
public function method_2()
{
some code ...
/*Here I want to call method_1() of the child controller that have called this method i.e. method_2* automatically */
}
}
I am calling method_2() from child_1 & child_2 using
class Child_1 extends MY_Controller
{
public function __construct()
{
parent::__construct();
}
public function method_1(){//custom implementation goes here}
public function some_method()
{
...some code
$this->method_2();//call inherited method method_2()
}
}
A similar code for child_2
abstract class MY_Controller extends CI_Controller
{
public function __construct()
{
parent::__construct();
}
public abstract function method_1();//children will give custom implementation
public function method_2()
{
// some code ...
$this->method_1(); //Call the method directly it will implement the child's method
/*Here I want to call method_1() of the child controller that have called this method i.e. method_2* automatically */
}
}
I am attempting to access the parent class __construct properties within a child class that extends this, however not sure how to do this as I have tried multiple methods and didn't give me the expected result.
So I have a baseController and a indexController which extends it, I want to be able to have direct access to the properties of the parent within the child controller.
$config = ['site' => 'test.com'];
class baseController {
public function __construct($config){
$this->config = $config;
}
}
class indexController extends baseController {
public function __construct(){
parent::__construct(); // doesnt seem to give any outcome
}
public static function index() {
var_dump($this->config); // need to access within this method
}
}
$app->route('/',array('indexController','index')); // the route / would call this controller and method to return a response
There are several issues with code you have there. You are setting up config as a global, it should be inside your BaseController and set it to public or protected:
class BaseController {
protected $config = ...
Just like #mhvvzmak1 mentioned, your child constructor is calling the parent properly. for example you can do it like so:
class IndexController extends BaseController {
public function __construct(){
$config = [];
parent::__construct($config);
}
and finally just like dan08 mentioned, you can't reference $this from a static method, change your index function:
public function index() {
Update
If you really want the child function to remain static as required by your framework, you make config a static function on the BaseController and call it in the child.
class BaseController {
protected static function config() {
return ['site' => 'mySite'];
}
}
class Child extends BaseController {
public static function index() {
$config = BaseController::config();
}
}
I'm developing an API to acces some data on my database. I'm creating a controller for each part of the API. For example, I will have a controller to attend API calls to get a film list (FilmsController) and other controller to attend API calls to get a director list (DirectorsController)
Each controller will have a basic set of methods (getList, getInfo) so I made an ApiController to use as the base for the others. In the ApiController I have the basic set of methods but I have to call the models in non very polite way.
I'm I missing something? Is there any other way to call the models dynamically? I'm using the controllers wrong?
Here is the code, thanks.
class ApiController extends BaseController {
protected $model = '';
public function getList()
{
$items = call_user_func(array($this->model,'all'));
return Response::json($items);
}
...
}
And the FilmsController
class FilmsController extends ApiController {
protected $model = 'Film';
}
Am I going with a bad design?
If you really want to bind model to controller, it would be better to use Laravel IoC container and its automatic resolution feature.
class ApiController extends BaseController {
protected $model;
public function getList()
{
$items = $this->model->all();
return Response::json($items);
}
}
class FilmsController extends ApiController {
public function __construct(Model $model)
{
$this->model = $model;
}
}
Find more about this in documentation
why you call model using variable and use call_user_func function
you can just create ApiController as abstract class and you override the basic set of methods (getList, getInfo) into FilmsController and DirectorsController then you can use Film Model
ApiController:
class ApiController extends BaseController {
public function getList()
{
}
FilmsController:
class FilmsController extends ApiController {
public function getList()
{
$items = Film::all();
return Response::json($items);
}
}
I have a model -
class Model{
public $childModel;
public function getModel($url){
$this->childModel = 'model/'.$url;
include($this->childModel);
new ModelHomeHome();
}
}
this is child model -
class ModelHomeHome extends Model{
function __construct(){
echo 'This is Home Model.';
}
}
a Controller Class -
class Controller{
public $model;
function __construct(){
$this->model = new Model();
}
}
and this is the child controller -
class ControllerHomeHome extends Controller{
function help(){
$this->model->getModel('home/home.php');
}
}
and in a page -
include(controller.php);
include(model.php);
The problem is the child model class is not initializing. Fatal error: Call to a member function getModel() on a non-object ... .
If I place the $this->model = new Model(); inside the help() function of the child controller instead of placing inside the parent controller, it works. But I want to initialize the model inside the constructor of parent controller. Please help.
Are you sure that is the path to your file. Most frameworks I have seen usually have files all over the place so I try to have constants that ensure I am in the correct parent director when retrieving files.
This works fine for me when I include the model and controller class and run the following code
include('controller.php');
include('model.php');
$home = new ControllerHomeHome();
$home->help();
outputs:
This is Home Model.
I am trying to build an abstract base controller that will extend all other controllers. So far I have something like:
abstract class BaseController {
protected $view;
protected $user;
public function __construct() {
$this->view = new View; //So a view is accessible to subclasses via $this->view->set();
$this->user = new User; //So I can check $this->user->hasPermission('is_admin');
}
abstract function index();
}
class UserController extends BaseController {
public function index() {}
public function login() {
if($this->user->isLoggedin()) {
redirect to my account
}
else {
$this->view->set('page_title', "User Login");
$this->view->set('sidebar', $sidebar); //contains sidebar HTML
$this->view->set('content', $content); //build main page HTML
$this->view->render();
}
}
}
The problem i get is I get errors like this:
Call to a member function set() on a non-object in C:\xampp\htdocs\program\core\controllers\admin.controller.php on line 44
If I put the $user and $views properties in the main controller (ie UserController), everything works fine. But I only want to set up these objects once (in the base controller) and not have to add $this->view = new View; in all my controllers.
FIXED: I overrode my constructors and I thought you couldn't call parent::__construct() on abstract classes.
What you are trying to do should work. Make sure you aren't covering up your constructor in UserController. (i.e., if it has a constructor, it needs to call its parent constructor.)
Otherwise, do some debugging to see where $this->view is being reset.
Your code works for me. You are either overriding your __construct() method in UserController, or you are overridding the view field with something other than a View object.
What you have in this form would work.