1.2.373. Don’t Send $this In Constructor

Don’t use $this as an argument while in the __construct(). Until the constructor is finished, the object is not finished, and may be in an unstable state. Providing it to another code may lead to error.

This is true when the receiving structure puts the incoming object immediately to work, and don’t store it for later use.

<?php

// $this is only provided when Foo is constructed
class Foo {
    private $bar = null;
    private $data = array();

    static public function build($data) {
        $foo = new Foo($data);
        // Can't build in one call. Must make it separate.
        $foo->finalize();
    }

    private function __construct($data) {
        // $this is provided too early
        $this->data = $data;
    }

    function finalize() {
        $this->bar = new Bar($this);
    }
}

// $this is provided too early, leading to error in Bar
class Foo2 extends Foo {
    private $bar = null;
    private $data = array();

    function __construct($data) {
        // $this is provided too early
        $this->bar = new Bar($this);
        $this->data = $data;
    }
}

class Bar {
    function __construct(Foo $foo) {
        // the cache is now initialized with a wrong
        $this->cache = $foo->getIt();
    }
}

?>

See also Don’t pass this out of a constructor.

1.2.373.1. Suggestions

  • Finish the constructor first, then call an external object.

  • Sending $this should be made accessible in a separate method, so external objects may call it.

  • Sending the current may be the responsibility of the method creating the object.

1.2.373.2. Specs

Short name

Classes/DontSendThisInConstructor

Rulesets

All, Analyze

Exakat since

1.0.4

PHP Version

All

Severity

Minor

Time To Fix

Slow (1 hour)

Precision

Very high

Features

$this, constructor

Examples

Woocommerce, Contao

Available in

Entreprise Edition, Exakat Cloud