Strict Standards: Declaration of ChildClass::foo() should be

Not for 'how-to' coding questions but PHP theory instead, this forum is here for those of us who wish to learn about design aspects of programming with PHP.

Moderator: General Moderators

Post Reply
User avatar
anjanesh
DevNet Resident
Posts: 1679
Joined: Sat Dec 06, 2003 9:52 pm
Location: Mumbai, India

Strict Standards: Declaration of ChildClass::foo() should be

Post by anjanesh »

Why is it not ok to have a method of the same name in the child class with different parameters ?

Code: Select all

<?php
error_reporting(E_ALL + E_STRICT); # E_STRICT specific
 
class ParentClass
 {
        protected static function foo($param1, $param2)
         {
                echo "Parent\n";
         }
 }
 
class ChildClass extends ParentClass
 {
        public static function foo($param1)
         {
                parent::foo($param1, 2);
                echo "Child\n";
         }
 }
 
ChildClass::foo(1);
?>

Code: Select all

Strict Standards: Declaration of ChildClass::foo() should be compatible with that of ParentClass::foo() in test-class.php on line 19
Parent Child
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

Re: Strict Standards: Declaration of ChildClass::foo() shoul

Post by Chris Corbyn »

I have to admit, I think this is wrong of PHP. Because PHP does not support method overloading it makes sense to allow the parameters to be overridden in the child method. But indeed, it's not considered correct from PHP's point of view.

In Java you can do that because the method signature includes its parameters.

Code: Select all

public class Foo {  public void something(int x, int y) {  }} public class Bar extends Foo {  public void something(String x, String y) {  }}
But on the same token it's valid to put both of those methods (even though they have the same name) in a single class in Java. This is where PHP falls down and just has to rule out overriding methods with a different signature.

IMHO, it should be fine to override the method *provided the number required of parameters doesn't change*. But it's not :P
User avatar
anjanesh
DevNet Resident
Posts: 1679
Joined: Sat Dec 06, 2003 9:52 pm
Location: Mumbai, India

Re: Strict Standards: Declaration of ChildClass::foo() should be

Post by anjanesh »

In Java you can do that because the method signature includes its parameters.
In which language it isnt ? All major OOP languages have method overloading with parameters as part of its signature.
Its obvious that in PHP, parameters cant be treated as signatures because of weak type system.

But I really cant understand why the number of parameters need to match the child's method too ! Isnt that the job of abtsract class ?
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

Re: Strict Standards: Declaration of ChildClass::foo() should be

Post by Chris Corbyn »

anjanesh wrote:
In Java you can do that because the method signature includes its parameters.
In which language it isnt ? All major OOP languages have method overloading with parameters as part of its signature.
Its obvious that in PHP, parameters cant be treated as signatures because of weak type system.
I wouldn't call PHP a "major OOP language" ;) Perl would be another "language" which doesn't do overloading... as would JavaScript.
But I really cant understand why the number of parameters need to match the child's method too ! Isnt that the job of abtsract class ?
It basically boils down to conforming to an interface (whether that's by implementing an interface, or by extending a class).

If a method type-hints that it wants an instance of Foo as it's only parameter then it expects (read, requires) *any* subclass of Foo to also behave the same way.

Code: Select all

class Foo {
 public function test(Bar $b) {
    //
 }
}
 
class MainClass {
  public function doSomething(Foo $foo) {
    $foo->test(new Bar());
  }
}
 
$obj = new MainClass();
$obj->doSomething(new Foo());
 
Now if you were to change that interface by overriding the test() method with different parameters the type-hint would allow it; but it could potentially result in a fatal error:

Code: Select all

class SubFoo extends Foo {
  public function test (Zip $zip) {
    //whatever
  }
}
 
$obj = new MainClass();
$obj->doSomething(new SubFoo());
//Error SubFoo::test() requires object of type Zip as parameter 1; object of type Bar given
You have similar problems if you add extra parameters which are not optional.

My argument is that PHP should check the types of the parameters and if they're compatible it should allow the override. It should on the same token check if any additional parameters have default values (and hence are "optional").
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

Re: Strict Standards: Declaration of ChildClass::foo() should be

Post by Chris Corbyn »

:arrow: Moved to T&D since this is potentially an interesting discussion.
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Re: Strict Standards: Declaration of ChildClass::foo() should be

Post by Christopher »

anjanesh wrote:Why is it not ok to have a method of the same name in the child class with different parameters ?

Code: Select all

Strict Standards: Declaration of ChildClass::foo() should be compatible with that of ParentClass::foo() in test-class.php on line 19 Parent Child
What you you mean "it not ok" ? That is simply a Strict warning that is a actually very nice and informative. It is quite possible that not having the same number of parameters could mean the programmer has overlooked something and it could cause problems. PHP provides a Strict warning to bring this to your attention.

What's the problem? It only says the "Declaration ... should be compatible" not must be compatible.
(#10850)
Z3RO21
Forum Contributor
Posts: 130
Joined: Thu Aug 17, 2006 8:59 am

Re: Strict Standards: Declaration of ChildClass::foo() should be

Post by Z3RO21 »

Give the functions second parameter a default value, then just don't use it.

Code: Select all

class ChildClass extends ParentClass
{
        public static function foo($param1, $param2 = false)
        {
               parent::foo($param1, 2);
               echo "Child\n";
        }
}
This should remove the error, and achieve what you want to do.
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

Re: Strict Standards: Declaration of ChildClass::foo() should be

Post by Chris Corbyn »

Z3RO21 wrote:Give the functions second parameter a default value, then just don't use it.

Code: Select all

class ChildClass extends ParentClass
{
        public static function foo($param1, $param2 = false)
        {
               parent::foo($param1, 2);
               echo "Child\n";
        }
}
This should remove the error, and achieve what you want to do.
Are you sure? I could swear I tried this in my own library just a few weeks ago and was forced to just use another method name (since I want E_STRICT without warnings).

EDIT | Just tried it and you're right. I realise what I was trying to do which PHP was complaining about now. I was trying to make on interface extend another which added an optional parameter to an existing method. PHP doesn't allow that since the interfaces clash.
User avatar
anjanesh
DevNet Resident
Posts: 1679
Joined: Sat Dec 06, 2003 9:52 pm
Location: Mumbai, India

Re: Strict Standards: Declaration of ChildClass::foo() should be

Post by anjanesh »

So how do I use E_STRICT and at the same time suppress that warning ? Where do I insert the @ symbol ?
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

Re: Strict Standards: Declaration of ChildClass::foo() should be

Post by Chris Corbyn »

anjanesh wrote:So how do I use E_STRICT and at the same time suppress that warning ? Where do I insert the @ symbol ?
Don't use E_STRICT if you're just going to surpress the warnings. If you disagree with E_STRICT then just use E_ALL.

However, set_error_handler() should do it.
User avatar
anjanesh
DevNet Resident
Posts: 1679
Joined: Sat Dec 06, 2003 9:52 pm
Location: Mumbai, India

Re: Strict Standards: Declaration of ChildClass::foo() should be

Post by anjanesh »

I got to use E_STRICT for other parts of the code.
I just dont want this particular error popping up though.
Marko Leer
Forum Newbie
Posts: 1
Joined: Wed Jan 26, 2011 5:50 am

Re: Strict Standards: Declaration of ChildClass::foo() shoul

Post by Marko Leer »

Type hinting will produce the same strict error:

Code: Select all

class ArtikelCollection extends Collection{ 
	public function addItem(Artikel $obj,$key=null){
		parent::addItem($obj,$key);
		}
	}
Post Reply