Skip to content

Instantly share code, notes, and snippets.

@everzet everzet/console
Created Dec 5, 2012

Embed
What would you like to do?
Why, php? WHY???
PHP Fatal error: Uncaught exception 'LogicException' with message 'The parent constructor was not called: the object is in an invalid state ' in splfileobject.php:16
Stack trace:
splfileobject.php(16): SplFileInfo->_bad_state_ex()
#1 {main}
thrown in splfileobject.php on line 16
Fatal error: Uncaught exception 'LogicException' with message 'The parent constructor was not called: the object is in an invalid state ' in splfileobject.php:16
Stack trace:
#0 splfileobject.php(16): SplFileInfo->_bad_state_ex()
#1 {main}
thrown in splfileobject.php on line 16
<?php
class cls1 extends \SplFileObject
{
public function __construct()
{
}
public function fpassthru()
{
// does nothing
}
}
$cl = new cls1;
$cl->fpassthru();
@jubianchi

This comment has been minimized.

Copy link

commented Dec 5, 2012

Some internal PHP classes enforce parent constructor call...
If your constructor does nothing, just don't implement it to fallback to the parent one.

@mauris

This comment has been minimized.

Copy link

commented Dec 5, 2012

Or simply write

parent::__construct();

in your constructor.

@gries

This comment has been minimized.

Copy link

commented Dec 5, 2012

afaik. the SplFileObject sets the required parameter $filename passed to parent::__construct as a private property that is used for all other methods provided by the class.

I'm really no theoretical OOP-Expert, but if you extend a parent Class that requires a parameter in its __construct, and this parameter is set as a protected property.
Isn't it the responsibility of the Child-Class to either initialize the Object corretctly or to call the parent __construct ?

@gries

This comment has been minimized.

Copy link

commented Dec 5, 2012

@thephpdeveloper This wont work either.

SplFileObject requires a valid path to an existing file.

@everzet

This comment has been minimized.

Copy link
Owner Author

commented Dec 5, 2012

@gries i'm actually trying to mock this class, not extend.

@gries

This comment has been minimized.

Copy link

commented Dec 5, 2012

@everzet yeah you extend it to create a mock, but you extend it.
I asked the internals-list they basically say: "this is the way the class is designed deal with it"
I am right now editing the documentation to add a INFO section that makes the user aware of this issue.

@hason

This comment has been minimized.

Copy link

commented Dec 5, 2012

class cls1 extends \SplFileObject
{
    public function __construct()
    {
        parent::__construct('php://memory');
    }

    public function fpassthru()
    {
        // does nothing
    }
}
@jubianchi

This comment has been minimized.

Copy link

commented Dec 5, 2012

@everzet : I think @mageekguy found a way to mock these class in atoum. Perhaps you could ask him for tips ;)

@everzet

This comment has been minimized.

Copy link
Owner Author

commented Dec 12, 2012

@jubianchi there's no clean way to mock this class. And i already know dirty one...

@nackjicholson

This comment has been minimized.

Copy link

commented Jun 26, 2014

$fileObject = $this->getMock('SplFileObject', [], ['php://memory']);

@bkuhl

This comment has been minimized.

Copy link

commented Jun 26, 2014

Thank you for posting that solution! Just stumbled across this in Google while trying to mock the same object. You saved me a bunch of time I'm sure!

@cabloo

This comment has been minimized.

Copy link

commented Jun 26, 2016

@nackjicholson thanks for that one!

@sslgeorge

This comment has been minimized.

Copy link

commented Jul 3, 2017

You are the bomb @nackjicholson

@DanWithams7d

This comment has been minimized.

Copy link

commented Dec 19, 2017

For anyone who wants details about what is actually happening here;

SplFileObject will throw this error if you either;

  1. Do not call the parent::__construct() at all.
    or
  2. If you try to call other class methods (e.g. $this->callSomething()) BEFORE calling he parent::__construct(). The scope of the called method is irrelevant, so if you are calling a native SplFileObject/SplFileInfo method or a method in the scope of your superclass it will error. You can do other things before the parent::__construct() as long as they are not interacting with $this, parent:: or self:: (not sure about static methods. I assume the same goes for reading/writing properties but I haven't tested this. Ensure that anything you need to do is done pre-parent construct is done directly in the superclass construct and not abstracted to other methods if you can help it.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.