PHP empty constructor - php

Just wondering is it best to define an empty constructor or leave the constructor definition out completely in PHP? I have a habit of defining constructors with just return true;, even if I don't need the constructor to do anything - just for completion reasons.

If you don't need a constructor it's best to leave it out, no need to write more code. When you DO write it, leave it empty... returning true doesn't have a purpose.

There is a difference between the two: If you write an empty __construct() function, you overwrite any inherited __construct() from a parent class.
So if you don't need it and you do not want to overwrite the parent constructor explicitly, don't write it at all.

EDIT:
previous answer is no longer valid, since PHP now behaves like other oop programming languages.
constructors aren't part of interfaces. therefore you are now allowed to override them how you prefer without any issues whatsoever
the only exception to this is:
interface iTest
{
function __construct(A $a, B $b, Array $c);
}
class Test implements iTest
{
function __construct(A $a, B $b, Array $c){}
// in this case the constructor must be compatible with the one specified in the interface
// this is something that php allows but that should never be used
// in fact as i stated earlier, constructors must not be part of interfaces
}
PREVIOUS OLD NOT-VALID-ANYMORE ANSWER:
there is an important difference between an empty constructor and no constructor at all
class A{}
class B extends A{
function __construct(ArrayObject $a, DOMDocument $b){}
}
VS
class A{
function __construct(){}
}
class B extends A{
function __construct(ArrayObject $a, DOMDocument $b){}
}
// error B::__construct should be compatible with A constructor

You should only define an empty constructor if your object should never be instantiated. If that is the case, make the __construct() private.

constructor always return instance of class in which its defined . Hence you never use "return" inside constructor . Lastly its better not to define it if you are not gona use it .

One reason you might want to define an empty constructor is when you want to avoid calling a function that has the same class name.
class FooBar {
function foobar() {
echo "Hello world";
}
}
new FooBar(); // outputs "Hello world" in PHP < 8
This is due PHP 4 backwards compatibility, where constructors had the same name of the class.
Anyway it got deprecated in PHP 7.4.26.
class FooBar {
function __construct() {
}
function foobar() {
echo "Hello world";
}
}
new FooBar(); // no output

Related

When is necessary to use static methods?

I thought usually we use static method because we do not need to instantiate objects. and we can use className::staticFunction to call static method, bub today found:
test1.php
<?php
class Foo {
static public function helloWorld() {
print "Hello world " ;
}
}
Foo::helloWorld();
test2.php
<?php
class Foo {
public function helloWorld() {
print "Hello world " ;
}
}
Foo::helloWorld();
Question:
Both of above scripts work. We did not declare function as static, we can still use className::staticFunction to call the function. Why do we need use static methods?
We did not declare function as static, we can still use className::staticFunction
What you probably didn't notice is that PHP complains about the second type of invocation:
PHP Strict Standards: Non-static method Foo::helloWorld() should not be called statically in php shell code on line 1
Strict Standards: Non-static method Foo::helloWorld() should not be called statically in php shell code on line 1
To make these notices visible you need to set the value of error_reporting to -1, either using ini_set() or via the php.ini configuration file; btw, this is recommended during development.
Conclusion
A function that's called statically should be declared as static function xyz().
Update
Btw, using the scope resolution operator :: doesn't necessarily mean you're making a static call; consider this example:
class Foo
{
public function helloWorld()
{
print "Hello world ";
}
public function doSomething()
{
self::helloWorld();
}
}
$f = new Foo;
$f->doSomething();
This works because using self:: as opposed to Foo:: doesn't change the invocation "mode" (unless the method you're calling is defined as static).
The "problem" with static methods is the way they're called:
Foo::bar();
Any call to a static method is by necessity hardcoded and cannot easily be substituted. Compare with:
$foo->bar();
$foo is a variable here, meaning the exact object and implementation of bar() can be substituted. This is important for and the basis of dependency injection.
You'd use a static method for:
first and foremost cases where you don't need individual object instances
anything you need to do before an object can be instantiated
alternative object constructors, for instance DateTime::createFromFormat() instead of new DateTime
idempotent utility functions which you are 100% sure never need to be substituted or mocked
You may use static functions in other scenarios here and there, but these are the main points. You need to be aware that declaring a method static means you need to call it statically, which means its call-time use cannot really be altered. For a long treaty on this subject, read How Not To Kill Your Testability Using Statics.
Well a simply hello world program might not be able to show a big difference is the usage of static vs not but take a look at this class
class foo {
private $a = 1;
private static $b = 2;
public function foobar()
{
echo $this->a;
}
}
in this above class if you call foobar statically then $this->a will not resolve.
PHP is funny like that, but I'll usually have a utilities class which takes arguments of things to perform logic on and return. Stuff like this doesn't need an instantiated class. It's up to the user/developer to correctly call methods (read: use the correct method accessors).
When you are working on a large OOP based project, you’ll no doubt be working with many classes (both parent and child classes). An unfortunate consequence of this is that in order to access elements from different classes, they must manually be passed through each class (or worse, storing an instance in a global variable). This can be painstakingly frustrating and can lead to messy code and overall bad project design. Thankfully, static elements are accessible from any context (i.e. anywhere in your script), so you can access these methods without needing to pass an instance of the class from object to object.
As you don’t need to declare an object instance to access static elements, you can be saved from unnecessary declarations to access seemingly simple functions.
Static elements are available in every instance of a class, so you can set values that you want to be available to all members of a type.
From the above example test1.php
helloworld() function cannot be overriden or overloaded since you have added a static keyword.
However in the second example, test2.php
helloworld() function can be overloaded and overriden
Illustration:1 (Works)
<?php
class Foo {
function helloWorld() {
print "Hello world " ;
}
}
class Foo1 extends Foo
{
function helloWorld()
{
echo "Foo's World";
}
}
$Foo1 = new Foo1();
$Foo1->helloWorld(); //Foo's World
Illustration:2 (Fails)
Cannot make static method Foo::helloWorld() non static
<?php
class Foo {
static function helloWorld() {
print "Hello world " ;
}
}
class Foo1 extends Foo
{
function helloWorld()
{
echo "Foo's World";
}
}
$Foo1 = new Foo1();
$Foo1->helloWorld();

