-1

I have this 2 classes:

class EventScripts {
protected $database;
private $test;

public function __construct(Database $database) {
    $this->database = $database;
}

public function ScriptA($callTime, $params) {
    // Does NOT output the information of the database. It simply does nothing and the code aborts.
    var_dump($this->database);
    return $params;
}   
}

class EventSystem {

protected $database;
protected static $results;

public function __construct(Database $database) {
    $this->database = $database;
}


public function handleEvents() {

    // outputs the array with information of the database
    var_dump($this->database);

    $EventScripts = new EventScripts($this->database);
    $EventScripts->ScriptA(5, "test");          
}
}

I call EventSystem like this:

try {
    $database = new Database("host", "user", "password", "database");
    $EventSystem = new EventSystem($database);
} catch (Exception $e) {
    echo $e->getMessage();
}

$EventSystem->handleEvents();

Now the var_dump() in EventSystem correctly shows me the information of the database that is saved in the protected $database-variable.

But when I do this exact thing in the ScriptA()-method, nothing happens and the code aborts. It even doesn't return anything anymore.

Where is my mistake?

SwiftedMind
  • 3,701
  • 3
  • 29
  • 63
  • Show the code calling `ScriptA` method – hindmost Apr 26 '14 at 09:17
  • What do you mean? There is shown the `ScriptA` method – SwiftedMind Apr 26 '14 at 09:19
  • @hindmost look the method handleEvents() carefully inside the class eventsystem – shanavascet Apr 26 '14 at 09:21
  • 1
    I *strongly* recommend to you that you enable error reporting and logging to the highest level while you're developing and debugging. Watch for notices and warnings. http://stackoverflow.com/q/845021/367456 – hakre Apr 26 '14 at 09:28
  • Unable to reproduce even: http://3v4l.org/pIg9X – hakre Apr 26 '14 at 09:34
  • @hakre I just had `error_reporting(E_ALL);` and it showed nothing. Now with the other settings I get 500 Internal Server Error I don't understand why you're code is working. I have nearly exactly the same. I just don't use a string, but a real database – SwiftedMind Apr 26 '14 at 10:13
  • 500 internal server error is an invitation to look into the error log of your webserver. it should contain more on that one. – hakre Apr 27 '14 at 07:09

1 Answers1

1

Protected members of classes are available to the class and inherited classes of it. Not to entirely different classes.

In you can you can extend both classes from one (perhaps abstract) class that is "with database" and it has that details encapsulated as a protected member.

abstract class DatabaseBased
{
    /**
     * @var Database
     */
    protected $database;

    public function __construct(Database $database)
    {
        $this->setDatabase($database);
    }

    protected function setDatabase(Database $database)
    {
        $this->database = $database;
    }
}

Here the one class you had problems with:

class EventScripts extends DatabaseBased
{
    private $test;

    public function ScriptA($callTime, $params)
    {
        var_dump($this->database);

        return $params;
    }
}

When you now create the other object, you can inject the database directly:

public function handleEvents() {

    // outputs the array with information of the database
    $EventScripts = new EventScripts();
    $EventScripts->setDatabase($this->database);
    $EventScripts->ScriptA(5, "test");
}
hakre
  • 193,403
  • 52
  • 435
  • 836
  • I tried to use the way explained on this site [link](http://kunststube.net/static/). Is there no way to directly set the database when creating the instance? But this is a nice way, I will try it out – SwiftedMind Apr 26 '14 at 10:17
  • Okay, I tried it out, but I get this error: `Fatal error: Using $this when not in object context in /mnt/webg/e3/36/52873436/htdocs/avalon/images/test/events.php on line 13`. line 13 is `var_dump($this->database);` – SwiftedMind Apr 26 '14 at 15:59
  • Okay, it works. My fault. Your answer is correct and working :) Thank you – SwiftedMind Apr 27 '14 at 06:42
  • 1
    @Akeno: My answer might have been a little misleading. As I found out later, your problem was not about inheritance but something different, in fact, as I commented then, I was not able to reproduce your error. My answer uses setter injection. You example uses constructor injection. I think constructor injection is fine. Find out the exact cause of error, then fix the cause. Keep this answer only as an additional example for protected usage across "friendly" types (e.g. a layer sharing resources). – hakre Apr 27 '14 at 07:12