What is the difference between Static and self in PHP?

Asked

Viewed 16,118 times

27

What’s the difference between static and self? Exemplify situations that justify your different uses. What does this have to do with late Static Binding?

4 answers

27


static is used to define that a method or attribute in a class is static. This means (as someone who knows OO must know) that that method/attribute belongs to the class and not to an instance of it and can therefore be accessed without instilling a new object.

Example:

<?php
class Foo
{
    public static $meu_estatico = 'foo';

    public function valorEstatico() {
        return self::$meu_estatico;
    }
}

It is possible to use something like :

print Foo::$meu_estatico . "\n";

Pure like that, without it being necessary to make a $a = new Foo() before.

Note in the example that the self, that was also questioned. It is only used to use a static variable within the class that contains it.

$a = new Foo();
echo $a->valorEstatico() // tem como saída "foo"

It is important to make clear that a static value belongs to the class and not to the instances, but can be used within the class via self.

This is very interesting for values you want available for the entire application, for example. If they change in the class only once the entire application has access to the same values.

These examples were taken from http://www.php.net/manual/en/language.oop5.static.php

AFTER UPDATE OF THE QUESTION . . .

When a class uses a static method that has been inherited from another, static values within that inherited method will refer to the parent class if the self. To use the specialized class (daughter) as a reference for these static values, the self Static Binding is used. Understand Binding as "link" (I don’t know if it helps much) . Quoting doc is an example:

This feature was named "late Static bindings" with a pespectiva internal in mind. "Late Binding" comes from the fact that Static:: no longer be solved using the class where it is set but it will be evaluated using runtime information. It was also called "Static Binding" as can be used for (but not limited to) call for static methods. (http://php.net/lsb)

Examples (also of Ocds, but merged the two)

<?php
class A {
    public static function who() {
        echo __CLASS__;
    }
    public static function test() {
        self::who(); // Isso vai sair como "A", o nome da classe mãe 
    } 
    public static function test2() {
        static::who(); // Já esse aqui vai sair "B", o nome da classe filha    
    }  
}  

class B extends A {      
    public static function who() {
         echo __CLASS__;
    }  
}   

B::test(); // Isso vai sair como "A", o nome da classe mãe 
B::test2(); // Já esse aqui vai sair "B", o nome da classe filha  
?>

11

self serves to access class properties within itself, that is, for all instances there will only be a single value since the property is class. static is a qualifier that generates a class property instead of an object property or class instance, the code below exemplifies the use of the two and also differentiates a property of an object from the class of a class property:

<?php
    class X {
        private $non_static_member = 1; //propriedade do objeto da classe
        private static $static_member = 2; // propriedade da classe

        function __construct() {
            // Acessando propriedade do objeto da classe
            echo $this->non_static_member . ' '
              // Acessando propriedade da classe  
              . self::$static_member;
        }
    }
    // Precisamos instanciar a classe para acessar as propriedades do objeto criado.
    (new X())->$non_static_member;
    // Acessamos a partir da classe.
    X::static_member

?>

Basically late Static Binding is used to reference a specialization (daughter class) from an implementation performed in the generalized class (mother class), allowing polymorphism between daughter classes.

<?php
    class DartVader {
        public static function say() {
           echo "I'm your father";
        }
        public static function sayToLuky() {
           self::say(); // "I'm your father" 
        } 
        public static function sayToDartVader() {
           static::say(); // Can be "Han Solo my love!" or "Noooooo!"    
        }
    }

    class Luke extends DartVader {      
        public static function say() {
            echo "Noooooo!";
        }  
    }   

    class Leia extends DartVader {
        public static function say() {
            echo "Han Solo my love!";
        }
    }

    Leia::sayToDartVader() // "Han Solo my love!"
    Leia::sayToLuky() // "I'm your father"
    Luke::sayToDartVader() // "Noooooo!"
    Luke::sayToLuky() // "I'm your father"
?>
  • 1

    +1 being +0.5 for correctness and +0.5 for references to Star Wars.

4

Self

A keyword self Accesses a property within the class and is equivalent to: $this. Ex.:

class Foo {
  function __construct() {
    return self::bar();
  }

  public function bar() {
    return "bar";
  }
}

When executing $foo = new Foo() is returned the value of the bar function within the class.

Static

A keyword static makes a function accessible without the need to instantiate the class where it is "hosted". For example:

class Foo {
  public static function bar() {
    return get_class() . "bar";
  }
}
echo Foo::bar();

This code will be printed Foobar. Recapping self serves to access functions or variables that are within a class and is equivalent to $this, already static serves to access functions or variables without calling a class.

Late Static Bindings

This is how much is inherited by another static attributes class.

0

Given the excellent answers, I want to emphasize the question of inheritance. But first, let’s recap the following:


self:

It is used to return the value of a property or call (run) some static method - MUST be used WITHIN of the class in question with the operator ::;

static:

Is used for:

  1. Declare a property or method to be static. That is, it is not necessary to instantiate the class in question (new MinhaClasse(););

  2. Return the value of a static property or call (run) some static method - CAN be used INSIDE AND OUTSIDE of the relevant class with the same operator ::;


Inheritance

Consider the following code:

class Foo
{
    public static $variavel = 'Valor A';

    public static function valorVariavel
    {
        return self::$variavel;
    }
}

echo Foo::valorVariavel(); // retorna "Valor A" que pertence a classe "Foo";

I declared the class Foo with the static method valorVariavel() that returns the value of static property $variavel. Then I called the static method with the operator :: (instead of the operator ->).

Now that comes the catjump! Consider the following code:

class Bar extends Foo
{
    public static $variavel = 'Valor B';
}

echo Bar::valorVariavel(); // retorna "Valor A" que pertence a classe "Foo";

In class Bar declared the static property $variavel worthwhile Valor B, but when calling the method, returns Valor A.

This happens because the self returns what’s in your class. Whether property or method.

To circumvent this, we can return the property value with static, instead of self:

class Foo
{
    public static $variavel = 'Valor A';

    public static function valorVariavel()
    {
        return static::$variavel;
    }
}

class Bar extends Foo
{
    public static $variavel = 'Valor B';
}

echo Foo::valorVariavel(); // retorna "Valor A" que pertence a classe "Foo";
echo Bar::valorVariavel(); // retorna "Valor B" que pertence a classe "Bar";

With static, we always return the value of the LAST DECLARATION, following the order of inheritance (see next example).

It is also legal to always declare static properties in child classes when you want to change their value. Or else the value of the parent class (which has been extended) will be overwritten. What would eventually affect all other classes extending this same parent class that are being instantiated/called later in the same script (execution).

Take this example:

class Foo
{
    public static $variavel = 'Valor A';

    public static function valorVariavel()
    {
        return static::$variavel;
    }

    public static function setVariavel($valor)
    {
        static::$variavel = $valor;
    }
}

class Bar extends Foo
{
    // propriedade não foi declarada
}

class FooBar extends Foo
{
    public static $variavel = 'Valor D';
}


echo Foo::valorVariavel(); // retorna "Valor A" que pertence a classe "Foo";

echo Bar::valorVariavel(); // retorna "Valor A" que pertence a classe "Bar";

Bar::setVariavel('Valor C');

echo Foo::valorVariavel(); // retorna "Valor C" que pertence a classe "Foo";

echo Bar::valorVariavel(); // retorna "Valor C" que pertence a classe "Bar";

echo FooBar::valorVariavel(); // retorna "Valor D" que pertence a classe "FooBar";

FooBar::setVariavel('Valor E');

echo Foo::valorVariavel(); // retorna "Valor C" que pertence a classe "Foo";

echo Bar::valorVariavel(); // retorna "Valor C" que pertence a classe "Bar";

echo FooBar::valorVariavel(); // retorna "Valor E" que pertence a classe "FooBar";

When I first started learning POO, I took a "blessed beating" with these differences of static for self. I hope this will clarify the question of inheritance.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.