How does 'self' exactly work in inherited classes?

According to php, class::self always points to the class itself, but as I wrote down these codes, something strange happens:
class C_foo{
function foo() { return "foo() from C_foo"; }
function bar() { echo self::foo(); }
}
class C_bar extends C_foo{
function foo() { return "foo() from C_bar"; }
}
C_foo::bar();
C_bar::bar();
I thought the output would have been:
foo() from C_foo
foo() from C_bar
But in fact:
foo() from C_foo
foo() from C_foo
It means that the self in parent class does NOT exactly inherit into the child, it works more like to this:
foo() {return parent::foo();}
Is that a feature from php or is it a bug? Or is it mean to be like this?
Otherwise, such thing is occurred as I tried to tell a class create objects from itself, the code is something like this:
class Models {
function find($exp) {
...
...
$temp_model = new self();
...
...
}
}
class Something extends Models {...}
$somethings = Something::find("...");
Maybe someone would ask, "why don't you set a variable with the value of class, and use the variable as the __construction function?"
Like this:
...
...
function find($exp) {
...
...
$class_name = __class__;
$temp_model = new $class_name();
...
...
}
...
In fact I did that, and got a even more weird result:
It works only when the class does not have any property or function but find(), or an error telling me a variable shows off where a function sould exist would jump out.
It sounds like you're describing the PHP feature known as 'late static binding'.
PHP provides two syntaxes: self:: and static::.
static was introduced in PHP 5.3 because a lot of people expected self to work the you're describing.
See the PHP manual for more: http://php.net/manual/en/language.oop5.late-static-bindings.php
You can also use the syntax new self() or new static() to create new instances:
$parent = new self();
$child = new static();
This is because the class which receives the methods of the parent is of that class. So:
$bar is Bar, therefore self:: refers to Bar, not to Foo. Even though that method is from Foo.
This may be different from Java, but it probably indicates how PHP is doing inheritance internally.
In PHP, classes are not object. Because of that, there is no inheritance of static methods (actually, they are similar to global functions).
So, when C_foo says self, it always means C_foo (even if you called a method from C_bar).
If you want create instances from an abstract class method, you should try the Factory pattern.

Accessing child variables from the super class without instanciation

