ID:               41461
 User updated by:  ralph at smashlabs dot com
 Reported By:      ralph at smashlabs dot com
 Status:           Bogus
 Bug Type:         Class/Object related
 Operating System: *
 PHP Version:      *
 New Comment:

PS. I did check this with the internals list before I posted.. And I
think you actually confirmed it for me on the list

http://news.php.net/php.internals/29646

Thank you for your time,
-ralph


Previous Comments:
------------------------------------------------------------------------

[2007-05-28 17:42:50] ralph at smashlabs dot com

I am sorry, perhaps I should rephrase (I was rushed when I wrote the
original bug report) and I don't think I was especially clear.

In general, we are speaking strictly of Method Overriding.  PHP
currently allows concrete classes to override methods in abstract
classes as demonstrated by this code:

[EMAIL PROTECTED] ~/tmp $ cat test_method_override.php 
<?php

error_reporting(E_ALL | E_STRICT);

class Z_Abstract
{
  public function someFunc($one, $two)
  {  }
}

class Z_Concrete extends Z_Abstract
{
  public function & someFunc($uno, $dos, $tres)
  {  }
}

$o = new Z_Concrete();
[EMAIL PROTECTED] ~/tmp $ php test_method_override.php 
[EMAIL PROTECTED] ~/tmp $ 

As you can see, no E_STRICT was triggered, thus allowing the concrete
class to override the method from the abstract class.

On the other hand, when adding an _empty_ interface to the superclass
hierarchy, the behavior changes.  The simple inclusion of an interface
now (albeit empty) seemingly shouldn't add any complexities to method
overriding for methods outside the scope of the interface itself.  I
have done a bit more homework, and it seems like not alot of IS_A
inheritance literature exists to describe this problem, let alone
justify the behavior we are seeing in practice..  See code:

[EMAIL PROTECTED] ~/tmp $ cat test_method_override2.php 
<?php

error_reporting(E_ALL | E_STRICT);

interface Z_Interface
{ }

class Z_Abstract implements Z_Interface
{
  public function someFunc($one, $two)
  {  }
}

class Z_Concrete extends Z_Abstract
{
  public function & someFunc($uno, $dos, $tres)
  {  }
}

$o = new Z_Concrete();
[EMAIL PROTECTED] ~/tmp $ php test_method_override2.php 

Strict standards: Declaration of Z_Concrete::someFunc() should be
compatible with that of Z_Abstract::someFunc() in
/home/webdeveloper/tmp/test_method_override2.php on line 14



At the very least, I looks like one of the two is broken (At least in
the spirit of OOP as it relates to polymorphism and overriding methods.)

------------------------------------------------------------------------

[2007-05-28 15:08:50] [EMAIL PROTECTED]

Thank you for taking the time to write to us, but this is not
a bug. Please double-check the documentation available at
http://www.php.net/manual/ and the instructions on how to report
a bug at http://bugs.php.net/how-to-report.php

PHP follows strict is_a inheritance.

By the way, it is called signature and even if you could change it it
would not solve the problem. And anyway it would break inheritance
rules.

------------------------------------------------------------------------

[2007-05-21 23:06:13] ralph at smashlabs dot com

Description:
------------
When an interface is a parent of a class, the interface is implying a
specific profile for a given function (here its __get) even though it is
not defined in the interface itself.  This is making it impossible to
overload and/or change the profile of the function in a descendant
class.


Reproduce code:
---------------
The following will produce this notice:

Strict Standards: Declaration of Z_Concrete::__get() should be
compatible with that of Z_Abstract::__get() in xxx on line 16

<?php

error_reporting(E_ALL | E_STRICT);

interface Z_Interface
{ }

abstract class Z_Abstract implements Z_Interface
{
  public function __get($name)
  {
    return;
  }
}

class Z_Concrete extends Z_Abstract
{
  public function & __get($name)
  {
    return null;
  }
}

$t = new Z_Concrete();





This code will not produce a notice:

<?php

error_reporting(E_ALL | E_STRICT);

abstract class Z_Abstract
{
  public function __get($name)
  {
    return;
  }
}

class Z_Concrete extends Z_Abstract
{
  public function & __get($name)
  {
    return null;
  }
}

$t = new Z_Concrete();

The only difference is that the former has an interface as a parent,
the latter does not.


Expected result:
----------------
No E_STRICT notice raised

Actual result:
--------------
E_STRICT notice raised.


------------------------------------------------------------------------


-- 
Edit this bug report at http://bugs.php.net/?id=41461&edit=1

Reply via email to