static キーワード
このページでは、static
キーワードを使って static メソッド や
static プロパティを定義する方法を説明します。
static
は、
static 変数
や static な無名関数、そして
遅延静的束縛
にも使えます。これらの場合の static
の使い方は、
それぞれのページを参照ください。
クラスプロパティもしくはメソッドを static として宣言することで、 クラスのインスタンス化の必要なしにアクセスすることができます。 static として宣言されたプロパティやメソッドは、 インスタンス化されたオブジェクトの内部からも :: (スコープ定義演算子) を使ってコールできます。
static メソッド
static メソッドはオブジェクトのインスタンスを生成せずに コールすることができるので、疑似変数 $this は、 static として宣言されたメソッドの内部から利用することはできません。
static でないメソッドをstaticメソッドとしてコールすると、 Error がスローされます。
PHP 8.0.0 より前のバージョンでは、
static でないメソッドをstaticメソッドとしてコールすることが非推奨になっており、
E_DEPRECATED
レベルの警告が発生していました。
例1 static メソッドの例
<?php
class Foo {
public static function aStaticMethod() {
// ...
}
}
Foo::aStaticMethod();
$classname = 'Foo';
$classname::aStaticMethod();
?>
static プロパティ
static プロパティは、
スコープ定義演算子
を使ってアクセスできますが、
オブジェクト演算子 (->
) を使ってアクセスすることはできません。
変数を用いてクラスを参照することも可能です。
変数の値に (self
や parent
、
static
といった)
キーワードを指定することはできません。
例2 static プロパティの例
<?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"; // Undefined "Property" my_static
print $foo::$my_static . "\n";
$classname = 'Foo';
print $classname::$my_static . "\n";
print Bar::$my_static . "\n";
$bar = new Bar();
print $bar->fooStatic() . "\n";
?>
上の例の PHP 8 での出力は、たとえば以下のようになります。:
foo foo Notice: Accessing static property Foo::$my_static as non static in /in/V0Rvv on line 23 Warning: Undefined property: Foo::$my_static in /in/V0Rvv on line 23 foo foo foo foo
User Contributed Notes 28 notes
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.
http://www.php.net/manual/en/language.variables.scope.php
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 b extends a{
static protected $test="class b";
}
$obj = new b();
$obj->static_test();
?>
It is worth mentioning that there is only one value for each static variable that is the same for all instances
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
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 http://php.net/manual/en/class.reflectionclass.php
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
This is also possible:
class Foo {
public static $bar = 'a static property';
}
$baz = (new Foo)::$bar;
echo $baz;
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
?>
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
<?php
trait t {
protected $p;
public function testMe() {echo 'static:'.static::class. ' // self:'.self::class ."\n";}
}
class a { use t; }
class b extends a {}
echo (new a)->testMe();
echo (new b)->testMe();
outputs
static:a // self:t
static:b // self:t
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
?>
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 A {
protected static $a;
public static function init($value) { self::$a = $value; }
public static function getA() { return self::$a; }
}
class B extends A {
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.
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).
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;
}
}
?>
<?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
*/
?>
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>
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();
?>
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);
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!
?>