I'm attempting to access member variables in a child class via the parent class without instantiation.
This is one of my attempts but B::getStatic() fails with Access to undeclared static property.
Is there another solution to this, possibly without static?
class A {
static public function getStatic() {
return self::$myStatic;
}
}
class B extends A {
public static $myStatic = 5;
}
class C extends A {
public static $myStatic = 6;
}
var_dump(B::$myStatic);
var_dump(B::getStatic());
var_dump(C::$myStatic);
var_dump(C::getStatic());
The concept you're running into is called "Late Static Binding." Until PHP 5.3.0, there was no support for this.
If you're running 5.3.0 or higher, update the getStatic() method:
static public function getStatic() {
return static::$myStatic;
}
The others are right, the way your code is it can't be done since the variable doesn't exist at compile time.
The way to do something like this is usually with an abstract class (available in PHP5 and up, it looks like).
Class A would be the abstract class, and would have a getStatic() function. Classes B and C would extend A and have definitions for the getStatic() function. This way, when you call getStatic() you will get the value the subclass defines since there is no definition in A.
The caveat to this approach is that you can't instantiate A since it's abstract. You would ALWAYS have to make a B or a C (or a subclass there-of).
You could also make a setter in A and have the subclasses use it to set the value (instead of an '='s). That would let you instantiate A and it could set the value if it ever needs to. You might be able to make the setter private so it can't be called directly, I don't know if subclasses can use private functions in PHP.
You have a mismatch between the declaration of the function and variable.
Either you need to move the declaration of the function to B
or
move the declaration of the variable to A.
Class B inherits the properties from class A instead of the reverse.
Why don’t you use B::$myStatic like in your example?
You have to move myStatic into A. Your method getStatic in A can't access a variable that does not exist in A.
From the PHP manual:
Static references to the current class
like self:: or __CLASS__ are resolved
using the class in which the function
belongs, as in where it was defined:
So because the method is defined in A, when you call getStatic() on B or C it is trying to return a::$myStatic, which doesn't exist. Even if it did exist you would only ever get that value back, not any overridden value in a subclass.
A solution is Late Static Bindings, but this is only available in PHP 5.3 which is not yet released.
$myStatic must be declared static in class A: See here.
class A {
public static $myStatic = 5;
}
class B extends A {
public static $myStatic = 3;
}
class C extends A {
public static $myStatic = 1;
}
Then just use B::$myStatic ...

Defining class methods in PHP

