suche nach in der

Klassenabstraktion> <Gültigkeitsbereichsoperator (::)
Last updated: Sat, 07 Jan 2012

view this page in

Static-Schlüsselwort

Klassenmember oder -methoden als statisch zu deklarieren macht diese zugänglich, ohne dass man die Klasse instantiieren muss. Auf ein als statisch deklariertes Member kann nicht mit einem instantiierten Klassenobjekt zugegriffen werden (obgleich eine statische Methode dies kann).

Für die Abwärtskompatibilität zu PHP 4 werden Member oder Methode behandelt als ob diese als public static deklariert wären, wenn keine Sichtbarkeit deklariert wird.

Als Initialwerte für statische Eigenschaften können nur Zeichenketten und Konstanten zugewiesen werden, die Zuweisung berechneter Ausdrücke ist nicht möglich. Während also die Initialisierung mit einem Integer oder Array möglich ist können der Wert einer anderen Variablen, der Rückgabewert einer Funktion oder ein Objekt nicht als Initialwert zugewiesen werden.

Weil statische Methoden ohne die Instanz eines erzeugten Objektes aufrufbar sind, ist die Pseudovariable $this nicht innerhalb von der als statisch deklarierten Methode verfügbar.

Auf statische Eigenschaften kann nicht durch das Objekt mittels des Pfeiloperators -> zugegriffen werden.

Unstatische Methoden statisch aufzurufen ruft eine Warnung der Stufe E_STRICT hervor.

Beginnend mit PHP 5.3.0 kann die Klasse über eine Variable referenziert werden. Der Variablenwert kann dabei kein Schlüsselwort (wie self, parent oder static) sein.

Beispiel #1 Beispiel für statische Member

<?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";      // Undefinierte "Eigenschaft" 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";
?>

Beispiel #2 Beispiel für statische Methoden

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

Foo::aStaticMethod();
$classname 'Foo';
$classname::aStaticMethod();
?>


add a note add a note User Contributed Notes
Static-Schlüsselwort
yarco dot w at gmail dot com
29-Jun-2007 10:38
Use a variable to initialize a static variable also trigger errors.
For example:

<?php

function test()
{
 
$t = time();
  static
$buf[] = $t; // this wouldn't work
}

?>

But you can do it seperatly:
<?php
function test()
{
  static
$buf;

 
$t = time();
 
$buf[] = $t;
}
?>
meszaros dot gergely at gmail dot com
07-May-2007 01:34
If you need a workaround for a static property overloading problem (see previous post) try this:
<?php
abstract class a {
    public static
$lala = '1';
    function
__construct () {
       
# echo self::$lala
       
$vars = get_class_vars(get_class($this));
        echo
$vars['lala'];
    }
}
class
b extends a {
     public static
$lala = '2';
}

new
b();
?>
admin at goodsoft dot lv
07-Nov-2006 11:05
<?php
       
abstract class a {
                public
                        static
$lala = '1';
                function
__construct () {
                        echo
self::$lala;
                }
        }

        class
b extends a {
                public
                        static
$lala = '2';
        }

        new
b();
?>

This one outputs `1`.
james at earthemergency dot org
12-Oct-2006 01:36
One way to get around the fact that static variables are shared throughout the inheritance tree to map a instance variable to a global variable named after the class.

<?php
$GLOBALS
['static'] = array();
class
root {
  public
$self;
  public static
$all_instances;
 
  function
__construct() {
   
$this->self = &$GLOBALS['static'][get_class($this)];
   
$this->self['instances'] += 1;
   
self::$all_instances     += 1;
  }
}

class
child_a extends root {
}

class
child_b extends root {
}

$a1 = new child_a();
$a2 = new child_a();
$a3 = new child_a();

$b1 = new child_b();
$b2 = new child_b();

echo
"child_a instances: " . $a3->self['instances'] . " | all_instances: " . child_a::$all_instances . "\n";
echo
"child_b instances: " . $b2->self['instances'] . " | all_instances: " . child_b::$all_instances . "\n";

echo
"\$GLOBALS['static'] = ";
var_dump($GLOBALS['static']);
?>

// Output:
child_a instances: 3 | all_instances: 5
child_b instances: 2 | all_instances: 5
$GLOBALS['static'] = array(2) {
  ["child_a"]=>
  &array(1) {
    ["instances"]=>
    int(3)
  }
  ["child_b"]=>
  &array(1) {
    ["instances"]=>
    int(2)
  }
}
jan(dot)-re-mov.ethis-mazanek/AT-abeo.cz
20-Sep-2006 08:42
This reacts to comment from
michael at digitalgnosis dot removethis dot com from 16-Dec-2004 08:09

> Note that Base::Foo() may no longer be declared 'static' since static methods cannot be overridden (this means it will trigger errors if error level includes E_STRICT.)

