36

I understand that there are two ways to access a PHP class - "::" and "->". Sometime one seems to work for me, while the other doesn't, and I don't understand why.

What are the benefits of each, and what is the right situation to use either?

johnnietheblack
  • 13,050
  • 28
  • 95
  • 133

7 Answers7

78

Simply put, :: is for class-level properties, and -> is for object-level properties.

If the property belongs to the class, use ::

If the property belongs to an instance of the class, use ->

class Tester
{
  public $foo;
  const BLAH;

  public static function bar(){}
}

$t = new Tester;
$t->foo;
Tester::bar();
Tester::BLAH;
Peter Bailey
  • 105,256
  • 31
  • 182
  • 206
  • 1
    so, for example...if i have a library class and in it, a function that will return a connect to my MySQL (basically as a singleton), i can and should refer to it by doing something like library::connect(); rather than $libraryObject->connect(); ? – johnnietheblack Aug 03 '09 at 22:19
  • also, if i use the object, i have to pass it into other functions, but if i use the static operator, i can avoid scope issues? thanks in advance! – johnnietheblack Aug 03 '09 at 22:21
  • 2
    @jonnietheblack: There's no *should*, it's a matter of what you want to do. If you want to use an Object that you can pass around, copy, clone etc, you instantiate the Object from the Class (using `new Class`) and from then on use things inside the Object with `->`. If you're not instantiating an Object, but just want to call the Class functions "as they are", you use `::`. It really depends on your usage of the Class, one method isn't better than the other. – deceze Aug 03 '09 at 23:24
  • 2
    To put it another way: `$object->func()` is okay, notice that `$object` is a variable, i.e. it's instantiated. `ClassName::func()` is also okay, notice that `ClassName` is not a variable, it's just the class name. `$object::func()` is not good, you're trying to call a method statically on an instantiated object. `ClassName->func()` is also no good for the reverse reason. – deceze Aug 03 '09 at 23:30
  • too much simplification... anyone reading this answer, please check all the pro/con of using static. i read someone going as far as saying "static methods are not OOP, they are procedural code in disguise" – wlf Oct 22 '20 at 15:33
9

The "::" symbol is for accessing methods / properties of an object that have been declared with the static keyword, "->" is for accessing the methods / properties of an object that represent instance methods / properties.

Cody Caughlan
  • 32,456
  • 5
  • 63
  • 68
  • 8
    It's a bit incorrect to say 'with the static keyword'. That's not the only case - accessing parent methods and constants both require the `::` operator, neither of which have to be declared static. – Peter Bailey Aug 03 '09 at 21:53
6

Php can be confusing in this regard you should read this.

What's also confusing is that you can call non static functions with the :: symbol. This is very strange when you come from Java. And it certainly surprised me when I first saw it.

For example:

class Car
{
    public $name = "Herbie <br/>";

    public function drive()
    {
        echo "driving <br/>";
    }

    public static function gas()
    {
        echo "pedal to the metal<br/>";
    }
} 

Car::drive(); //will work
Car::gas(); //will work

$car = new Car();
$car->drive(); // will work
$car->gas(); //will work

echo $car->name; // will work
echo Car::$name; // wont work error

As you can see static is very loose in php. And you can call any function with both the -> and the :: symbols. But there is a difference when you call with :: there is no $this reference to an instance. See example #1 in the manual.

Justin
  • 26,443
  • 16
  • 111
  • 128
MrHus
  • 32,888
  • 6
  • 31
  • 31
5

When you declare a class, it is by default 'static'. You can access any method in that class using the :: operator, and in any scope. This means if I create a lib class, I can access it wherever I want and it doesn't need to be globaled:

class lib
{
    static function foo()
    {
       echo "hi";
    }
}
lib::foo(); // prints hi

Now, when you create an instance of this class by using the new keyword, you use -> to access methods and values, because you are referring to that specific instance of the class. You can think of -> as inside of. (Note, you must remove the static keyword) IE:

class lib
    {
        function foo()
        {
           echo "hi";
        }
    }
$class = new lib;
$class->foo(); // I am accessing the foo() method INSIDE of the $class instance of lib.
Tyler Carter
  • 60,743
  • 20
  • 130
  • 150
1

It should also be noted that every static function can also be called using an instance of the class but not the other way around.

So this works:

class Foo
{
  public static function bar(){}
}

$f = new Foo();
$f->bar(); //works
Foo::bar(); //works

And this doesn't:

class Foo
{
  protected $test="fddf";
  public function bar(){ echo $this->test; }
}

$f = new Foo();
$f->bar(); //works
Foo::bar(); //fails because $this->test can't be accessed from a static call

Of course you should restrict yourself to calling static methods in a static way, because instantiating an instance not only costs memory but also doesn't make much sense.

This explanation was mainly to illustrate why it worked for you some of the times.

André Hoffmann
  • 3,505
  • 1
  • 25
  • 39
  • That wouldn't make any sense, since without an instance there are no non-static variables that this method could access. Did you try that? If so what version did you use? Besides if it would work, the static keyword wouldn't bring any changes to a method either. – André Hoffmann Aug 03 '09 at 22:39
  • Just gave that a try and figured out that it only dies when you are calling a dynamic method which is using dynamic variables in a static context. PHP seriously lacks a clear coding style in some aspects :-/ – André Hoffmann Aug 03 '09 at 22:52
1

:: is used to access a class static property. And -> is used to access a class instance ( Object's ) property.

Consider this Product class that has two functions for retrieving product details. One function getProductDetails belongs to the instance of a class, while the other getProductDetailsStatic belongs to the class only.

class Product {
  protected $product_id;

  public function __construct($product_id) {
    $this->product_id = $product_id;
  }

  public function getProductDetails() {
     $sql = "select * from products where product_id= $this->product_id ";
     return Database::execute($sql);
  }

  public static function getProductDetailsStatic($product_id) {
     $sql = "select * from products where product_id= $product_id ";
     return Database::execute($sql);
  }
}

Let's Get Products:

$product = new Product('129033'); // passing product id to constructor
var_dump( $product->getProductDetails() ); // would get me product details

var_dump( Product::getProductDetailsStatic('129033') ); // would also get me product details

When to you use Static properties?

Consider this class that may not require a instantiation:

class Helper {
  static function bin2hex($string = '') {
  }
  static function encryptData($data = '') {
  }
  static function string2Url($string = '') {
  }
  static function generateRandomString() {
  }
}
popeye
  • 481
  • 1
  • 4
  • 16
0

Sourcing WikiPedia - Class

In object-oriented programming, a class is a programming language construct that is used as a blueprint to create objects. This blueprint describes the state and behavior that the created objects all share. An object created by a class is an instance of the class, and the class that created that instance can be considered as the type of that object, e.g. a type of an object created by a "Fruit" class would be "Fruit".

The :: operator accesses class methods and properties which are defined in php using the static keyword. Class const are also accessed using ::

The -> operator accesses methods and properties of an Instance of the class.

If the function operates on an instance, you'll be using ->. If it operates on the class itself, you'll be using ::

Another use of :: would be when you want to call your parent functions. If one class inherits another - it can override methods from the parent class, then call them using parent::function()

gnarf
  • 105,192
  • 25
  • 127
  • 161