Scope issue with __construct()

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
Quintok
Forum Newbie
Posts: 2
Joined: Wed Jul 04, 2007 11:34 pm

Scope issue with __construct()

Post by Quintok »

Hello All, I apologise in advance my first post is a request for help, I know how irritating that can be.

I think I've made a quite obvious mistake it's just I can't figure out what it is.
For some reason php doesn't seem to like me referencing external global (is it global?) variables from inside a constructor of another class in another file. Here are my three files and their corresponding contents, I've written two copies of "loadSecond.php" one that works and one that does not but I'd like it to.

I'm using v5.2.3

index.php

Code: Select all

<?php
include_once "loadFirst.php";
include_once "loadSecond.php";
?>
loadFirst.php

Code: Select all

<?php
class FirstLoaded
{
   function test()
   {
      echo "hurrah!";
   }
}
$FirstLoaded = new FirstLoaded();
?>
loadSecond.php that does not work

Code: Select all

<?php
class foo
{
   function __construct()
   {
      $FirstLoaded->test();
   }
}
$foo = new foo();
?>
loadSecond.php that does work

Code: Select all

<?php
$FirstLoaded->test();
?>
here is the output
Notice: Undefined variable: FirstLoaded in C:\Inetpub\wwwroot\new\loadSecond.php on line 6

Fatal error: Call to a member function test() on a non-object in C:\Inetpub\wwwroot\new\loadSecond.php on line 6
thank you for any possible help.
User avatar
John Cartwright
Site Admin
Posts: 11470
Joined: Tue Dec 23, 2003 2:10 am
Location: Toronto
Contact:

Post by John Cartwright »

The manual explains everything on scope :wink:

To solve your situation, you need to pass the object to the class.

Code: Select all

class foo
{
   function __construct($FirstLoaded)
   {
      $FirstLoaded->test();
   }
}

$FirstLoaded = new someotherclass();

$foo = new foo($FirstLoaded);
User avatar
Zoxive
Forum Regular
Posts: 974
Joined: Fri Apr 01, 2005 4:37 pm
Location: Bay City, Michigan

Post by Zoxive »

$FirstLoaded isn't global.

So either do

Code: Select all

<?php
class foo
{
   function __construct()
   {
      GLOBAL $FirstLoaded;
      $FirstLoaded->test();
      // OR
      FirstLoaded::test();
   }
}
$foo = new foo();
Quintok
Forum Newbie
Posts: 2
Joined: Wed Jul 04, 2007 11:34 pm

Post by Quintok »

thank you for your replies.
I had actually tried global in my actual code and it'd thrown up a similar error to my example I posted here however it was for an unrelated problem (forgot a '$') when I tried the equivilent of:

Code: Select all

<?php
class foo
{
   function __construct()
   {
      global $FirstLoaded;
      $FirstLoaded->test();
   }
}
$foo = new foo();
?>
which lead me to believe that 'global' was not the solution :)
thanks for the help.
miro_igov
Forum Contributor
Posts: 485
Joined: Fri Mar 31, 2006 5:06 am
Location: Bulgaria

Post by miro_igov »

Zoxive forgot to

Code: Select all

}
$FirstLoaded = new FirstLoaded();
before to the

Code: Select all

$foo = new foo()
This will work with global , but using globals is not good idea. Better pass the first class as parameter.
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

Using the global keyword is bad practice. Pass the object into the constructor as Jcart suggests.
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

Post by Chris Corbyn »

If FirstLoaded will always be the same object instance, you may want to look at the singleton or the registry pattern. I'll show the singleton because it's simple to demonstrate, although used wrongly it will get you in sticky situations:

Code: Select all

class FirstLoaded {
  private static $_instance = null;

  private function __construct() {} //So it can't be instantiated publically

  public static function getInstance() {
    if (self::$_instance === null) self::$_instance = new self();
    return self::$_instance;
  }
  
  public function test() {
  }
}

class SecondLoaded {
  public function __construct() {
    $firstLoaded = FirstLoaded::getInstance();
    $firstLoaded->test();
  }
}

$firstLoaded = FirstLoaded::getInstance();
$secondLoaded = new SecondLoaded();
Post Reply