6

I'm new to PHP and practicing using static variables. I decided to grab an example that I learnt from C++ and re-write it for PHP (example from the bottom of this article).

There's a class with two private variables (one static), a constructor and a get-method. The constructor assigns the static variable's value to the second private variable, and then increments.

<?php
class Something
{
    private static $s_nIDGenerator = 1;
    private $m_nID;

    public function Something() { 
       $m_nID = self::$s_nIDGenerator++;
       echo "m_nID: " . $m_nID . "</br>"; //for testing, can comment this out
    }
    public function GetID() {
        return $m_nID;
    }

}

// extra question:
// static variable can be assigned a value outside the class in C++, why not in PHP?
// Something::$s_nIDGenerator = 1; 

    $cFirst = new Something();
    $cSecond = new Something();
    $cThird = new Something();

    echo $cFirst->GetID() . "</br>";
    echo $cSecond->GetID() . "</br>";
    echo $cThird->GetID() . "</br>";
?>

Using the echo test in line 9 to see if m_nID is getting a value I see:

m_nID: 1
m_nID: 2
m_nID: 3

But these values are not being returned by the "->GetID()" calls. Any ideas why?

Edit: both replies so far have solved this, I wish I could "check" them both, so thank you! I'll leave the original code in the question as-is for any future people who have a similar problem

4

2 回答 2

9

Your background in C++ led up to this issue, which is an easy mistake to make. In PHP, all instance (or object) variables are referenced using $this->, and static (or class) variables with self::. Based on your code:

public function GetID() {
    return $m_nID;
}

Access to the private variable $m_nID should be scoped like this:

public function GetID() {
    return $this->m_nID;
}

And inside your constructor:

$m_nID = self::$s_nIDGenerator++;

It should have been:

$this->m_nID = self::$s_nIDGenerator++;

Q & A

Why is there no need to put $ before m_nID when using $this->

The above two ways of referencing instance and class variables come with a very different kind of syntax:

  1. $this is the instance reference variable and any properties are accessed using the -> operator; the $ is not repeated for the property names themselves, although they're present in the declaration (e.g. private $myprop).

  2. self:: is synonymous to Something:: (the class name itself); it doesn't reference an instance variable and therefore has no $ in front of it. To differentiate static variables from class constants (self::MYCONST) and class methods (self::myMethod()) it's prefixed with a $.

Extra

That said, $this->$myvar is accepted too and works like this:

private $foo = 'hello world';

function test()
{
    $myvar = 'foo';
    echo $this->$foo; // echoes 'hello world'
}
于 2012-12-20T03:38:45.930 回答
2
class Something{
    private static $s_nIDGenerator = 1;
    private $m_nID;

    public function Something() { 
       $this->m_nID = self::$s_nIDGenerator++;
    }
    public function GetID() {
        return $this->m_nID;
    }

}

It is interesting to note the difference between using self::$s_nIDGenerator on a static variable vs using $this->s_nIDGenerator on a static variable, whereas $this-> will not store anything.

于 2012-12-20T03:44:44.593 回答