In my test on Windows PHP Version 5.1.4 it seems that it *is possible* to override static method.

This code works at my machine without producing E_STRICT error:
<?php
class Base
{
   static function
Foo ( $class = __CLASS__ )
   {
      
call_user_func(array($class,'Bar'));
   }
}

class
Derived extends Base
{
   static function
Foo ( $class = __CLASS__ )
   {
      
parent::Foo($class);
   }

   static function
Bar ()
   {
       echo
"Derived::Bar()";
   }
}

Derived::Foo(); // This time it works.
?>
Jakob Schwendner
04-Nov-2005 10:17
Here is my solution to the static search method problem for data objects. I found the debug_trace version posted earlier quite clever, but a little too risky.

<?php
class Foo {
    static function
find($class) {
       
$obj = new $class();
        return
$obj;
    }
}

class
Bar extends Foo {
    static function
find() {
        return
parent::find(__CLASS__);
    }

    function
print_hello() {
        echo(
"hello");
    }   
}

Bar::find()->print_hello();
?>
daxxar
19-Jul-2005 06:14
Heh. The last post, eh, is wrong.
I didn't test it in PHP.

I saw it as an aberration to C++ when I read it, which is why I commented on it. So, I guess I misread "A member or method declared with static can not be accessed with a variable that is an instance of the object and cannot be re-defined in an extending class." to mean that you can't call $foo->StaticFunc(), (and when I explained the issue in the #php-channel on EFNet, I was under the impression that others thought likewise), when I guess it means that you can't access $this *inside* StaticFunc(). I dunno.

If it's a language bug, it should be fix, if it's a documentation "bug" (most likely), the documentation should be worded more cleary (rephrased), IMO. :)
daxxar
18-Jul-2005 02:04
Just to point it out, this is slightly different from the C++ OO approach.

The following code compiles and runs fine using g++ with the options -W -Wall -pedantic :)
#include <iostream>
struct Foo { static void Bar() { std::cout << "Hi!" << std::endl; } };
int main() { Foo x; x.Bar(); return 0; }

Whereas accessing a static method via an instance of a class in PHP doesn't work.

It's not a problem, but it's perhaps worth noting, if you're used to C++ OO.
aidan at php dot net
04-May-2005 04:14
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).
06-Apr-2005 12:14
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
erikzoltan NOSPAM at msn NOSPAM dot com
06-Apr-2005 02:50
I was doing this in a more complex example (than previous note) and found that I had to place the initialization statement AFTER the class in a file where I was using the __autoload function.
erikzoltan NOSPAM at msn NOSPAM dot com
06-Apr-2005 12:40
I had trouble getting a static member to be an instance of a class.  Here's a code example that DOESN'T work. 

<?php

// This doesn't work.

class XYZ
{
   
// The following line will throw a syntax error.
   
public static $ABC = new ABC();
}

class
ABC
{
}

$myXyz = new XYZ();
var_dump($myXyz);
var_dump(XYZ::$ABC);

?>

I get the following entry in my error log. 

[05-Apr-2005 18:27:41] PHP Parse error: syntax error, unexpected T_NEW in staticTest.php on line 7

Since PHP doesn't appear to allow static constructor methods, I was only able to resolve this problem by moving the initialization outside of the class.  To make my code more self-documenting I put it above the class.  The revised example below appears to work. 

<?php

// This will work.

// Moved the static variable's initialization logic outside the class. 
XYZ::$ABC = new ABC();

class
XYZ
{
   
// I'm just declaring the static variable here, but I'm not initializing it.
   
public static $ABC;
}

class
ABC
{
}

$myXyz = new XYZ();
var_dump($myXyz);
var_dump(XYZ::$ABC);

?>
michalf at ncac dot torun dot pl
01-Apr-2005 12:42
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
c_daught_d at earthlink dot net
14-Jan-2005 10:57
A twist on christian at koch dot net's Singleton example is setting/getting non-static member variables using self::$instance->varname within static method calls.

Within the modified Singleton class below, the member variable $value is set within the getInstance static method instead of the constructor.

Whether this is "pure" OPP, I don't know. But it does work, is worth mentioning, and could be usefull.

class Singleton
{

    private static $instance=null;
    private $value=null;

    private function __construct() {
    }

    public static function getInstance() {
        if ( self::$instance == null ) {
            echo "<br>new<br>";
            self::$instance = new Singleton("values");
            self::$instance->value = "values";
        }
        else {
            echo "<br>old<br>";
        }

        return self::$instance;
    }
}
ference at super_delete_brose dot co dot uk
14-Jan-2005 04:11
Both static and const fields can be accessed with the :: operator. However, while a constant can't be changed, this is not true for static variables.

If you want to access an array using the :: operator you have to declare the array static, since you can't have a constant array. Beware:

