Hi everybody I have a code that give me this error
Fatal error: Class 'MY_Controller' not found in C:\wamp\www\project\application\controllers\admin\home.php on line 3
I have no idea why it's showing this error…
The code of C:\wamp\www\project\application\controllers\admin\home.php is
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Home extends MY_Controller {
function index()
{
redirect('admin/login');
}
function logout()
{
$this->session->unset_userdata('logged_in');
//session_destroy();
redirect('admin/login');
}
}
?>
The code of C:\wamp\www\project\application\libraries\MY_Controller.php is
<?php
class MY_Controller extends CI_Controller {
public function __construct() {
parent::__construct();
if (!$this->session->userdata('logged_in')) {
redirect('admin/login');
}
}
}
And also if I place
class Home extends CI_Controller
instead of
class Home extends MY_Controller
in the
C:\wamp\www\project\application\controller\admin\home.php
file and try to load the
C:\wamp\www\project\application\libraries\MY_Controller.php
in the constructor of
C:\wamp\www\project\application\controllers\admin\home.php
it shows
Call to a member function userdata() on a non-object
Why so?
You need to put class files to core instead of library folder when you extending System classes. Put MY_Controller.php in core folder.
Refer to the documentation: http://codeigniter.com/user_guide/general/core_classes.html
Core controllers need to be stored in application/core/
So when you extend an object, it will look for it there. Library folder is used for storage of 'external' libraries, which you must explicitly include in your controller:
Ex:
$this->load->library('class name');
Info on libraries here: http://codeigniter.com/user_guide/general/libraries.html
Related
I am using codeigniter(3.1.5) and Ihave two controllers in my application/controllers/ folder. with name controller A and Controller B. I want to extends Controller A in Controller B so that I can use methods of Controller A. But it generates class not found error.
Here is my sample code:
A_Controller.php:
defined('BASEPATH') OR exit('No direct script access allowed');
class A_Controller extends CI_Controller {
public function index()
{
}
public function display(){
echo 'base controller function called.';
}
}
B_Controller.php:
defined('BASEPATH') OR exit('No direct script access allowed');
class B_Controller extends A_Controller {
}
I want to execute display() method of controller A in controller B.
If i put controller A in application/core/ folder and in application/config/config.php file make
$config['subclass_prefix'] = 'A_';
then I can able to access methods of controller A.
Please suggest.
Thanks in advance.
Extending a controller in another controller is not really good. Building with MVC and especially with CI, you have other options to achieve this.
Use a class MY_Controller inside application/core that extends the CI_Controller. Later, all (or some) of your controllers should extend the MY_Controller. In MY_Controller you can have many functions and you can call which function you want in your controller.
Use a library. Write your own library in application/libraries and load it in your controller wherever you want. A library is a class with functionality for your project.
Use a helper. Write your own helper in application/helpers and load it in your controller. A helper should have a general purpose for your application.
In that way, your code will be more flexible and reusable for the future. Messing with 2 Controllers seems bad to me. Remember that with the default Routing system of CI you can be confused.
Try to use following code.
defined('BASEPATH') OR exit('No direct script access allowed');
class B_Controller extends A_Controller {
public function test()
{
$this->display();
}
}
Use construct in controller
defined('BASEPATH') OR exit('No direct script access allowed');
class B_Controller extends A_Controller {
public function __construct() {
parent::__construct();
}
public function test()
{
$this->display();
}
}
I found the solution using including parent controller on child controller like this -
require_once(APPPATH."modules/frontend/controllers/Frontend.php");
then my function like this -
class Home extends Frontend {
function __construct() {
parent::__construct();
}
function index() {
echo $this->test(); //from Frontend controller
}
}
I hope this will help.
add this script in B_Controller :
include_once (dirname(__FILE__) . "/A_Controller.php");
for example B_Controller.php :
defined('BASEPATH') OR exit('No direct script access allowed');
include_once (dirname(__FILE__) . "/A_Controller.php");
class B_Controller extends A_Controller {
}
I'm currently learning Codeigniter. As you know, there is a default file called welcome.php in the controller when you first install the package.
I tried to modify that page to index.php, and here is the code:
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class Index extends CI_Controller {
public function index()
{
$this->load->view('welcome_message');
}
}
I also changed the route.php in the config file:
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
$route['default_controller'] = 'Index';
$route['404_override'] = '';
$route['translate_uri_dashes'] = FALSE;
Then I access the page by entering this path: http://localhost/CI/index.php, but it says there are two errors:
Message: Undefined property: Index::$load. Filename: controllers/Index.php
Message: Call to a member function view() on null. Filename:controllers/Index.php
Did I forget to change something else in order to make it work?
I downloaded CI3.0.2 and tried your code in my computer. I encountered the same problem, and with a few time debug I found what caused this problem.
Your class is Index and your function is index two, in php class when you don't define constructor __construct it will try to find if there's a method that have same name with class nameIndex, so in this situation index function is the constructor of class Index. if this confuse you see this document : constructor php official document
Solution:
class Index extends CI_Controller {
public function __construct()
{
parent::__construct();
}
public function index()
{
$this->load->view('welcome_message');
}
}
I have a relatively simple question. I am trying to inherit a constructor from a php superclass to authenticate on this controller.
Here is my super class:
class Auth_Controller extends CI_Controller {
function __construct()
{
parent::__construct();
if(!session_id()){
session_start();
}
$this->load->view('login_v/logincheck');
}
}
and here is my subclass:
class Event_Controller extends Auth_Controller {
function __construct()
{
parent::__construct();
}
public function get_events_by_owner() {
$this->load->model('Event_model');
$data['events'] = $this->Event_model->select_by_owner($_SESSION['SignedIn']);
$this->load->view('event_view', $data);
}
}
This is not working. only a white page is rendered. I'm not sure why it isn't working. If I move the constructor from Auth_Controller to Event_Model this works.
Thanks!
EDIT:
Fatal error: Class 'Auth_Controller' not found in
../controllers/event_controller.php on line 12
Your solution is not going to work, you should try either:
Move this code:
if(!session_id()){
session_start();
}
$this->load->view('login_v/logincheck');
to a cutom library, than run this library within constructor of your controller. Please read Creating Libraries for details.
or:
Create MY_Controller class and put auth code (quoted above) into its constructor. Than you'll be able to extend like:
class Event_Controller extends MY_Controller {
(...)
Please read Creating Core System Classes for details.
Hi I'd like to add a public variable ($this->data[]) to all instances of CI_Controllers, that way I can store some base rules for outputting a page (css/js, etc) then have each controller append to this array to add its own requirements (more css/js). I have a core library with custom view functions that take those arrays and inject them into the head tag of the page template.
The options I've thought of;
Edit CI_Controller and add it there... guessing that's a bad idea.
Create a shell controller that extends CI_Controller, add the var to that, then have every other controller extend the shell controller.
Any other clever ways?
I've only been using CI for about a month and I've tried reading through the docs but I can't find any built in ways to do something like this? Has anyone encountered this before and if so how did you solve it?
Thanks!
[edit] Using PHP 5.3.x [/edit]
http://ellislab.com/codeigniter/user-guide/general/creating_libraries.html
You can extend CI_Controller to have the functionality you want.
application/core/MY_Controller.php:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class MY_Controller extends CI_Controller {
public function __construct()
{
parent::__construct();
}
public function my_function()
{
return "Cool return from my_function";
}
}
controllers/welcome.php
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Welcome extends MY_Controller {
public function index()
{
echo $this->my_function();//echo's "Cool return from my_function"
}
}
You simply define the functionality you want in MY_Controller. Then in your controllers, use extends MY_Controller instead of extends CI_Controller and you can call the functions anywhere inside those controllers.
I think what you want can be easily achieved using traits. Check here: PHP: Traits
More specifically -> Example #11 Defining Properties.
The only limitation is it's PHP 5.4+
You can create your own a base controller file to inherit basic page load methods from in \application\core\MY_Controller.php as such:
<?php defined('BASEPATH') OR exit('No direct script access allowed');
class MY_Controller extends CI_Controller {
public function __construct()
{
parent::__construct();
}
protected function loadPage($path, $data = array())
{
$this->load->view('common/head'); // Assuming you will use a folder for page parts
$this->load->view($path, $data);
$this->load->view('common/foot');
}
}
Afterwards in your page controller you can call upon the same methods much more easily:
<?php defined('BASEPATH') OR exit('No direct script access allowed');
class User extends MY_Controller {
public function index()
{
$data = array(); // get data from model
$this->loadPage('user/view', $data); // Assuming you will use folders for sets of views
}
public function edit()
{
$data = array(); // get data from model
$this->loadPage('user/edit', $data);
}
}
I have created an admin controller that extends the blog controller (both are located in application/controller). However, when I tried to access the controller, it gives me an error that the blog controller was not found. If I put require_once(APPPATH.'controllers/blog.php'); inside the admin.php file it works. But I'm just wondering if there's another possible way to extends the blog controller without having to use require_once inside the admin.php
From CI user guide
If you are extending the Controller
core class, then be sure to extend
your new class in your application
controller's constructors.
class Welcome extends MY_Controller {
function __construct()
{
parent::__construct();
}
function index()
{
$this->load->view('welcome_message');
}
}
That means your Blog controller must extends CI_Controller
Example:
class MY_Blog extends CI_Controller {
function hello() {
$data = 'something';
}
}
class Admin extends MY_Blog {
function do_something() {}
}
Userguide