php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #73647 stdClass is not inherited if the class definition doesn't explicit it.
Submitted: 2016-12-03 21:04 UTC Modified: 2016-12-04 15:13 UTC
Votes:1
Avg. Score:5.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:1 (100.0%)
From: klaussantana at gmail dot com Assigned:
Status: Not a bug Package: Scripting Engine problem
PHP Version: 7.0.13 OS: any
Private report: No CVE-ID: None
View Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
If you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: klaussantana at gmail dot com
New email:
PHP Version: OS:

 

 [2016-12-03 21:04 UTC] klaussantana at gmail dot com
Description:
------------
For some reason, if you not explicit extends a class from `stdClass` it will not pass the `instanceof` test.

Test script:
---------------
<?PHP
/****
 * stdClass Inheritance Failure
 * ================================================================================
 *    
 *    This example shows how stdClass is not inherited in classes definitions that
 *    do not explicit it. 
 *    
 */

class InstableDefinition {}
class StableDefinition extends stdClass {}
class AnotherInstableDefinition extends InstableDefinition {}
class AnotherStableDefinition extends StableDefinition {}

$Objects =
[
   'Instable Object' => new InstableDefinition,
   'Stable Object' => new StableDefinition,
   'Another Instable Object' => new AnotherInstableDefinition,
   'Another Stable Object' => new AnotherStableDefinition, 
];

foreach ( $Objects as $Object )
{
   $ObjectClass = get_class($Object);
   $ObjectStandard = $Object instanceof stdClass;
   $ObjectEvaluates = $ObjectStandard ? 'does' : "doesn't";
   
   echo "The `{$ObjectClass}` class objects {$ObjectEvaluates} instance from `stdClass`." .PHP_EOL;
}

echo 'All these tests ran under PHP version ' .PHP_VERSION .'.' .PHP_EOL;

Expected result:
----------------
The `InstableDefinition` class objects does instance from `stdClass`.
The `StableDefinition` class objects does instance from `stdClass`.
The `AnotherInstableDefinition` class objects does instance from `stdClass`.
The `AnotherStableDefinition` class objects does instance from `stdClass`.
All these tests ran under PHP version 7.0.13.

Actual result:
--------------
The `InstableDefinition` class objects doesn't instance from `stdClass`.
The `StableDefinition` class objects does instance from `stdClass`.
The `AnotherInstableDefinition` class objects doesn't instance from `stdClass`.
The `AnotherStableDefinition` class objects does instance from `stdClass`.
All these tests ran under PHP version 7.0.13.

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-12-03 21:14 UTC] klaussantana at gmail dot com
This causes a serious problem when you try something like this:

<?PHP class Insecure {}
(
   function ( stdClass $Object = null )
   {
      # Some stuff only for `stdClass` inheritants...
      return $Object;
   }
) ( new Insecure );
 [2016-12-03 21:37 UTC] requinix@php.net
-Status: Open +Status: Not a bug
 [2016-12-03 21:37 UTC] requinix@php.net
PHP does not have an implicit base class like C#'s System.Object or Java's java.lang.Object. stdClass is just a built-in, empty class.

If you want to know whether something is an object then use is_object().
 [2016-12-04 08:02 UTC] klaussantana at gmail dot com
requinix@php.net

You missed my comment right after publishing.. All classes defined without the `extends` expression should be implied as an extension of `stdClass`.

The following code should produce no error, but it does:
<?PHP class UserLand {}

$f = function ( stdClass $Object = null )
{
   # I want any object here that is not built-in classes like those: Closure, Exception, PDO, etc...
}

$f(new UserLand); // Doesn't work as of `UserLand` do not explicit extends `stdClass`.

// So it should be reasonable to UserLand pass an `instanceof` test against `stdClass`.

?>

Should I change this to "Feature/Change Request" instead?
 [2016-12-04 08:47 UTC] requinix@php.net
> All classes defined without the `extends` expression should be implied as an
> extension of `stdClass`.
That only works if stdClass is an implied base class. It is not. UserLand and stdClass are completely and entirely unrelated classes; they have as much in common as UserLand and SplFileInfo do.

If you want this as a feature request, that's fine, but a change like this would probably require an RFC. https://wiki.php.net/rfc/howto

And I still don't understand why you can't just use is_object().
 [2016-12-04 15:13 UTC] klaussantana at gmail dot com
Probably I'll do this RFC.

Ahh.. I can't use is_object() to typecast a parameter like this:

function ( is_object($Param) )
{
}

Also, I can't use something like this:

function ( Object $Param )
{
}

Or this:

function ( object $Param )
{
}

I only can typecast objects that I explicit know the class or one of its interface names, like:

function ( UserLand $Object = null ) : UserLand
{
   return $Object;
}

Also, if you just typecast any other kind of value to an object, a stdClass object will be created. Looking at this behaviour, it just make sense that any user defined class should be a stdClass extension if ommited.

The stdClass is not used by other built-in classes. Also it has no properties or methods, having only the magic methods defined by core that does nothing. As you said, it's an empty class. So any new class should come from this empty class if not specified an ancestor. This should permit correctly test an Object to see if it is a Standard Class (stdClass) or not. Closures, Exceptions and other non-standard classes have core limitations: like the prohibition of assigning a property to a closure object. I don't want this kind of object passed as parameter, only stdClass compatible. But classes that do not explicit it will fail parameter typecasting unless I know the class name.
 
PHP Copyright © 2001-2026 The PHP Group
All rights reserved.
Last updated: Tue Oct 06 19:00:01 2026 UTC