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.
Related
I am learning OOP right now and I have a property that specifies what class it should be.
class Controller{
public ?Model $model;
}
class LoginModel extends Model{
public function login(){}
}
Now, I want to load a class that is an inheritance of Model but contains a unique method not from Model. That causes the lint to think that there is an error in the code. Is there a way to fix the issue from Controller->model?
$controller = new Controller();
$controller->model = new LoginModel();
echo $controller->model->login();
I know that one way is we can change Model to LoginModel but that would be tedious if there are a lot of different controllers with different model designed to do different things.
consider this example
class Controller
{
public ?Model $model;
}
class Model { }
class LoginModel extends Model
{
public function login() { }
}
class LogoutModel extends Model { }
$controller = new Controller();
$controller->model = new LoginModel();
$controller->model->login(); //This works
$controller->model = new LogoutModel();
$controller->model->login(); //This doesn't works
The lint is saying that you cannot assure that there will be a login() to call. So unless you'll have a login() method in all models, in which case you can define an abstract or interface, otherwise since it can fail it will show you the error.
PS: there is a way around it, but I wouldn't recommend it for regular use.
if($controller->model instanceof LoginModel)
{
$controller->model->login(); //This works
}
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();
}
}
Well, I'm newbie in CodeIgniter Framework and i'm trying building a generic Model Class. See:
class Basic_Model extends CI_MODEL {
function __construct() {
// Call the Model constructor
parent::__construct();
}
}
I want to extends all Models based on Basic_Model, like this:
class Pagina_Model extends Basic_Model {
function __construct() {
// Call the Model constructor
parent::__construct();
}
}
The problem is when i try to call "pagina_model" from a Controller a got the following error:
Fatal error: Class 'Basic_Model' not found in /var/www/myproject/application/models/pagina_model.php on line 12
If i use "basic_model" in controller everything works fine.
EDIT 1:
I created a file named MY_Basic_Model.php in "/application/core" and changed the class name to "MY_Basic_Model". But i got the error:
Fatal error: Class 'MY_Basic_Model' not found in /var/www/myproject/application/models/pagina_model.php on line 12
For this you have to create Core System Classes (this is also known as Method Overriding).
Create a file MY_Model.php in application/core/ directory which will extend the base CI_Model class:
<?php
class MY_Model extends CI_Model {
function __construct()
{
parent::__construct();
}
}
Now you can extend this in your models (../applicaton/models/):
<?php
class Pagina_Model extends MY_Model {
function __construct()
{
parent::__construct();
}
}
Few things to note here:
1) The class declaration must extend the parent class.
2) Your new class name and filename must be prefixed with MY_ (this item is configurable).
How to configure:
To set your own sub-class prefix, open your application/config/config.php file and look for this item:
$config['subclass_prefix'] = 'MY_';
Documentation:
https://ellislab.com/codeigniter/user-guide/general/core_classes.html
You can do it this way.
lets assume you have basic_model.php inside your model folder .
Now add the code for class Basic_Model that you have written
class Basic_Model extends CI_MODEL {
function __construct() {
// Call the Model constructor
parent::__construct();
}
}
Now make a pagina_model.php inside your model folder and add the code that you written. Just include the first line like bellow
<?php
require APPPATH.'/models/basic_model.php';//just add this line and keep rest
class Pagina_Model extends Basic_Model {
function __construct()
{
parent::__construct();
}
}
hope this will solve your problem
You can do this ... MY_ model is really good but should you wish a sub model to extend a different sub model you can always do:
require(APPPATH.'models/Other_model.php');
class New_model extends Other_Model {
In my instance Other_Model actually extends MY_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.
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