I am trying a very simple thing here but it doesn't seem to work. Take a look at this code:
include 'custom/mainclass.php';
$child = new childClass();
class childClass extends mainClass {
}
Apparently childClass() cannot be found (According to php).. I'm 100% sure I'm doing something very stupid in the way of ordering my code.
I already searched the web but from what I understand I'm doing nothing wrong..
You have to declare your classes in your code first before using them.
include 'custom/mainclass.php';
class childClass extends mainClass {
}
$child = new childClass(); //Create an instance after the class has been declared
EDIT:
After some research it turned out, that you can actually use a class before declaring it.
But, declaration of the class and all parent classes must be in the same file.
So if you declare a parent class in one file and a child class in another, it won't work.
Also, you must declare parent classes first. After that you can extend them.
Same as with Variables, Functions or other language constructs,
First declare, then use.
Related
I am new to OO concepts in PHP. I have a class called MY_ controller which is my base class. All classes extend this class. I am using MVC architecture. I am using caching in my system now. So i load the cache variable in the constructor of my base class. I use normal php variable like $cacheVariable in my function to store the value from cache. I was wondering if it would serve any help if i store it as a class parameter and use like $this->cacheVariable? In each function i get cache value like $this->cache->get('cacheVariable'); will it help if i get value from $this->cacheVariable
If you want to be able to use $cacheVariable anywhere else besides your constructor you'll want to use $this
public function __construct() {
//...
$this->cacheVariable = $this->cache->get('cacheVariable');
//...
}
Also remember, if you want your children classes to inherit this variable from your base class you will need to set it as either public or protected. If it's private children will not inherit it.
When you say "class variable" I assume you are referring to a property (property of an instance=. Note the difference:
if you have a class, say MyClassA, then in your scripts you will instantiate that class using the operator new (depending on your PHP version you can use a different constructor syntax it changed since PHP-5.3.0):
<?php
class MY_controller{
public $cacheVariable;
// constructor
function MY_controller($aValue){
// constructor code which loads cacheVariable, for example with parameter
$this->cacheVariable = $aValue;
}
public function someFunction(){
//... some code, then access the property
$cv = $this->cacheVariable;
}
}
$aController = new MY_controller(42);
?>
As you inherit from MY_controller, every instance of that class, will have access to cacheVariable through $this->cacheVariable.
The important thing I wanted to clarify is that it is an instance property, not a class one. For further reference on OOP in PHP, refer to the properties section in PHP's OOP manual and the inheritance section.
When you instantiate only one instances of your controller (derived from your main controller), its a conceivable solution.
In my opinion the better idea is getting variable directly from cache service everywhere you want in your class and don't keep it as a class property. The reason is simple: let's say value of some key from cache will be changed (or expires) in the other place than your class. If you have this value as class property you need to keeping eye on it every time you access this value but if you retrieving it from cache you just don't care (because the cache cares if value of some key doesn't changed or expired).
I have a class ParentClass(), some child-classes ChildClass1(), ChildClass2(), etc. and an interface iChild(). The ChildClass() inherits from the ParentClass() and implements iChild():
class ChildClass1
extends ParentClass
implements iChild {}
class ChildClass2
extends ParentClass
implements iChild {}
In the iChild()-Interface, I would like to require, that some constants need to be filled (which are mainly identifiers and some functionality definitions). I have not found any meaning to do so, as constants may only be defined in the interface, but which are not redefinable in the implementing classes. The only workaround I found is to define some getter-functions in iChild(), which in turn return the necessary values, but that does not seem to be the right way to do. As I already extend from the ParentClass(), I also cannot use an abstract class to e.g. check the definition of the required constants in all ChildClasses.
Any ideas on how to tackle this problem?
Update: To answer a comment - with leaner and more readable I mean to following:
class ChildClass1 {
const MY_NAME = "Foo Bar Name 1";
}
-- vs --
class ChildClass1 {
public function GetMyName() {
return "Foo Bar Name 1";
}
}
I find the first example a lot more readable and understandable than the second. Unfortunatly, I currently do not have a way to enforce MY_NAME to be set by the ChildClasses.
I'm not sure that the proper solution here is for a constant. The very definition of a constant is that it does not change. If each implementation of iChild needs to define the constant it isn't really a constant, it is a variable. I suggest adding in the appropriate getter methods, communicating to the user that they need to supply this information in their implementation.
Ok, I did a little testing and it simply is not possible for a class to override a constant set by an interface it is implementing or a parent class it is extending. Class constants appear to be checked at compile time and a fatal error is thrown if you attempt to override it. For what you are trying to do the appropriate answer is providing getter methods in your interface.
Can anyone give me an example of the following desired OOP structure please.
I want a main class (super class) (interface or abstract class?) where all the other classes that are extending from it can have their functions called from instances of the main super class.
e.g.
class mainSupoerClass() {
}
class doWork exends mainSupoerClass(){
public function addEntity(){
//do stuff for entity
}
}
I want be able to do this:
$data = new mainSupoerClass;
$data->addEntity(); (doesnt belong to this class but its fetching the function from doWork class)
Can anyone give me a start on the correct OOP structure to carry out this work?
In simple terms, you can't. You have to instantiate the extended class and you'll get all functions within the instantiated class and also the parent class/classes.
Is there any reason you need this to be done this way?
That won't work the way you describe it. PHP (nor any other language) can know which derived class you refer too. It would work if you instantiate doWork instead of mainSupoerClass.
I think you are looking for the factory pattern, but I'm not sure.
With that pattern, you build an interface (either an interface or an abstract class), and let a factory instantiate any descendant of that class.
Now your code doesn't need to know which instance it is, because it can call any method declared in the interface/abstract base class.
An interface is more flexible in this regard. If you create an abstract class, you will need to derive all other classes from that class. Usually this won't be a problem, but sometimes you want a whole new implementation. In that case, an interface is better. You can implement the interface in a completely different class, and still make use of PHP's typehinting for validating that any object you pass to a function or method implements the interface.
Even it's called super-class, it does not mean that it has all classes defined elsewhere. The methodology is the following:
[super] --> [concrete]
and not
[concrete] --> [super]
So a concrete class extends the superclass. The concrete class will then have everything of the superclass plus what the concrete class has / overwrites - but not the other way round.
class Super
{
public function a() {}
}
class Concrete extends Super
{
public function b() {}
}
Super has ::a() and in addition Concrete has ::b(). But Super will never have ::b().
Additionally even you have multiple classes, there is always one instance regardless of how many classes it is compound of, commonly called object:
$object = new Concrete;
This makes a Concrete object.
You'll have to read. Try these:
Article: http://sourcemaking.com/design_patterns/abstract_factory
Code: http://sourcemaking.com/design_patterns/abstract_factory/php/2
It appears that the factory design pattern is what you are looking for.
I don't understand why you wanted to be able to do:
(doesnt belong to this class but its fetching the function from doWork class)
What's the reason behind it?
This is for fun only, don't scream please.
I would like to rewrite the content of a class's methods at runtime (I mean, without modifying the file, only replacing/editing the code in memory), is that possible?
Using reflection, or anything else?
Don't close this question please, I'm looking for another answer than runkit.
Why not simply create a new class that inherits from the one you want to modify and overwrite it's methods?
<?php
class MySimpleXML extends SimpleXMLElement {
public function themethodiwanttooverwrite() {
//...
}
}
?>
As long as the method isn't marked as final...
If I have:
class main {
//hello
}
class child1 {
function love($v) {
}
}
class child1 {
function hate($v) {
}
}
function __autoload($file) {
include_once($file . '.php');
}
Is there a way I can set this up so that I can do
$main = new main();
$main->hate();
$main->love();
and still
keep them as seperate classes, and
use the autoloader for the child classes?
I think even if the child classes extend the main class, that I can't access the child methods from the parent class. Is that correct? If so, is there something like a reverse extends which injects the child class properties/methods into the main class?
Update 1
Okay, so it looks like there's nothing straight-up built in to php to acheive this (Thanks everyone for the answers). How about I write up my goal and maybe you or someone you know can suggest a way to acheive this?
I would like to have one main class. I then have a set of subclasses which operate like grouped function libraries. Each of these subclasses is __autoloaded when needed to acheive an end. So for example, I have a subclass of file upload & processing functions, a subclass of database interaction functions, a subclass of xml processing functions, and so on.
I want to use this like: call the main class at the top of every script $main = new main();. Then, later on, an image processing method from a child class (which has not been loaded) is needed, so I call
$main->methodFromChildClass(); which will cause that child class to be autoloaded and the method used.
I am hoping in this way to optimize which files are loaded, and keep things well organized. I'm fairly new to oop. Is there a way to achieve this type of organization now?
There is not such a language construct (not in PHP anyway - other languages offer mechanisms like mixins, which kind of work like that), but there is a technique to do something like that called inversion of control.
class Main {
public $child;
public function __construct($child) {
$this->child = $child;
}
}
$main = new Main(
new Child1()
);
$main->child->love();
This is very simplified example, that does not show full potential of this technique. For more information search for 'inversion of control' and 'design patterns'
I think you're interested in is called traits, which are not available in the current release of PHP, but will be in the next version, and is available in trunk if you check out the source from SVN and compile yourself.
For more information, see http://wiki.php.net/rfc/traits
Not to my knowledge, kinda violates the whole concept of OO programming. The main class should have the methods and properties which need to be used by all child classes of the main class, and then the child classes have methods and properties that only they will need to use.
I suppose if you really wanted to, you could store a child class object inside a main class object and do something like $main->child->hate(); but that would be sort of recursive, because if the child extends the parent class, and if the child was created and stored on the parent's construct, then you would wind up with an infinite loop of the parent creating the child which creates a new parent inside it which creates a new child which creates a new parent ad infinitum. Though you could get around that by simply having a method that would have to be manually called in order to create and store the child.
With the code you gave, it's not going to work.
If child1 extends main, you can call hate() method only by creating instance from the child1 class or by introducing the hate() method in the main() class.
Child classes inherit methods from Mother classes but the reverse is not true.
What exactly are you trying to do ?
You can use magic to simulate that behaviour, but "clean" is something different
class main {
public function __call ($name, $args) {
switch ($name) {
case 'hate':
$x = new child1;
return $x->hate();
break;
case 'love':
$x = new child2;
return $x->hate();
break;
}
}
}