I've just started experimenting with OO PHP, but there's one basic principle I don't really uderstand that well, and don't find too much info on it.
When creating a __construct() method, why would you want it to be public, when it's specifically a constructor for that class?
When would you want to call a constructor outside the class?
To me, it seems using a protected constructor is good practice, right?
I know this is basic OO stuff, but I don't find any info directly on it, specifically for constructors.
The __construct (not "__constructor") method is the one called when you do new MyClass(), i.e. when you instantiate the class. The constructor needs to be public, unless you only want to instantiate the class from within itself. If the latter, you need at least one other public static method you can call in which the class will instantiate itself, otherwise you're unable to create any instance of it.
Whenever you create a new instance of a class, the constructor is called. If the constructor is not public, no other code can create an instance of that class.
Hence, if you want to create instances of the class, make the constructor public.
A constructor is always only part the class it is defined in, I don't understand what you mean by "when it's specifically a constructor for that class".
To clarify:
The only way to invoke the constructor is with new Class(). There is no other way to invoke it. __construct is a magic method and there is no way to explicitly call a magic method.
Related
I have read in laravel's facade documentation the following sentence:
Typically, it would not be possible to mock or stub a truly static
class method.
1) question 1: I'm trying to understand facade in laravel. As I guess, it's implemented because if we have classes, and they have big namespaces and big names and every time we want to use this class and we don't want to use new keyword and use statements, we use the facade which is an easier code and readable. I also think that laravel implemented facades because they wanted to write non-static functions in their classes so that they could be tested. After all of this, we use facades like static classes (because of readability and not using new and use), but in reality, it makes new instances.
Am I right?
2) If the above is right, can you provide me an example why it's not possible to test a static method as laravel docs said?
A facade does not solve the big namespaces problem you mentioned. Big namespaces are solved using aliases. You can declare them in your config/app.php and internally Laravel will use class_alias when you call them. This is how e.g. \Cache or \DB work.
A facade is basically a proxy class to a singleton object instance of another class (the facade itself ensures the instance is a singleton).
Typically to register a singleton in Laravel you:
Add app()->singleton(ABC::class) in your service provider
Access it via app()->make(ABC::class)->...
A facade basically takes care of that for you if you haven't already registered that class as a singleton.
Basically a facade is a way to proxy that singleton instance of another class.
Also it's generally not possible to mock or stub static methods however if you are using facades you can do \ABCFacade::swap($mockObject) and therefore your facades can be mocked.
It is also false that you cannot test a static method. You can absolutely test a static method. For example:
public testStaticMethod() {
$this->assertEquals(1, ABC::method()); // We tested a static method against a desired behaviour
}
What you usually can't do is mock a static method. Here's how you would typically mock something with PHPUnit:
public testWithDependency() {
$dependency = $this->getMockBuilder(Dependency::class)->getMock();
$dependency->expects($this->once())->method('dependantMethod')->willReturn(true);
$objectToTest = new ABC($dependency); //We're passing a fake dependency which behaves in an ideal way
$this->assertEquals(1, $objectToTest->methodToTest()); //Any calls to the dependency will call mock methods and not real ones
}
The problem arises when trying to mock a static method. As you can see mocking creates mock instances of a certain type. It can't mock the static members of that type because the mock object itself is not actually of that type.
However as I just found out the statement that it's not possible to mock or stub a static method is not entirely true. There's the AspectMock you can mock static methods or helper methods. This seems to work by intercepting all function calls via a custom autoloader.
This being said, just because you can doesn't mean it's good practice to use static methods, there's other issues to consider like e.g. you normally can't have static interfaces in most programming languages or you normally can't override static methods in most programming languages. Note the "in most programming languages" part here. In PHP it's entirely possible to override static methods with late static binding but that means you need to make a conscious decision about this when implementing the static method.
Another disadvantage is that a class of statics can't implement an interface because interfaces apply to object behaviours and not the static behaviour. Therefore you can't swap out one interface for another if you are using statics which is a major disadvantage.
In general the aversion to static methods is not because of testability but because if you are coding in OOP you are really limited if you are using statics.
Hopefully this will help clear up some confusion.
For my latest website I'm trying to use OOP. I'm using the project to develop my understanding of this technique. Previously I would 'include' a functions folder that contains various php files labelled things like image.upload.functions.php and general.error.handling.functions.php etc.
However, this time I'm using classes wherever possible.
I have just read that in order to use a parents methods (in an extended class) you must run the parents constructor however I haven't done this and my project seems to work ok.
So.. I have a class called Form Validation
I have another class called Process Login that extends Form Validation.
My Form Validation class does things like test a password strength to make sure it is strong enough, check whether a user is in the database etc.
I extend Form Validation with a Registration class and a Forgotten Passowrd class.
Should I be putting:
parent::_construct();
..in the constructor of each of the extended classes?
Could someone explain 'simply' the reasons why we do OR do not do this? And whether it's something I should be doing?
Many thanks :-)
Here's the link to official documentaion: constructors and destructors
And here's the quote:
Note: Parent constructors are not called implicitly if the child class defines a constructor. In order to run a parent constructor, a call to parent::__construct() within the child constructor is required. If the child does not define a constructor then it may be inherited from the parent class just like a normal class method (if it was not declared as private).
Calling parent constructor is NOT necessary. And, in general, it is not called implicitly, if You have defined constructor in Your own child class. But, if in the parent constructor You have a nice piece of logic or functionality, that You don't want to lose, then call parent's constructor from the child's one.
You call parent::__construct() (watch that there are two underscores) if you want to reuse the functionality of the constructor from the class you're extending.
The reuse of code is a main reason for inheritance in OOP. So if there is any algorithm in your parent class that you want to use, you have to call parent::__construct().
If you're extending the parent's constructor, you also have to call it before (or after) your own additions, e.g. like this
class A extends B {
public __constructor() {
parent::__construct();
// Your own code
}
}
If you don't want to use any of your parents' constructor functions, you don't inherit from that parent constructor - but I assume that in most cases you want to.
Is it possible - in PHP - to "disable" the functionality of overriding the constructor of a class?
Just to make the scenario clear:
I've an abstract class A, with a constructor. This constructor is essential for the working of the class.
Then I have some "siblings", that "extend" the abstract class A. They - obiously - have to extend that class, but I don't want them to touch the constructor.
I know it's possible to call parent::__construct(), but that way I don't force that pattern. In the case a colleague of mine is implementing a new class that extends my abstract class, I don't want there to be no confusion. Of-couse everything is documented, but y'all know how it goes when it comes to reading stuff ;-)
Any ideas on how to disable the overriding of the constructor? (In that case I'd make an abstract init() method that can be override, but my "abstract constructor" will cal that one). Or any other ideas to implement this wanted situation?
Thanks!
Niek
You can declare the constructor as final when your class is abstract.
public final function __construct(){}
In this constructor you can call you init() method.
Move code from constructor to another method. Constructors shouldn't contain any logic, only initialization of variables by arguments, given to constructor.
http://misko.hevery.com/code-reviewers-guide/flaw-constructor-does-real-work/
You could check what class invoked the constructor and if was the parent class you execute your construct code, otherwise you not
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?
I understand that singleton enforces a class to be created once. But why should an instance exists if I dont access it directly? Why is that pattern for, isn't it easier just use full static class with static methods and datas?
Some time ago I was asked what is the benefit of using singleton over of using static class, here is my response:
Static class leads to invisible dependencies - that is a class that use the static class, but that class is not part of the class' interface.
Singleton also allows this, because it provides global access point, but it's instance can be passed as an argument to the class / method
If there is any initialization, as the connect method, it should be called from each class method, which leads to duplicated code. On the other hand, the initialization of the singleton is performed in the constructor, which is called just once from the getInstance()
method
Singleton can be easily refactored in a factory, adding a parameter to the getInstance() method and returning different instances
Static class is harder to extend, because if we want to override a method, that is called within the class with self::methodName(), we should override the caller as well (although in PHP 5.3 there is a late static binding, which can be used to avoid those problems)
If you need to add an argument, needed for all of the methods, you can easily do this in singleton because of the single access point, but you can't in a static class
The major difference between a static class and a singleton is that with the static class, you need to hardcode the class name in your code everywhere you use it:
StaticClass::doSomething();
StaticClass::doSomethingElse();
While with a singleton, you only need to hardcode the class name once:
$singleton = SingletonClass::getInstance();
// other code does not need to know where $singleton came from,
// or even that class SingletonClass exists at all:
$singleton->doSomething();
$singleton->doSomethingElse();
Another important difference is that singleton classes can be part of hierarchies and can implement interfaces.
This does not mean that Singleton (the pattern) is good and should be used liberally. But it is better than using a static class directly.
[Edit]: The stuff I have written below is actually plain wrong. Just got alerted to this answer from years ago by a downvote. They do serve a purpose ;)
A singleton exists once, but it can have internal state - as opposed to a static class. You might e.g. use it as a global registry, which you can't do with a static class.
[Edit:] What comes next, though, is as true as it ever was.
It's debatable whether singletons are a good idea, though. They introduce global state into an application, which can make it very hard to test. But that is another discussion.