Skip to content

Instantly share code, notes, and snippets.

@everzet
Created December 5, 2012 13:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save everzet/4215537 to your computer and use it in GitHub Desktop.
Save everzet/4215537 to your computer and use it in GitHub Desktop.
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
Copy link

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
Copy link

mauris commented Dec 5, 2012

Or simply write

parent::__construct();

in your constructor.

@gries
Copy link

gries 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
Copy link

gries commented Dec 5, 2012

@thephpdeveloper This wont work either.

SplFileObject requires a valid path to an existing file.

@everzet
Copy link
Author

everzet commented Dec 5, 2012

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

@gries
Copy link

gries 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
Copy link

hason commented Dec 5, 2012

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

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

@jubianchi
Copy link

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

@everzet
Copy link
Author

everzet commented Dec 12, 2012

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

@nackjicholson
Copy link

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

@bkuhl
Copy link

bkuhl 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
Copy link

cabloo commented Jun 26, 2016

@nackjicholson thanks for that one!

@sslgeorge
Copy link

You are the bomb @nackjicholson

@DanWithams7d
Copy link

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