Ключевое слово "static"

Подсказка

Эта страница описывает использование ключевого слова static для определения статических методов и свойств. static также может использоваться для определения статических переменных и позднего статического связывания. Для получения информации о таком применении ключевого слова static пользуйтесь вышеуказанными страницами.

Объявление свойств и методов класса статическими позволяет обращаться к ним без создания экземпляра класса. Атрибут класса, объявленный статическим, не можеть быть доступен посредством экземпляра класса (но статический метод может быть вызван).

В целях совместимости с PHP 4, сделано так, что если не использовалось определение области видимости, то член или метод будет рассматриваться, как если бы он был объявлен как public.

Так как статические методы вызываются без создания экземпляра класса, то псевдо-переменная $this не доступна внутри метода, объявленного статическим.

Доступ к статическим свойствам класса не может быть получен через оператор ->.

При попытке вызова нестатических методов статически выводится предупреждение уровня E_STRICT.

Как и любая другая статическая переменная PHP, статические свойства могут инициализироваться только используя литерал или константу, выражения же недопустимы. Таким образом вы можете инициализировать статическое свойство например целым числом или массивом, но не сможете указать другую переменную, результат вызова функции или объект.

Начиная с версии PHP 5.3.0 существует возможность ссылаться на класс используя переменную. Поэтому значение переменной в таком случае не может быть ключевым словом (например, self, parent и static).

Пример #1 Пример статического свойства

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

    public function 
staticValue() {
        return 
self::$my_static;
    }
}

class 
Bar extends Foo
{
    public function 
fooStatic() {
        return 
parent::$my_static;
    }
}


print 
Foo::$my_static "\n";

$foo = new Foo();
print 
$foo->staticValue() . "\n";
print 
$foo->my_static "\n";      // Не определено свойство my_static

print $foo::$my_static "\n"// Начиная с PHP 5.3.0
$classname 'Foo';
print 
$classname::$my_static "\n"// Начиная с PHP 5.3.0

print Bar::$my_static "\n";
$bar = new Bar();
print 
$bar->fooStatic() . "\n";
?>

Пример #2 Пример статического метода

<?php
class Foo {
    public static function 
aStaticMethod() {
        
// ...
    
}
}

Foo::aStaticMethod();
$classname 'Foo';
$classname::aStaticMethod(); // Начиная с PHP 5.3.0
?>

Коментарии

Inheritance with the static elements is a nightmare in php. Consider the following code:

<?php
class BaseClass{
    public static 
$property;
}

class 
DerivedClassOne extends BaseClass{
}

class 
DerivedClassTwo extends BaseClass{
}

DerivedClassOne::$property "foo";
DerivedClassTwo::$property "bar";

echo 
DerivedClassOne::$property//one would naively expect "foo"...
?>

What would you expect as an output? "foo"? wrong. It is "bar"!!! Static variables are not inherited, they point to the BaseClass::$property.

At this point I think it is a big pity inheritance does not work in case of static variables/methods. Keep this in mind and save your time when debugging.

best regards - michal
2005-03-31 17:42:09
http://php5.kiev.ua/manual/ru/language.oop5.static.html
Автор:
You misunderstand the meaning of inheritance : there is no duplication of members when you inherit from a base class. Members are shared through inheritance, and can be accessed by derived classes according to visibility (public, protected, private).

The difference between static and non static members is only that a non static member is tied to an instance of a class although a static member is tied to the class, and not to a particular instance.
That is, a static member is shared by all instances of a class although a non static member exists for each instance of  class.

Thus, in your example, the static property has the correct value, according to principles of object oriented conception.
class Base
{
  public $a;
  public static $b;
}

class Derived extends Base
{
  public function __construct()
  {
    $this->a = 0;
    parent::$b = 0;
  }
  public function f()
  {
    $this->a++;
    parent::$b++;
  }
}

$i1 = new Derived;
$i2 = new Derived;

$i1->f();
echo $i1->a, ' ', Derived::$b, "\n";
$i2->f();
echo $i2->a, ' ', Derived::$b, "\n";