Is it possible in PHP (as it is in C++) to declare a class method OUTSIDE the class definition?
No, as of PHP 5.2. However, you may use __call magic method to forward call to arbitrary function or method.
class A {
public function __call($method, $args) {
if ($method == 'foo') {
return call_user_func_array('bar', $args);
}
}
}
function bar($x) {
echo $x;
}
$a = new A();
$a->foo('12345'); // will result in calling bar('12345')
In PHP 5.4 there is support for traits. Trait is an implementation of method(s) that cannot be instantiated as standalone object. Instead, trait can be used to extend class with contained implementation. Learn more on Traits here.
Yes it is possible to add a method to a PHP class after it is defined. You want to use classkit, which is an "experimental" extension. It appears that this extension isn't enabled by default however, so it depends on if you can compile a custom PHP binary or load PHP DLLs if on windows (for instance Dreamhost does allow custom PHP binaries, and they're pretty easy to setup).
<?php
class A { }
classkit_method_add('A', 'bar', '$message', 'echo $message;',
CLASSKIT_ACC_PUBLIC);
$a = new A();
$a->bar('Hello world!');
Example from the PHP manual:
<?php
class Example {
function foo() {
echo "foo!\n";
}
}
// create an Example object
$e = new Example();
// Add a new public method
classkit_method_add(
'Example',
'add',
'$num1, $num2',
'return $num1 + $num2;',
CLASSKIT_ACC_PUBLIC
);
// add 12 + 4
echo $e->add(12, 4);
You could perhaps override __call or __callStatic to locate a missing method at runtime, but you'd have to make up your own system for locating and calling the code. For example, you could load a "Delegate" class to handle the method call.
Here's an example - if you tried to call $foo->bar(), the class would attempt to create a FooDelegate_bar class, and call bar() on it with the same arguments. If you've got class auto-loading set up, the delegate can live in a separate file until required...
class Foo {
public function __call($method, $args) {
$delegate="FooDelegate_".$method;
if (class_exists($delegate))
{
$handler=new $delegate($this);
return call_user_func_array(array(&$handler, $method), $args);
}
}
}
As PHP 5.3 supports closures, you can dynamically define instance methods as variables holding closures:
$class->foo = function (&$self, $n) {
print "Current \$var: " . $self->var . "\n";
$self->var += $n;
print "New \$var: " .$self->var . "\n";
};
Taking $self (you can't use $this outside object context) as a reference (&), you can modify the instance.
However, problems occur when you try to call the function normally:
$class->foo(2);
You get a fatal error. PHP thinks foo is a method of $class, because of the syntax. Also, you must pass the instance as the first argument.
There is luckily a special function for calling functions by name called call_user_func:
call_user_func($class->foo, &$class, 2);
# => Current $var: 0
# => New $var: 2
Just remember to put & before the instance variable.
What's even easier is if you use the __call magic method:
class MyClass {
public function __call ($method, $arguments) {
if (isset($this->$method)) {
call_user_func_array($this->$method, array_merge(array(&$this), $arguments));
}
}
}
Now you can call $class->foo(2) instead. The magic __call method catches the call to an unknown method, and calls the closure in the $class->foo variable with the same name as the called method.
Of course, if $class->var was private, the closure in stored in the $class->foo variable wouldn't be able to access it.
No.
You can extend previously declared classes, though, if that helps.
No it is not posible. if you define function/method outside class construct it becomes global function.
C++ can't do this either. Did you mix up declaration with definition?
No, as everyone has said, it is not strictly possible.
However, you can do something like this to emulate a mixin in PHP or add methods to a class at runtime, which is about as close as you're going to get. Basically, it's just using design patterns to achieve the same functionality. Zope 3 does something similar to emulate mixins in Python, another language that doesn't support them directly.

Calling Static Method from Class B(which extends Class A) of Class A

There was an interesting question in a practice test that I did not understand the answer to. What is the output of the following code:
<?php
class Foo {
public $name = 'Andrew';
public function getName() {
echo $this->name;
}
}
class Bar extends Foo {
public $name = 'John';
public function getName() {
Foo::getName();
}
}
$a = new Bar;
$a->getName();
?>
Initially, I thought this was produce an error because static methods can not reference $this (atleast in PHP5). I tested this myself and it actually outputs John.
I added Foo::getName(); at the end of the script and did get the error I was expecting. So, what changes when you call a static method from within a class that extends the class you're calling from?
Would anyone mind explaining in detail exactly what is going on here?
Foo::getName() is using an older PHP4 style of scope resolution operator to allow an overridden method to be called.
In PHP5 you would use parent::getName() instead
It's useful if you want to extend, rather than completely override the behaviour of the base class, e.g. this might make it clearer
class Bar extends Foo {
public $name = 'John';
public function getName() {
echo "My name is ";
parent::getName();
}
}
If you call the static method bound to the other object, the method is executed in the context of the current object. Which allows access to the $this-object.
Better way to call the superclass-method from inside the subclass would be:
parent::getName();
$this to the object in whose context the method was called. So: $this is $a->getName() is $a. $this in $fooInstance->getName() would be $fooInstance. In the case that $this is set (in an object $a's method call) and we call a static method, $this remains assigned to $a.
Seems like quite a lot of confusion could come out of using this feature. :)
When you call $a->getName() you're referencing a specific object, $a, which is of class Bar and so returns "John".
Foo::getName() isn't valid outside the function because there's no specific object.
I'm not sure it works in PHP, but if you cast the object to the superclass as in (Foo)$a->getName() then you'd get "Andrew" as your result. You'd still be talking about the specific object ($a) but in this case of type Foo. (Note you wouldn't generally want to do this)
Sometimes programmers are better at explaining things in code than in English!
The first thing going on here is the concept of overloading. When you instantiate Bar, it's getName() method overloads the method of the same name in Foo.
Overloading is a powerful and important part of OOD.
However, it is often useful to be able to call the version of a method that exists in the Parent class (Foo).
Here's an example:
class Dog
{
public function getTag()
{
return "I'm a dog.";
}
}
class Skip extends dog
{
public function getTag()
{
return Dog::getTag() . " My name is Skip.";
// I'm using Dog:: because it matches your example. However, you should use parent:: instead.
}
}
$o = new Skip();
echo $o->getTag(); // Echo's: "I'm a dog. My name is Skip."
Clearly this is a very parochial example but it illustrates a point.
Your base class is the most general implementation of a Type. In this case, it's "Dog." You want to put information in this base class that is common to all instances of that Type. This prevents duplication in each of the Derived classes (like "Skip").
Your script is taking advantage of this feature, perhaps inadvertently.

Categories