Brainiac
Brainiac

Reputation: 295

How do I make variable classwide accessable (Object oriented Programming PHP)

I have a class named testclass and several functions in it. They all need to access one predefined variable $need_to_have. I want to define it within the class, but how?

Example:

class testclass {

  // This won't work:
  private static $need_to_have = get_some_info();

  public static testfunction1() {
    // Do Something with $need_to_have
  }

  public testfunction2 () {
    // Do something else with $need_to_have
  }

}

Forgot to mention: I want to have it privat and I'm calling the variable only on static functions, so I can't use the constructor.

Upvotes: 1

Views: 703

Answers (4)

automatix
automatix

Reputation: 14532

There is no (object oriented) way to "make variable classwide accessable". But it's not needed.

What you are looking for are object and class properties or class constants.

class TestClass {

    const TEST_CLASS_CONSTANT = 'foo';

    private static $testClassProperty;
    // or with value: private static $testClassProperty = 'bar';

    private $testObjectProperty;
    // or with value: private $testObjectProperty = 'baz';

    // This won't work
    // private static $need_to_have = get_some_info();
    // -- since you only can execute functions/methods outside of class structure
    // or within other functions/methods.

    public function testMethod() {
        // Writable access to TEST_CLASS_CONSTANT: not possible, since it's a constant.
        // Writable access to $testClassProperty: possible with keywords self, parent, and static.
        self::$testClassProperty = 'newbar';
        // Writable access to $testObjectProperty: possible with keywords this or parent.
        $this->testClassProperty = 'newbaz';

        // Readable access to TEST_CLASS_CONSTANT: possible with keywords self, parent, and static.
        echo self::TEST_CLASS_CONSTANT;
        echo PHP_EOL;
        // Readable access to $testClassProperty: possible with keywords self, parent, and static.
        echo self::$testClassProperty;
        echo PHP_EOL;
        // Readable access to $testObjectProperty: possible with keywords this or parent.
        echo $this->testClassProperty;
    }

}

$testObject = new TestClass();
$testObject->testMethod();

Upvotes: 0

Ivan Yonkov
Ivan Yonkov

Reputation: 7034

This, pretty much, has a lot of ways to do it.

The most popular way here is having a so called getter (accessor) method, which will return the current information regarding the property and it still can be private.

class TestClass {

    private static $myVar = 5;

    public static getMyVar() {
        return self::$myVar;
    }
}

So, with proper autoloader, across all your application, you will be able to call

TestClass::getMyVar();

And, as you stated in the comments, nobody will have access to change it from outside the class.

However, it could be considered bad practice, not only for the static way, as also that you should not refer to a class which you have nothing coupled to it, only to retrieve information.

Best way here is to implement registry pattern, where you can register information to the global space.

Make a separated class which implements the Registry design pattern, and maybe set some constraints, so once setted your myVar nobody can reset it, on order to be able to use the following syntax

Registry::get('myVar');

This, of course, will give you the opportunity to put some more logic in that property before registering it into the globalspace, because, defining a property, might make you troubles regarding some definitions.

Upvotes: 1

Jon
Jon

Reputation: 437376

You can't do that, because you can't initialize class properties with non-constant expressions.

What you can do is put an accessor method between you and the property, e.g.:

class testclass {

  private static $need_to_have;
  private static $need_to_have_initialized;

  public static testfunction1()
  {
    // Do Something with getNeedToHave()
  }

  private static function getNeedToHave()
  {
      if (!self::$need_to_have_initialized) {
          self::$need_to_have = get_some_info();
          self::$need_to_have_initialized = true;
      }

      return self::$need_to_have;
  }
}

If there is a constant value that get_some_info is guaranteed to never return, you can use that to initialize $need_to_have; this will allow you to get rid of the helper property $need_to_have_initialized:

// example: get_some_info() never returns false
private static $need_to_have = false;

private static function getNeedToHave()
{
    if (self::$need_to_have === false) {
        self::$need_to_have = get_some_info();
    }

    return self::$need_to_have;
}

Another possible modification (improvement?) is to make the property (and the "initialized" flag, if applicable) local static variables inside getNeedToHave; this way they won't even be visible from anywhere within the class itself:

private static function getNeedToHave()
{
    static $need_to_have = false;

    if ($need_to_have === false) {
        $need_to_have = get_some_info();
    }

    return $need_to_have;
}

Upvotes: 3

Fluffeh
Fluffeh

Reputation: 33512

Make it a property of the class, set it once and use it everywhere:

class testclass 
{

    public static $need_to_have;

    public function __construct()
    {
        //$this->need_to_have=1;
        // Or rather the value returned by 
        // whatever it is you are doing with it
        $this->need_to_have=$this->setNeed();
    }

    public function testfunction1() 
    {
        // Do Something with $need_to_have
        echo $this->need_to_have
    }

    public function testfunction2 () 
    {
        echo $this->need_to_have
    }

    public function setNeed()
    {
        $x=4;
        $y=6;
        $ret=$x*$y;
        return $ret;
    }

}

Upvotes: 0

Related Questions