outputs
1 1
1 2
2005-04-06 06:14:38
http://php5.kiev.ua/manual/ru/language.oop5.static.html
To check if a function was called statically or not, you'll need to do:

<?php
function foo () {
   
$isStatic = !(isset($this) && get_class($this) == __CLASS__);
}
?>

More at (http://blog.phpdoc.info/archives/4-Schizophrenic-Methods.html). 

(I'll add this to the manual soon).
2005-05-04 10:14:10
http://php5.kiev.ua/manual/ru/language.oop5.static.html
It's come to my attention that you cannot use a static member in an HEREDOC string.  The following code

class A
{
  public static $BLAH = "user";

  function __construct()
  {
    echo <<<EOD
<h1>Hello {self::$BLAH}</h1>
EOD;
  }
}

$blah = new A();

produces this in the source code:

<h1>Hello {self::}</h1>

Solution:

before using a static member, store it in a local variable, like so:

class B
{
  public static $BLAH = "user";

  function __construct()
  {
    $blah = self::$BLAH;
    echo <<<EOD
<h1>Hello {$blah}</h1>
EOD;
  }
}

and the output's source code will be:

<h1>Hello user</h1>
2008-01-01 22:48:39
http://php5.kiev.ua/manual/ru/language.oop5.static.html
Автор:
Note that you should read "Variables/Variable scope" if you are looking for static keyword use for declaring static variables inside functions (or methods). I myself had this gap in my PHP knowledge until recently and had to google to find this out. I think this page should have a "See also" link to static function variables.
language.variables.scope
2008-01-28 02:27:32
http://php5.kiev.ua/manual/ru/language.oop5.static.html
Hi, here's my simple Singleton example, i think it can be useful for someone. You can use this pattern to connect to the database for example.

<?php

 
class MySingleton
 
{
    private static 
$instance null;

    private function 
__construct()
    {
     
$this-> name 'Freddy';

    }

    public static function 
getInstance()
    {
      if(
self::$instance == null)
      {
        print 
"Object created!<br>";
       
self::$instance = new self;

      }

      return 
self::$instance;

    }

    public function 
sayHello()
    {
      print 
"Hello my name is {$this-> name}!<br>";

    }

    public function 
setName($name)
    {
     
$this-> name $name;

    }

  }

 
//

 
$objA MySingleton::getInstance(); // Object created!

 
$objA-> sayHello(); // Hello my name is Freddy!

 
$objA-> setName("Alex");

 
$objA-> sayHello(); // Hello my name is Alex!

 
$objB MySingleton::getInstance();

 
$objB-> sayHello(); // Hello my name is Alex!

 
$objB-> setName("Bob");

 
$objA-> sayHello(); // Hello my name is Bob!

?>
2008-10-20 04:06:00
http://php5.kiev.ua/manual/ru/language.oop5.static.html
Static variables are shared between sub classes

<?php
class MyParent {
   
    protected static 
$variable;
}

class 
Child1 extends MyParent {
   
    function 
set() {
       
       
self::$variable 2;
    }
}

class 
Child2 extends MyParent {
   
    function 
show() {
       
        echo(
self::$variable);
    }
}

$c1 = new Child1();
$c1->set();
$c2 = new Child2();
$c2->show(); // prints 2
?>
2009-03-17 18:56:28
http://php5.kiev.ua/manual/ru/language.oop5.static.html
Автор:
Regarding the initialization of complex static variables in a class, you can emulate a static constructor by creating a static function named something like init() and calling it immediately after the class definition.

<?php
class Example {
    private static 
$a "Hello";
    private static 
$b;

    public static function 
init() {
       
self::$b self::$a " World!";
    }
}
Example::init();
?>
2009-12-18 16:45:05
http://php5.kiev.ua/manual/ru/language.oop5.static.html
On PHP 5.2.x or previous you might run into problems initializing static variables in subclasses due to the lack of late static binding:

<?php
class {
    protected static 
$a;
   
    public static function 
init($value) { self::$a $value; }
    public static function 
getA() { return self::$a; }
}

class 
extends {
    protected static 
$a// redefine $a for own use
   
    // inherit the init() method
   
public static function getA() { return self::$a; }
}

B::init('lala');
echo 
'A::$a = '.A::getA().'; B::$a = '.B::getA();
?>

This will output:
A::$a = lala; B::$a = 

If the init() method looks the same for (almost) all subclasses there should be no need to implement init() in every subclass and by that producing redundant code.

Solution 1:
Turn everything into non-static. BUT: This would produce redundant data on every object of the class.

Solution 2:
Turn static $a on class A into an array, use classnames of subclasses as indeces. By doing so you also don't have to redefine $a for the subclasses and the superclass' $a can be private.

Short example on a DataRecord class without error checking:

<?php
abstract class DataRecord {
    private static 
$db// MySQLi-Connection, same for all subclasses
   
private static $table = array(); // Array of tables for subclasses
   
   
public static function init($classname$table$db false) {
        if (!(
$db === false)) self::$db $db;
       
self::$table[$classname] = $table;
    }
   
    public static function 
getDB() { return self::$db; }
    public static function 
getTable($classname) { return self::$table[$classname]; }
}

class 
UserDataRecord extends DataRecord {
    public static function 
fetchFromDB() {
       
$result parent::getDB()->query('select * from '.parent::getTable('UserDataRecord').';');
       
       
// and so on ...
       
return $result// An array of UserDataRecord objects
   
}
}

$db = new MySQLi(...);
UserDataRecord::init('UserDataRecord''users'$db);
$users UserDataRecord::fetchFromDB();
?>

I hope this helps some people who need to operate on PHP 5.2.x servers for some reason. Late static binding, of course, makes this workaround obsolete.
2010-02-25 03:38:46
http://php5.kiev.ua/manual/ru/language.oop5.static.html
Starting with php 5.3 you can get use of new features of static keyword. Here's an example of abstract singleton class:

<?php

abstract class Singleton {

    protected static 
$_instance NULL;

   
/**
     * Prevent direct object creation
     */
   
final private function  __construct() { }

   
/**
     * Prevent object cloning
     */
   
final private function  __clone() { }

   
/**
     * Returns new or existing Singleton instance
     * @return Singleton
     */
   
final public static function getInstance(){
        if(
null !== static::$_instance){
            return static::
$_instance;
        }
        static::
$_instance = new static();
        return static::
$_instance;
    }
   
}
?>
2010-12-11 19:09:58
http://php5.kiev.ua/manual/ru/language.oop5.static.html
<?php
class foo {
    private static 
$getInitial;

    public static function 
getInitial() {
        if (
self::$getInitial == null)
           
self::$getInitial = new foo();
        return 
self::$getInitial;
    }
}

foo::getInitial();

/*
this is the example to use new class with static method..
i hope it help
*/

?>
2011-04-18 14:50:17
http://php5.kiev.ua/manual/ru/language.oop5.static.html
Here statically accessed property prefer property of the class for which it is called. Where as self keyword enforces use of current class only. Refer the below example:

<?php
class a{

static protected 
$test="class a";

public function 
static_test(){

echo static::
$test// Results class b
echo self::$test// Results class a

}

}

class 
extends a{

static protected 
$test="class b";

}

$obj = new b();
$obj->static_test();
?>
2011-07-09 06:17:05
http://php5.kiev.ua/manual/ru/language.oop5.static.html
Автор:
It should be noted that in 'Example #2', you can also call a variably defined static method as follows:

<?php
class Foo {
    public static function 
aStaticMethod() {
       
// ...
   
}
}

$classname 'Foo';
$methodname 'aStaticMethod';
$classname::{$methodname}(); // As of PHP 5.3.0 I believe
?>
2013-10-24 04:34:44
http://php5.kiev.ua/manual/ru/language.oop5.static.html
In real world, we can say will use static method when we dont want to create object instance. 

e.g ... 

validateEmail($email) {
 if(T) return true;
return false;
}

//This makes not much sense
$obj = new Validate();
$result = $obj->validateEmail($email);

//This makes more sense
$result = Validate::validateEmail($email);
2013-11-19 04:45:02
http://php5.kiev.ua/manual/ru/language.oop5.static.html
The static keyword can still be used (in a non-oop way) inside a function. So if you need a value stored with your class, but it is very function specific, you can use this:

class aclass {
    public static function b(){
        static $d=12; // Set to 12 on first function call only
        $d+=12;
        return "$d\n";
    }
}

echo aclass::b(); //24
echo aclass::b(); //36
echo aclass::b(); //48
echo aclass::$d; //fatal error
2015-10-02 22:44:05
http://php5.kiev.ua/manual/ru/language.oop5.static.html
To check if a method declared in a class is static or not, you can us following code. PHP5 has a Reflection Class, which is very helpful. 

try {
    $method = new ReflectionMethod( 'className::methodName );
    if ( $method->isStatic() )
    {
        // Method is static.
    }
}
catch ( ReflectionException $e )
{
    //    method does not exist
    echo $e->getMessage();
}

*You can read more about Reflection class on class.reflectionclass
2015-11-13 12:39:58
http://php5.kiev.ua/manual/ru/language.oop5.static.html
Автор:
<?php

trait {
  protected 
$p;
  public function 
testMe() {echo 'static:'.static::class. ' // self:'.self::class ."\n";}
}

class 
{ use t; }
class 
extends {}

echo (new 
a)->testMe();
echo (new 
b)->testMe();

outputs
static:// self:t
static:// self:t
2016-02-27 23:06:31
http://php5.kiev.ua/manual/ru/language.oop5.static.html
It is worth mentioning that there is only one value for each static variable that is the same for all instances
2018-03-19 19:36:22
http://php5.kiev.ua/manual/ru/language.oop5.static.html
This is also possible:

class Foo {
  public static $bar = 'a static property';
}

$baz = (new Foo)::$bar;
echo $baz;
2018-03-30 21:38:42
http://php5.kiev.ua/manual/ru/language.oop5.static.html
It is important to understand the behavior of static properties in the context of class inheritance:

- Static properties defined in both parent and child classes will hold DISTINCT values for each class. Proper use of self:: vs. static:: are crucial inside of child methods to reference the intended static property.

- Static properties defined ONLY in the parent class will share a COMMON value.

<?php
declare(strict_types=1);

class 
staticparent {
    static   
$parent_only;
    static   
$both_distinct;
   
    function 
__construct() {
        static::
$parent_only 'fromparent';
        static::
$both_distinct 'fromparent';
    }
}

class 
staticchild extends staticparent {
    static   
$child_only;
    static   
$both_distinct;
   
    function 
__construct() {
        static::
$parent_only 'fromchild';
        static::
$both_distinct 'fromchild';
        static::
$child_only 'fromchild';
    }
}

$a = new staticparent;
$a = new staticchild;

echo 
'Parent: parent_only='staticparent::$parent_only', both_distinct='staticparent::$both_distinct"<br/>\r\n";
echo 
'Child:  parent_only='staticchild::$parent_only', both_distinct='staticchild::$both_distinct', child_only='staticchild::$child_only"<br/>\r\n";
?>

will output:
Parent: parent_only=fromchild, both_distinct=fromparent
Child: parent_only=fromchild, both_distinct=fromchild, child_only=fromchild
2018-09-04 22:18:23
http://php5.kiev.ua/manual/ru/language.oop5.static.html
//Difference Between self:: and static::

<?php
class {
    protected static 
$name "Class A";

    public static function 
getName() {
        return 
self::$name// Uses class A's property
   
}

    public static function 
getNameStatic() {
        return static::
$name// Uses the property from the child class
   
}
}

class 
extends {
    protected static 
$name "Class B";
}

echo 
B::getName();       // Output: Class A (Because of self::)
echo B::getNameStatic(); // Output: Class B (Because of static::)

?>
2025-02-20 14:22:07
http://php5.kiev.ua/manual/ru/language.oop5.static.html

    Поддержать сайт на родительском проекте КГБ