<?php
class foo
{
  static
$stuff = array('key1' => 1, 'key2' => 2);
}

class
bar
{
  public function
__construct()
  {
   
var_dump(foo::$stuff);
  }
}

class
bad
{
  public function
__construct()
  {
   
foo::$stuff = FALSE;
  }
}

new
bar();    // prints array(2) { ["key1"]=> int(1) ["key2"]=> int(2) }

new bad();
new
bar();    // prints bool(false)
?>

A safe implementation requires a little more effort:

<?php
class foo
{
  private static
$stuff = array('key1' => 1, 'key2' => 2);

  public final static function
getstuff()
  {
    return
self::$stuff;
  }
}

class
bar
{
  public function
__construct()
  {
   
var_dump(foo::getstuff());
  }
}

class
bad
{
  public function
__construct()
  {
   
foo::$stuff = FALSE;
  }
}

new
bar();    // prints array(2) { ["key1"]=> int(1) ["key2"]=> int(2) }
new bad();    // results in a fatal error
?>
michael at digitalgnosis dot removethis dot com
16-Dec-2004 08:41
Here's another way to do the same thing (see my post below) without having to muck up your Foo() function's parameters in the Base and all Derived classes.

However, you cannot use static, and still must define Foo() in derived classes.  This way also performs slower and may not always work--but it DOES make for prettier code.

<?php

class Base
{
    function
Foo ()
    {
       
$call = debug_backtrace();
       
call_user_func(array($call[1]['class'],'Bar'));
    }
}

class
Derived extends Base
{
    function
Foo () { parent::Foo(); }

    function
Bar ()
    {
        echo
"Derived::Bar()";
    }
}

Derived::Foo();

?>
michael at digitalgnosis dot removethis dot com
16-Dec-2004 08:09
If you are trying to write classes that do this:

<?php

class Base
{
    static function
Foo ()
    {
       
self::Bar();
    }
}

class
Derived extends Base
{
    function
Bar ()
    {
        echo
"Derived::Bar()";
    }
}

Derived::Foo(); // we want this to print "Derived::Bar()"

?>

Then you'll find that PHP can't (unless somebody knows the Right Way?) since 'self::' refers to the class which owns the /code/, not the actual class which is called at runtime. (__CLASS__ doesn't work either, because: A. it cannot appear before ::, and B. it behaves like 'self')

But if you must, then here's a (only slightly nasty) workaround:

<?php

class Base
{
    function
Foo ( $class = __CLASS__ )
    {
       
call_user_func(array($class,'Bar'));
    }
}

class
Derived extends Base
{
    function
Foo ( $class = __CLASS__ )
    {
       
parent::Foo($class);
    }

    function
Bar ()
    {
        echo
"Derived::Bar()";
    }
}

Derived::Foo(); // This time it works. 

?>

Note that Base::Foo() may no longer be declared 'static' since static methods cannot be overridden (this means it will trigger errors if error level includes E_STRICT.)

If Foo() takes parameters then list them before $class=__CLASS__ and in most cases, you can just forget about that parameter throughout your code.

The major caveat is, of course, that you must override Foo() in every subclass and must always include the $class parameter when calling parent::Foo().
christian at koch dot net
16-Nov-2004 06:10
STATIC is cool. Here is an example how to get an existing instance as a Singleton:

<?php

class Singleton {

    private static
$instance=null;
    private
$value=null;

    private function
__construct($value) {
       
$this->value = $value;
    }

    public static function
getInstance() {
        if (
self::$instance == null ) {
            echo
"<br>new<br>";
           
self::$instance = new Singleton("values");
        }  else {
            echo
"<br>old<br>";
        }
        return
self::$instance;
    }

}

$x = Singleton::getInstance();
var_dump($x); // returns the new object
$y = Singleton::getInstance();
var_dump($y); // returns the existing object
?>

ckj
dmintz at davidmintz dot org
10-Nov-2004 12:20
[Editor's Note: This is done for back compatability. Depending on your error level, An E_STRICT error will be thrown.]

PHP 5.0.1 doesn't seem to mind if you call a static method in a non-static context, though it might not be the best of style to do so.

On the other hand, PHP complains if you try to try to call a non-static method in a static context (if your error reporting is cranked up to E_STRICT).

class Test {
   
    static function static_method() {
        echo "Here's your static method: Foo!<br />\n";
    }
    function static_method_caller() {
        echo "static_method_caller says:  ";$this->static_method();   
    }
    function non_static() {
        echo "I am not a static method<br />\n";
    }

}

$t = new Test();
$t->static_method();
$t->static_method_caller();
Test::non_static();

Klassenabstraktion> <Gültigkeitsbereichsoperator (::)
Last updated: Sat, 07 Jan 2012