php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #51900 Abstract Method Not Overridden will Halt PHP.
Submitted: 2010-05-24 17:27 UTC Modified: 2011-02-12 01:43 UTC
Votes:2
Avg. Score:4.5 ± 0.5
Reproduced:2 of 2 (100.0%)
Same Version:2 (100.0%)
Same OS:1 (50.0%)
From: jrdoane at gmail dot com Assigned:
Status: Not a bug Package: Class/Object related
PHP Version: 5.2.13 OS: Ubuntu 9.10/RHEL 4
Private report: No CVE-ID: None
 [2010-05-24 17:27 UTC] jrdoane at gmail dot com
Description:
------------
if you have an abstract class that gets overridden, if a method that is overridden has a default where the abstract doesn't, PHP just halts without any error, warning, or fatal. For small projects this is manageable, but when you have a large project, hunting down these things take a long time, such as a multi-thousand lined library loaded with abstract classes.

These are the folowing versions of PHP that I've tested:
$ php --version
PHP 5.2.10-2ubuntu6.4 with Suhosin-Patch 0.9.7 (cli) (built: Jan  6 2010 22:56:44)
Copyright (c) 1997-2009 The PHP Group
Zend Engine v2.2.0, Copyright (c) 1998-2009 Zend Technologies

and

<This is a RHEL box. (Red Hat Enterprise Linux ES release 4 (Nahant Update 8))>
$ php --version
PHP 5.2.13 (cli) (built: Apr  6 2010 18:40:35)
Copyright (c) 1997-2010 The PHP Group
Zend Engine v2.2.0, Copyright (c) 1998-2010 Zend Technologies


Test script:
---------------
runme.php
<?php
include("file1.php"); // Fails here because a method isn't overridden.
// Just halts, no errors with error_reporting on and error output set to E_ALL.
// The included file never actually executes any code unless the $bar in
// the abstract class is changed to $bar=null, which fixes the problem, but
// finding the problem to begin with is the problem.
?>

file1.php
<?php
include_once("file2.php");
class example extends absEx {
    function foo($bar=null) {
        // Do something
    }
}
?>

file2.php
<?php
abstract class absEx {
    abstract function foo($bar);
}
?>

Expected result:
----------------
Error: Abstract method not overridden (Line: ##### OR method name)

Actual result:
--------------
# PHP halts suddenly with no error output.

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2010-06-08 13:11 UTC] tony2001@php.net
-Status: Open +Status: Bogus
 [2010-06-08 13:11 UTC] tony2001@php.net
Not reproducible.
Please enable error reporting and make sure display_errors is set to On.

PHP 5.3.99-dev
PHP 5.3.3-dev 
PHP 5.2.14-dev 

All these versions report a fatal error:
Fatal error: Class example contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (abcEx::foo) in /tmp/1.php on line 4
 [2010-06-09 14:26 UTC] jrdoane at gmail dot com
Display_Errors is on.
E_ALL is being displayed.
No change, I checked this before submitting a bug report.
 [2011-02-12 01:22 UTC] justin dot rebelo at gmail dot com
For what it's worth, I have been having this same issue for some time on my 
ubuntu-based workstation. It took me  while to narrow it down to just this 
situation but I have the following issue.

Declare an abstract class:

abstract class Foo {
  abstract public function test () {
  }
}

class Bar extends Foo {
}

When Bar.php gets loaded, PHP dies instantly and silently. Nothing is logged, 
nothing is printed to browser and when run on CLI, nothing prints to console.

phpinfo verifies:

error_reporting = E_ALL
display_errors = 1
display_startup_errors = 1

I also use xdebug and have stepped through the code to the point where it dies 
after including the offending file and I get no useful information through it 
either.

I am using PHP Version 5.3.3-1ubuntu9.3
 [2011-02-12 01:43 UTC] scottmac@php.net
I get

Fatal error: Abstract function Foo::test() cannot contain body in 
/private/tmp/foo.php on line 4

If i remove the body I get


Fatal error: Class Bar contains 1 abstract method and must therefore be declared 
abstract or implement the remaining methods (Foo::test) in /private/tmp/foo.php 
on line 7
 [2011-02-12 01:44 UTC] justin dot rebelo at gmail dot com
Ah, of course I mistyped my example for starters...

Are you using E_ALL or -1 or something else?
 [2011-02-12 02:55 UTC] justin dot rebelo at gmail dot com
I finally solved it and you are right that the issue was not as it seemed.

I wrote my example off the top of my head while I was already away from a 
workstation and 
wasn't actually running it. When I tested it, of course, even in the same 
environment, it 
worked correctly despite the fact that I was still not getting the errors out of 
the bad 
class includes in the exact same environment.

So, my error was one I'm ashamed of, but I confess it here for posterity and 
hopefully it 
helps someone else who ends up here for the same reason.

The classes my application was loading were being loaded from an include file. 
The 
application is built using a shared, custom framework which optionally includes 
some files 
if the application has need to provide those pieces through includes.

As you might guess by now, since the include files are part of the *optional* 
bootstrapping 
in the shared framework, they are included as such:

@include 'init.inc.php'; // Load app-specific init script if there is one

The init.inc.php file was the one loading the application-specific classes. I've 
honestly 
very _very_ seldom used the @ operator in my code in abour 5 or 6 years of php 
work because 
I know it's generally not a Good Idea, but in this case it seemed perfectly 
acceptable 
shorthand, since the existence of an app init script was purely optional and 
there was no 
reason to treat its non-existence as a mentionable issue.

So, it turns out that the include() call itself is not all that is affected by 
the prefixed 
error suppression operation. In fact, the contents of the included file and 
presumably any 
code that branches off therein are all affected by the error suppression and, at 
that point 
in the application, error_reporting was returning 0 but only there.

That was a good waste of a few hours, but a valuable lesson because I'll never 
bother using 
the @ operator again!
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Wed May 29 12:01:32 2024 UTC