I call a CodeIgniter controller method -imgupload- from jquery ajax. This controller extends my custom front controller.
class newad extends My_Controller{
public function __construct() {
parent::__construct();
}
public function imageupload() {
$this->load->library("uploadhandler");
}
The imgupload method calls the uploadhandler class which extends from newad.
class uploadhandler extends newad {
The functionality of that class works properly, except for one thing, I cant access the properties of the My_Controller class, even though they are declared protected.
The inheritance chain looks like this: My_Controller->newad->uploadhandler.
Any idea why I cant access those properties?
In short the answer is you do not need to extend Controller class here. You can just pass the value to your library as a parameter.
$params = array('user_ud' => $this->userID, 'otehr' => 'other');
$this->load->library('uploadhandler', $params);
//Now from your library
class uploadhandler{
public function __construct($params)
{
// Do something with $params
}
//.. Your code...//
}
Now about your question:
The functionality of that class works properly, except for one thing, I cant access the properties of the My_Controller class, even though they are declared protected. The inheritance chain looks like this: My_Controller->newad->uploadhandler. Any idea why I cant access those properties?
As inheritance chain are ok, you can access property of My_Controller from your library but not the value of the Current controller, because these two are different object.
So here is my answer how can we access the value? One way I have already mentioned. That will be enough if you need to share some property with the library. But what if you need to access all the Controller instance. There is a function to get the reference of controller instance get_instance(). You can use this function anywhere and get access of all public property controller. If you need to access any private property of controller the define a geter function to access that.
Explanation
First of all you need to learn basic about OOP. Learn about Class, Object, Inheritance..
When I said property of My_controller is different from the same property the you accessed from uploadhandler, it may confused you if you are not familiar with class and object. Here is two instance(object) of different class.
For short let say you have some classes like: Vehicle, Car, Machine and Person. All they have common attributes say name, weight ..
So, can we just inherit Any of these class from other??
Simple answer is no. We can't(!) define a Person class extending from Others. So how can we decide which incoherence would legal. If you can say Foo is a Bar you can write Foo class extending from Bar. Now from your case, It is obvious uploadhandler is not a controller. So Never Extend a anything from something that is not something.
NB: The answer is generic. If you need any specific clarification, just ask, I can update my answer
Related
The application I am working on has a wrapper(DAO) for each model class. The model itself is derived from Eloquent class. The issue is that junior developers keep calling methods like ModelClass:Where() or ModelClass::find() rather than using DAOClass:DaoMethod(). How can I restrict in my class that implementor of class can't do something like ModelClass::where()?
Thanks
The final keyword should do the trick. Just make all your desired DAOClass methods final. That way, once they are called from a class which extends your DAOClass, they will get a fatal error.
If I give the same name to a function in the Model of Codeigniter, that function gets called automatically when I load the model.
//controller
$this->load->model('my_model');
//model
class My_model extends CI_model {
function my_model {
}
}
In this case I don't have to call my model function like this
$this->my_model->my_model();
because loading the model calls the function as well.
Can somebody explain this behaviour? I haven't found anything in docs regarding this.
This is a common concept in Object-Orientated programming. The function is acting as a Constructor. The constructor is called when an instance of the object is created.
In PHP using the __construct() method is the advised way to declare a constructor for the class. However, in PHP 4, a constructor was declared using the class name, so:
For backwards compatibility, if PHP 5 cannot find a __construct()
function for a given class, and the class did not inherit one from a
parent class, it will search for the old-style constructor function,
by the name of the class.
In CodeIgniter, a model is a class. As you don't have a __construct() method in your class, PHP is treating your my_model function as the constructor for the class (as it is the same as the class name).
You may want to the following method to your model. This will stop my_model being treating as a constructor.
function __construct()
{
// Call the Model constructor
parent::__construct();
}
I'd personally avoid calling a method the same name as the class in PHP, as it can lead to this confusion! PHP's docs have some useful information on constructors.
I am trying to work out the best way to design my classes and I think abstract classes it the right way here, but I'm not sure! I am building a plugin for Wordpress carts that at the moment, will work for both Woocommerce and WP-Ecommerce. As these two systems have different implementations of certain functionality, such as getting an order object, I want to create a separate class for each platform.
I have the following which will contain generic methods that should be available to the classes that inherit from it. This class should never be instantiated:
class Order_Export {
}
I then have 2 more classes that will inherit from the above:
class Order_WooExport extends Order_Export {
}
class Order_WPExport extends Order_Export{
}
Is my design right here? Am I right in saying the class Order_Export should be an abstract class? What about methods that I want the class inheriting to implement? Do I simply mark the signature in the abstract class and not provide a body, or do interfaces come into play somewhere here?
How about instantiating the right class? Do I create a factory that will return one or the other?
Any advice appreciated!
That sound correct to use abstract base class, as long as you are sure to never need to instantiate Order_Export :
abstract class Order_Export
{
abstract protected function someMeth1();
abstract protected function someMeth2();
public function someMeth3() {
// Do common thing to both Order_WooExport and Order_WPExport
// using someMeth1(), someMeth2()...
}
}
Then :
class Order_WooExport extends Order_Export
{
protected function someMeth1() {
// Do something specific
}
protected function someMeth2() {
// Do something specific
}
}
Finally, the factory seems to be the right way to go too.
A lot of frameworks out there decided to use this approach: force the user to extend a base controller class (if you want to create a new controller) or to extends a base model class (if you want to create a new model).
Let's take a look at the code of CodeIgniter's controller base class:
/**
* Constructor
*/
public function __construct()
{
self::$instance =& $this;
// Assign all the class objects that were instantiated by the
// bootstrap file (CodeIgniter.php) to local class variables
// so that CI can run as one big super object.
foreach (is_loaded() as $var => $class)
{
$this->$var =& load_class($class);
}
$this->load =& load_class('Loader', 'core');
$this->load->initialize();
log_message('debug', "Controller Class Initialized");
}
What does it do? Well, as far as I can see, it just allows us to use $this->load->... for example.
Let's take a look at the __get() magic method of the model base class:
/**
* __get
*
* Allows models to access CI's loaded classes using the same
* syntax as controllers.
*
* #param string
* #access private
*/
function __get($key)
{
$CI =& get_instance();
return $CI->$key;
}
It does exactly the same thing. Now what does this way of doing things bring?
PRO
You can access useful CI classes by $this->....
CONS
You have to force the user to extends the base class
You have to force the user to call the parent::__construct() in the class construct
get_instace() is reserved
$this->instance redefinition cause a fatal error
You have basically repeated the same code both in the Model base class and the Controller base class
Now let's take a look at another approach:
Create a static class, such as App that do all the things the base controller does:
For example, $this->load->... would be App::load->....
Now consider pros and cons again:
PRO
You can access useful CI classes by App::....
You don't have to force the user to extends the base class
You don't have to force the user to call the parent::__construct() in the class construct
no methods name or properties name are reserved
You can use App both in the Model and in the Controller
CONS
You have no more the $this-> sexy syntax???
QUESTION
Here it comes the real question: would be the second a better or worse approach compared to the CI one? Why?
PRO
You can access useful CI classes by App::....
You don't have to force the user to extends the base class
You don't have to force the user to call the parent::__construct() in the class construct no methods
name or properties name are reserved
This not entirely valid. CI never force dev to extend the base class. All core framework functionality could be easily extended. You can have MY_Controller.php within application/core folder, contain your own base class, eg:
Front_Controller extends CI_Controller{
// Share common properties or functionalities across front/public controllers here
}
Admin_Controller extends CI_Controller{
// Share common properties or functionalities across administrative controllers here
}
Then, parent::parent_method() is very common in PHP. Mostly you'll have this syntax elsewhere, if you really use OO design in your application. This enable you to adding functionality to a subclass without loosing the inherited functionality from parent class.
So answering your question :
Here it comes the real question: would be the second a better or worse
approach compared to the CI one? Why?
Both attemps can be considered legal, atm. Because, the fact that : 1) there is no consistency checking (something like instanceof CI_Controller in PHP 5, or is_a for PHP4) within CI bootstrap, 2) And, CI not force you to returning anything from a controller action method (a Response object, like in SF, for example).
Thats to say, you can have an arbitrary class act as a controller. In fact you didn't need to wrap core Controller functionality within a static class, no one stoped you to use get_instance()->load->library('foo') and get_instance()->load->database() within those arbitrary class.
i would like to know if it is possible to have a function in PHP which returns an interface or a class which contains an interface?
i tried something like this, but it fails
<?php
//class for list of controllers for ACL
class Gestionale_Action_Helper_Crud extends Zend_Controller_Action_Helper_Abstract {
interface crud_controller
{
public function indexAction();
public function modificaAction();
public function cancellaAction();
public function creaAction();
}
public function getCrudInterface(){
return $this->crud_controller;
}
}
what i wanted to do, in zend framework, create an interface that crud controllers must implement, or even better if i could create an abstract controller and have them implement that
thank you
I'd suggest that you use Zend_Rest_Controller instead of creating your own interface.
Zend_Rest_Controller is an abstract class that defines five basic methods you need in a CRUD-controller: index, get, post, put, and delete.
Combined with Zend_Rest_Route it lets you create nice and clean RESTful application.
You can get more reading on Zend_Rest_Controller at http://weierophinney.net/matthew/archives/228-Building-RESTful-Services-with-Zend-Framework.html and http://techchorus.net/create-restful-applications-using-zend-framework
Just place the interface outside of any class (preferably in a different file) and let it be implemented by all your crud-controllers.
<?php
class GrudController implements CrudInterface
{
// ...
}
i'm not sure i get what it is you want to do, but i'm fairly certain you're asking the wrong question. if you simply want to make sure an object implements a certain interface, this is quite easy to do. lets say for example you have some helper method in a class which deals with a crud controller, you just specify the type in the argument list:
class crud_helper {
public function help(crud_controller $cc) {
$cc->indexAction();
}
}
now you can pass any object that is an instance of a class that implements crud_controller to the method help. but no other object.