3

Let's say I have a class Bla that contains the variable $x.

I want this variable $x to keep its value for other objects once it's set by the first created object.

For example:

$object1 = new bla(.....);
$object1->setx();
$object1->getx();

$object2 = new bla(.....);
$object2->getx();

So I want:

 $object2->getx()

...to give me the value I already set by object1.

I tried using $x as a globale variable inside the class, it turns out that it's not possible. Can I use it outside the class and then access this variable inside the class?

What are the other methods?

4
  • Check out for the static properties php.net/manual/en/language.oop5.static.php Commented Jul 5, 2013 at 10:46
  • @zerkms if I used static, then I cant set it using the first object right? Commented Jul 5, 2013 at 10:48
  • uhm, nope. A static property is a property that belongs to a class, not to a particular instance. So its value is shared across all the objects of a particular class. Commented Jul 5, 2013 at 10:48
  • 1
    Relevant GoogleTechTalk about Global State youtube.com/watch?v=-FRm3VPhseI Commented Jul 5, 2013 at 10:52

5 Answers 5

5

Use static variables if you want them to have one and the same value, available regardless of their class instances (tutorial):

class bla
{
    private static $x;

    public function setx($x) {
        self::$x = $x;
    }

    public function getx() {
        return self::$x;
    }
}

$object1 = new bla();
$object1->setx(5);
echo $object1->getx();
echo '<br>';

$object2 = new bla();
echo $object2->getx();

Output:

5
5
Sign up to request clarification or add additional context in comments.

5 Comments

if I used static, then I cant set it using the first object right?
@maggie: where did you find that?
it's giving me "Strict standards: Accessing static property Wind1::$temperature as non static" note I'm using $this instead of self
I declared $temperature as private static
You cant use this with static variables!
0
class Bla {
    static private $x = "X!";
}

If you know what x should be at initialisation then just use the above. If x is computed then you can ensure it's only set once:

class Bla {
    static private $x = null;
    public function getX(){
        if($this->x === null){
            $this->x = theLogicToGetX();
        }
        return $this->x;
    }
}

Only the first call will set x and subsequent calls will use that value.

Comments

0

See with example:

<?php
class Foo {
    private static $my_static = 'foo';
    /**
     * Set static class property
     * 
     * @param string $v
     */
    public function setStaticValue($v) {
        self::$my_static = $v;
    }
    /**
     * Get static class property value
     * 
     * @return string
     */
    public function getStaticValue() {
        return self::$my_static;
    }
}
// show class static property value
echo foo::getStaticValue(); // foo
// now set new value in static property
foo::setStaticValue(' zoo ');
// show value
echo foo::getStaticValue(); // zoo
// make an object of class
$f = new Foo();
// show value
echo $f->getStaticValue(); // zoo
// make new object of class
$f2 = new Foo();
// show value
echo $f2->getStaticValue(); // zoo

Comments

0

It is possible with references

class A
{
  private $a;

  public function &getA(){return $this->a;}
  public function setA($a) { $this->a = $a;}  
}

class B
{
  public function useA(&$a) { $a+=5 ;}
}

$objA = new A();
$objB = new B();
$objA->setA(5); //seting value of a in A class to 5
$objB->useA($objA->getA()); //modify the reference of A class $a variable in B class object

echo $objA->getA(); //echo the value from A class object

Output: 10

My solution doesn't have static limitations. So it can be used on multiple objects of same class. If you want to have access to class variable by same class objects use static as suggested above by Lukas.

There is also registry pattern which you should take a look at. Registry pattern makes you able to access variable in whole php application.

The idea of a Registry is simple: providing a dynamic possibility for discovering collaborator objects, so that we not hardcode static calls to global objects like Singletons in each of them. In the testing environment, we can fill the Registry with mocks.

 class Registry
 {
    private static $instance;
    private $registry = array();
    private function __construct()
    {

    }

    public function  getInstance()
    {
         if(self::$instance == null) self::$instance = new Registry();
            return self::$instance;
    }

    public function __set($var,$val)
    {
       $this->registry[$var] = $val;
    }

    public function __get($var)
    {
       if(isset($this->registry[$var]))
            return $this->registry[$var];
       else throw new Exception("Value $var doesn't exists in registry");
    }



 }


 class A
 {
   public function useVar()
   {
     Registry::getInstance()->myVar += 10;
   }

   public function echoVar()
   {
     echo Registry::getInstance()->myVar;
   }
 }

 Registry::getInstance()->myVar = 5;
 $obj1 = new A();
 $obj2 = new A();

 $obj1->useVar();
 $obj2->echoVar();

OUTPUT: 15

Comments

0

Yeah, you can make this functionality. From here "global variable" means kind of variables, mentioned in the question.

You can use static variable of the class to store the value of global variable.

class Bla {
    static private $x;
}

To access this variable we can use couple of methods:

Make special setters and getters, I would recommend this as most simple and clear way:

class Bla {
    static private $x = 'init value';

    public function getX() {
        return self::$x;
    }

    public function setX($value) {
        self::$x = $value;
    }
}

// Usage:
$obj1 = new Bla();
echo $obj1->getX();// init value
$obj1->setX('changed value');

Of course if appropriate you can use just static access syntax (public variables or static setters and getters), which is even more simple and clear, than first method. For example:

class Bla {
    static public $x = 'init value';
}

// Usage:
echo Bla::$x;
Bla::$x = 3;

Also take in mind that objects are passing by references in PHP5.

class Bla {
    private $date;

    public function __construct(DateTime $x) {
        $this->date = $x;
    }

    public function getDate() {
        return $this->date;
    }
}

$date = new DateTime();

// Usage:
$obj1 = new Bla($date);
$obj2 = new Bla($date);
/* now play with $objN->getDate()->.. and $date->.. 
 * to see, that $x in both objects are referring to same variable. */

Now lets see at some not so good ways.

We can use magic setters and getters, which combined of a phpDoc can "emulate" behaviour of a real object variable (i mean in runtime it will get and set variable and in IDE, which supports phpDoc, you can even see variable in auto-completion). This solution violates the principle of encapsulation, so i wouldn't recommend common usage of it.

/**
 * @property mixed $x My global var.
 */
class Bla {
    static private $x = 'init value';

    public function __set($name, $value) {
        if ($name == 'x') {
            self::$x = $value;
        }
    }

    public function __get($name) {
        if ($name == 'x') {
            return self::$x;
        }
    }
}
// Usage:
$obj1 = new Bla();
echo $obj1->x;// init value
$obj1->x = 'changed value';

Same behaviour without magic we can get using references:

class Bla {
    static $storage = 'init value';
    public $x;

    public function __construct() {
        $this->x = &self::$storage;
    }
}

Also we can make $x here private and add special access methods, what makes sense only if you HATE to use static syntax (self::).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.