Cat
Cat

Reputation: 7312

How to load variables only when needed in PHP

I have a class with multiple public properties whose objects are being used in different parts of the system. The problem is that I need to load only some of those public properties in each place I'm using the objects of the class, because loading the entire list of properties every time would take forever.

Is there any way I can use __autoload or a similar function to call the functions that load different variables at the time they are called?

E.g.

class Bread {
  public 
    $Ingredients,
    $Price,
    $Color;

  public function magicLoading($var) {
    switch($var) {
      case "Ingredients" : return loadIngredients();
      case "Price"       : return loadPrice();
      case "Color"       : return loadColor();
      default            : break;
    }
  }

  public function loadIngredients() {
    $this->Ingredients = ...
  }
}

foreach($Bread->Ingredients as $Ingredient) {
  //do stuff here
}

Upvotes: 2

Views: 1037

Answers (3)

jd.
jd.

Reputation: 4098

In your code,

  • rename the function magicLoading to __get,
  • add a return statement in your 'load...' methods
  • check that the variables have not been initialized yet.

And it works !

Upvotes: 1

Peter Bailey
Peter Bailey

Reputation: 105908

Apologies to my colleagues for posting what looks like a duplicate answer, but they have missed something.

In order for the __get() and __set() hooks to function properly, the member variable in question cannot be declared at all - simply being declared but undefined isn't sufficient.

This means you'll have to remove the declaration of any variables you want to be accessible in this way (i.e., the public $Ingredients; etc)

Ergo, your class might then look like this.

class Bread
{
  /* No variable declarations or the magic methods won't execute */

  protected function loadIngredients()
  {
    $this->Ingredients = ...
  }

  public function __get( $var )
  {
    switch( $var )
    {
      case "Ingredients" : $this->loadIngredients(); break;
      case "Price"       : $this->loadPrice(); break;
      case "Color"       : $this->loadColor(); break;
      default            : throw new Exception( "No case for $var" );
    }
    return $this->$var;
  }
}

Upvotes: 1

AndreKR
AndreKR

Reputation: 33697

Yes, you can create the magic method __get that is called every time a property (that is not yet initialized) of the class is read.

Upvotes: 0

Related Questions