Operador de Resolución de Alcance (::)

Precaución

Lo siguiente es válido para PHP 4 y posteriores únicamente.

Algunas veces es útil hacer referencia a funciones y variables en las clases base o hacer referencia a funciones que se encuentran en clases que aún no tienen ninguna instancia. El operador :: es utilizado para realizar esto.

<?php
class {
    function 
example() {
        echo 
"I am the original function A::example().<br />\n";
    }
}

class 
extends {
    function 
example() {
        echo 
"I am the redefined function B::example().<br />\n";
        
A::example();
    }
}

// no hay objetos de la clase A.
// esto imprimirá
//   I am the original function A::example().<br />
A::example();

// crear un objeto de clase B.
$b = new B;

// esto imprimirá
//   I am the redefined function B::example().<br />
//   I am the original function A::example().<br />
$b->example();
?>

El ejemplo de arriba invoca a la función example() en la clase A, pero no hay un objeto de la clase A, así que no es posible escribir $a->example() o algo semejante. En vez de ello se invoca example() como una 'función de clase', es decir, como una función de la clase misma, no de un objeto de esa clase.

Existen funciones de clase, pero no existen variables de clase. De hecho, no existe objeto alguno en el momento de la invocación. Siendo así, una función de clase no puede utilizar ninguna variable de objeto (pero puede utilizar variables locales y globales), y no puede utilizar $this para nada.

En el ejemplo anterior, la clase B vuelve a definir la función example(). La definición original en la clase A queda desplazada y ya no se encuentra disponible, a menos que se haga referencia específicamente a la implementación de example() en la clase A empleando el operador ::. Se escribe A::example() para realizar esto (de hecho, se debe escribir parent::example(), tal como se muestra en la siguiente sección).

En este contexto, existe un objeto actual y puede tener variables de objeto. Así, cuando se usen desde el INTERIOR de una función de objeto, se puede utilizar $this y las variables de objeto.

add a note add a note

User Contributed Notes 31 notes

up
13
Shachar Shemesh
8 years ago
The PHP lexical analyzer gives this token the name "T_PAAMAYIM_NEKUDOTAYIM". It might as well have been written in Hebrew. Wait, it IS written in Hebrew. It means "double colon".

I'm writing this comment mostly so that people who are searching the web for what the #(!(@*&#$ errors such as "unexpected T_PAAMAYIM_NEKUDOTAYIM" or "missing T_PAAMAYIM_NEKUDOTAYIM" mean get to the right page in the PHP manual.

Shachar
up
4
Robert Chapin
7 years ago
I revised this example to give a better feel for the scope and overloading rules in PHP 4.

<?php
class A {
    function
example() {
        echo
"I am the original function A::example().<br />\n";
       
$this->other();
    }
    function
other() {
        echo
"I am the original function A::other().<br />\n";
    }
}

class
B extends A {
    function
example() {
        echo
"I am the redefined function B::example().<br />\n";
       
A::example();
    }
    function
other() {
        echo
"I am the redefined function B::other().<br />\n";
    }
}

// there is no object of class A.
// this will print
//   I am the original function A::example().<br />
//   PHP Fatal error:  Call to a member function on a non-object in test.php on line 5
A::example();

// create an object of class B.
$b = new B;

// this will print
//   I am the redefined function B::example().<br />
//   I am the original function A::example().<br />
//   I am the redefined function B::other().<br />
$b->example();
?>

Robert Chapin
Chapin Information Services
up
2
peter at textstore dot c() dot il
13 years ago
And now, encapsulated in constructor. Isn't it nice? Ye, and it WILL work when   more objects of class are serialized & unserialized ONLY when serialized in array / hash by one serialize() call - as serialize() should be used. However, when unserialized, it doesn't affect actual instances' "static" variable - thus, there will be 2 or more static variables after unserialization... but you can still change __wakeup() and to access "real"(actual) class' static value's reference, thus you have to use special function for every static value, as in example above... Ye, PHP is good!@

<?
  class O {

    function O() {
        static $statValue=0;
        $this->statValue= &$statValue;
    }
  }

  $o1= &new O;
  $o2= &new O;

  echo "\$o1: ".$o1->statValue."<br>";
  echo "\$o2: ".$o2->statValue."<br>";

  $o1->statValue= 5;
  $o2->statValue= 10;

  echo "\$o1: ".$o1->statValue."<br>";
  echo "\$o2: ".$o2->statValue."<br>";
?>
up
1
Rami Kayyali (rami at bluecubex dot com)
11 years ago
Regarding the note by "gk at proliberty dot com". No, eval() isn't superior to call_user_func(), eval() has security issues and performance overhead.
To achieve the same results using your example with call_user_func, simply pass $this_class by reference. This is probably because call_user_func is passing a copy of $this_class.

<?php

function init(&$this_class, $current_class, $params= NULL ){
   
$this_class->classFiles[] = __FILE__;

   
$parent_class=get_parent_class($current_class);
    if( !empty(
$parent_class)){
       
// call_user_func() NOW DOES CORRECTLY UPDATE $this_class->classFiles :)
       
call_user_func(array($parent_class,'init'),
        &
$this_class,$parent_class,$params);
    }
  
}
// init()

?>

But please note, call-time pass-by-reference has been deprecared, or at least, PHP 4.3.2 says so.

Conclusion: Minimize using eval as much as possible, many projects had major security issues because they were using eval().
up
0
singh206 at gmail dot com
6 years ago
Using PHP 4, I was unable to see an easy method for retrieving static constants in a library, as well as static functions.  There was no need to set variables, as the library is final, used for Configuration settings.

<?php
class StaticLibrary
{
   
//static constants are set here
   
function finalConstants(&$Vars)
    {
       
$Vars['someVar']        = 'Hello';
       
$Vars['anotherVar']     = 'World';
       
$Vars['moreVars']       = 'Keep It Coming';
    }

   
//usage: StaticLibrary::vars('someVar')
   
function vars($v)
    {   
               static
$Vars;
             if (!
is_array($Vars)) { $Vars = array(); StaticLibrary::finalConstants($Vars); } //setup access to the static contants in our Final library
            
return($Vars[$v]); //return some var
     
}

   
//usage: StaticLibrary::staticFunction('Some string and I want to ')   
   
function staticFunction($str)
    {
           
$str .= 'freak that string!';
            return
$str;
    }
}
?>

  I appreciate the ideas below!!
up
0
philipp dot feigl at gmail dot com
6 years ago
As already pointed out in a previous comment, there is no way to statically access variables, i wrote this small workaround

<?php
class A {
    var
$MY_VIRTUAL_CONST = 1;
    function
MY_VIRTUAL_CONST() { $vars = get_class_vars(__CLASS__); return $vars[strToUpper(__FUNCTION__)]; }
}

echo
A::MY_VIRTUAL_CONST();
?>

This magically retrieves the correct value without creating an object instance and its easily copy & pasteable, as the methods content is completly generic.
up
0
deadimp at gmail dot com
7 years ago
I've noticed that you can't easily obtain a re-scoping of a function-to-object by external means, and it can only really be done by functions ["methods" to be proper] inside the class.
I dub this phenomon "inability to externally modifiy scope resolution of class method", 'cause I don't really know the technical name. (Maybe something else along the lines of "inability to combine scope resolution and member selector operators".)
Enough of this, on to the example:
<?php
class Base {
var
$a=5;
function
Func() {
  echo
"Base::Func $this->a<br>";
}
}
class
Child extends Base {
function
Func() {
 
$this->a=35;
 
Base::Func();
 
//$this->Base::Func(); //Won't work either
 
echo "Child::Func $this->a<br>";
}
}
$obj=new Child;
$obj->Func(); //That works, outputs as expected
$obj->Base::Func(); //ERROR - See below
?>
As for the error, I get the Hebrew "double colon", as Shachar Shemesh mentioned: "parse error, unexpected T_PAAMAYIM_NEKUDOTAYIM"
I find it odd that I can't do this, and using C++ (where you are able to do this), I feel restricted in this sense.
And I can't think of any workarounds right now, aside from using this scope resolution in the class scope.

NOTE: I'm using PHP 5.0.5 right now (used to be using 4.x, but might've switched it in xampp)
up
0
docey
8 years ago
after doing some research as the manual was somewhat
vague, i found out that using $this in a class-function is
not fatal as the manual implied, its not even a warning.

it simply comes with a notice saying: $this is undefined.

it appears the class-function is just as a global function.
and as such the static keyword holds its value after scope
changes.

however it seems to also holds its value after the class
gets instanced. take a simple counter function thats a
member of a class. make a few calls to the counter to
let it count to lets say 3. then instance the class and let
it count it again 3 times. you think the score is now 3,
infact its 6.

so one simple way to find out if a function is called from
a instanced class or not is to have the constructor set a
class variable and then check for it using isset. since in
the class-function scope the $this is unavailable isset
will return false. but when the class has been instanced
it will return true.

btw, i tested it with php4.4.2CLI.

hope this will clear somethings up.
up
0
rudy at sandbenders dot ca
9 years ago
my last note is actually not 100% correct... as it is, trying to return a reference to an element of the class variables array won't work, even though the classVars function is declared as (possibly) returning a reference... the correct way to return a reference to one of your class variables would be

<?php

class theClass {
    ...
    function &
classVars($name = NULL, ...) {
        static
$myClassVars;
        ...
       
$myRef =& $myClassVars[$name];

        return(
$myRef);
    }
}

?>

which works as expected when you're looking for a reference. This should only be necessary when you're trying to return a reference to a piece of the array as opposed to the whole array itself. Simply doing this

<?php

return($myClassVars);

?>

works as expected, ie: you can get a reference to the whole array without needing to explicitly create a reference to it before returning.
up
0
rudy at sandbenders dot ca
9 years ago
Since re-posting a simplified version of the peterjoel.com solution to class variables in php4 was kinda lame, here's the modified solution to give you one function (per class) that allows you to use any number of 'class' variables...

<?php

class theClass {
    function &
classVars($name = NULL, $value = NULL) {  // The classVars function is (possibly) returning a reference...
       
static $myClassVars// Define a static var to hold our 'class' vars...

       
if (!is_array($myClassVars)) {  // Initialize the array if it isn't already...
           
$myClassVars = array();
        }

        if (!
is_null($name) && !is_null($value)) {  // If we got two arguments, set the class var that was passed...
           
$myClassVars[$name] = $value;
        }

        if (!
is_null($name)) {  // If we got one argument, return the var it's referring to...
           
return($myClassVars[$name]);
        } else {
            return(
NULL);
        }
    }
}

// Setting class variables...

theClass::classVars("varOne", "valueOne");
theClass::classVars("varTwo", "valueTwo");

// Getting class variables...

$myRef = &theClass::classVars("varOne");
echo
theClass::classVars("varTwo");

?>

You should be able to store anything in your class vars this way, and depending on how you call the function, you can have either a copy or a reference to the class var returned (see manual on 'returning by reference'...) Again, hope this helps someone...
up
0
rudy at sandbenders dot ca
9 years ago
'emulating' class variables in php4... peter at textstore dot c() dot il  put me on the right track... I came up with the following and then before posting this realized that peterjoel.com has already posted almost the exact same thing... anyways, this is a little simpler and only involves one function instead of a getter/setter pair...

class myClass {
    function &myVar($arg = NULL) {
        static $myClassVar;
        if (!is_null($arg)) {
            $myClassVar = $arg;
        }
        return($myClassVar);
    }
}

// Setting the 'class' var...

myClass::myVar($myNewClassVar);

// Getting the 'class' var...

$classVarRef = &myClass::myVar();

This should let you set up 'class' vars that will hold anything you can reference... with a little creative array usage, you could modify this to allow any number of class vars without having to write the same above function for each one... hope someone finds it useful...
up
0
JDS <jeff at newtnotes dot com>
9 years ago
Using an anonymous class instance via the scope resolution operator does not appear to call the constructor method of the class.  Thus, any "stuff" set up within a constructor method (the method called when creating a new instance of a class) will not get set up using anonymous classes.

So for example something like this

<?php
Class A{
    var
$thing;
    function
A(
       
$this->thing = "hello";
    )
    function
get ($var){
        return
$this->$var;
    }
}

echo
A::get('thing');
?>

will not print anything as A::thing does not get "set up" outside of the constructor.

You would have to create an instance of class A to get any value for A::thing.

For example:
<?php
$a
= new A();
echo
$a->get('thing');
?>
(prints "hello")

This is based on my observations and not from any official documentation.  I may be wrong about the details.
up
0
evert at collab dot nl
9 years ago
A note to RichardBronosky's suggestion:

This is a very insecure method, never unserialize user data because they might be able upload a totally different class.
They can only specify properties, not methods but if they can research your code they might be able to do uninteded stuff or create a XSS attack.

So only unserialize user-data when you are in a controlled safe enviroment.

Evert
up
0
RichardBronosky (firstname at lastname dot com)
9 years ago
In reply to tim dot ward at stivesdirect dot com:
I had a need to to do a very similar thing.  I wrote a class that will be used to create an object which can serialize itself into a cookie and be used to recover itself from the cookie later.  To do the recovery you must use the Scope Resolution Operator (::) to call a function as a class function (vs. and object function).  The recovery is very simple to initiate because there is only one line of code to call (e.g. $the_object = the_class::the_function(); )  But the function you call must do a ton of stuff, and call a few other functions within the class.  This is where the problem lies.

I would like to thank <brooke at jump dot net>, <pollita at php dot net>, and <MagicalTux at FF.ST> (from http://php.net/manual/en/function.get-class.php) for leading me to the solution.

<?php
class foo
{
   function
get_object_from_cookie(...)
   {
      ...
      return
unserialize($decrypted_cookie_data);
   }
   function
recover_from_cookie()
   { 
      ...
prepare to recover...
     
// The next line is the tricky part.
     
$o = call_user_func(array(__CLASS__, 'get_object_from_cookie'), $encryption_secret, $cookie_name);
     
$temp = $o->get_stuff();
     
$o->other_stuff = $o->do_calculate($temp);
     
$o->do_complicated_things();
      return
$o;
   }
}
$bar = foo::recover_from_cookie();
...
?>

I hope that saves someone an hour.  It sure would have saved me one.
up
0
mark at branly dot com
9 years ago
I didn't see where this issue was addressed so in regards to this post:

\\-------\\//-------//
when using "::" operator inside class functions, you can achieve quite interesting results. let's take this example:

  class cCat {                  
   function Miew(){
     // cCat does not have a member "kind", but cDog has, and we'll use it
     echo "I am ".$this->kind.", and I say MIEW\n";
   
     // here things are even stranger: does cCat class
     // support WhoAmI function? guess again...
     $this->WhoAmI();
   }
  }

  class cDog {
   var $kind = "DOG";
   function Bark(){    
       // let's make this dog act like a cat:)
       cCat::Miew();
   }              
 
   function WhoAmI(){
     echo "Yes, I'm really ".$this->kind."!";
   }
  }

  $dog = new cDog();
  echo $dog->Bark();

outputs:
I am DOG, and I say MIEW
Yes, I'm really DOG!

The interesting thing here is that cDog is not descendant of cCat nor vice versa, but cCat was able to use cDog member variable and function. When calling cCat::Miew() function, your $this variable is passed to that function, remaining cDog instance!

It looks like PHP doesn't check if some class is an ancestor of the class, calling function via '::'.

//------//\\--------\\

The problem here is not that PHP is not checking ancestry. The problem is that "$this" refers to the calling object $dog even though it is referenced inside the cCat class definition. Since a cCat is never instantiated, $this has not been scoped to it.

To further illustrate the point, if you never instatiate dog (or any object for that matter), $this will never be set and when you statically call the miew function, you will get the following output:

"I am , and I say MIEW"

This flexibility of member handling, PHP does not afford to methods and as such the second line of the miew function will generate a fatal error reporting that the method has been called from a non object.

If you did want to take it one step further in the whole ancestry guessing issue, try instatiating cCat and calling the miew function. You will get the same result as above *EXCEPT* the fatal error will inform you the function has not been defined.

So, there you have it--PHP DOES NOT guess at inheritance.
up
0
Tom Wiltshire
9 years ago
It's worth noting that you can't use a variable with this operator.
The following is legal:

    class MyObject {
        function myfunc() {
            return "Hello!";
        }
    }
    $type = "MyObject";
    $object = new $type();
    $message = $object->myfunc();

(Puts "hello" in $message)

You can also use the scope operator:

    $message = MyObject::myfunc();

However, the following is NOT legal:

    $message = $type::myfunc();

It's a pity, 'cos right now I've got a situation where it'd be really handy, but that's the way it goes!
up
0
stefano at obliquid dot it
10 years ago
peter has a good point to suggest the use of static function variables instead of static class variables that PHP 4 does not support.

Unfortunately, also the first sentence of the manual is misleading "... refer to functions and variables in base classes or to refer to functions in classes that have not yet any instances. The :: operator is being used for this.".

You cannot use the :: operator on class variables since there are no static class variables. I lost some time trying to refer to class variable with this operator, so I think it may be useful to post a warning.

http://dev.obliquid.com
up
0
altherac at yahoo dot fr
10 years ago
Using a class function is a good way to write a Singleton pattern in php 4 using a static variable.

The sample code below shows the pattern in action :

<?
    class Singleton
    {
        var $_info = null;

        function Singleton() {
            $this->_info = 'Original value';
        }

        function getInfo() {
            return $this->_info;
        }

        function setInfo($info) {
            $this->_info = $info;
        }

        function &getInstance() {
            static $instance = null;

            if (is_null($instance)) {
                $instance = new Singleton();
            }
            return $instance;
        }
    }

    $a = & Singleton::getInstance();
    $b = & Singleton::getInstance();
    $a->setInfo('Hi, my name is A');
    echo $b->getInfo();

?>

I have seen some Singleton pattern implementations that were using an external function to instanciate the object, but I don't think it is the best way to implement the pattern.

You may want to force the getInstance() function to be called in a static way with the :: operator by testing if $this is set and raising an error or returning a null value (depending on your design).
up
0
brooke at jump dot net
11 years ago
Someone mentioned that eval was better than call_user_func because the latter would not result in updates to the objects. I'm not sure this is the right place for such a debate, but if it is, then the right way is:

call_user_func(array(&this, $method), $arg1, $arg2);

You put a reference to (instead of a copy of) this in the array which you pass on.
up
0
wikiz at studentas dot lt
11 years ago
when using "::" operator inside class functions, you can achieve quite interesting results. let's take this example:

  class cCat {                    
    function Miew(){
      // cCat does not have a member "kind", but cDog has, and we'll use it
      echo "I am ".$this->kind.", and I say MIEW\n";
     
      // here things are even stranger: does cCat class
      // support WhoAmI function? guess again...
      $this->WhoAmI();
    }
  }
 
  class cDog {
    var $kind = "DOG";
    function Bark(){     
       // let's make this dog act like a cat:)
       cCat::Miew();
    }                
   
    function WhoAmI(){
      echo "Yes, I'm really ".$this->kind."!";
    }
  }

  $dog = new cDog();
  echo $dog->Bark();

outputs:
I am DOG, and I say MIEW
Yes, I'm really DOG!

The interesting thing here is that cDog is not descendant of cCat nor vice versa, but cCat was able to use cDog member variable and function. When calling cCat::Miew() function, your $this variable is passed to that function, remaining cDog instance!

It looks like PHP doesn't check if some class is an ancestor of the class, calling function via '::'.
up
0
gk at proliberty dot com
11 years ago
Contrary to the comment above, I have found that call_user_func()
is inferior to eval() because call_user_func() does not correctly
update objects passed by reference.

In the example below, each of my subclasses calls init(), passing
a reference to the current object, whose class variables are
initialized by classes in the hierarchy. The class variable
$this->classFiles contains the paths of each file for classes in
the hierarchy. It is not updated correctly using call_user_func()
but eval() works fine.

<?php
///////////////////////////////////////////////////////
/*
  xobj( );
    constructor
    SUBCLASSES MUST NOT have any constructors
*/
/////////////////////////////////////////////////////////
function xobj( $params= NULL ){

   
$current_class=get_class($this);
   
$this->init($this, $current_class, $params);
   
// $this->classFiles[0] is the file containing the final subclass
   
$this->classFile=$this->classFiles[0];
   
print_r($this->classFiles); exit;
   
$this->_init($params);
}

///////////////////////////////////////////////////////
/*
  void init(&$this_class, $current_class, $params= NULL );
    initialization
    this class MUST be overridden to set $this->classFiles correctly:
    initialization requires __FILE__ to get the path of every class file
*/
/////////////////////////////////////////////////////////
function init(&$this_class, $current_class, $params= NULL ){
   
$this_class->classFiles[] = __FILE__;

   
$parent_class=get_parent_class($current_class);
    if( !empty(
$parent_class)){
        eval(
"$parent_class::init(\$this_class, \$parent_class, \$params);");
       
// call_user_func() DOES NOT CORRECTLY UPDATE $this_class->classFiles:
        //call_user_func(array($parent_class,'init'),
$this_class,$parent_class,$params);
    }
   
}
// init()

?>

RESULT, using eval():
Array
(
    [0] => /usr/local/apache/htdocs/common/php/xobj/xobj_subclass.php
    [1] => /usr/local/apache/htdocs/common/php/xobj/xobj.php
)

RESULT, using call_user_func():
Array
(
    [0] => /usr/local/apache/htdocs/common/php/xobj/xobj_subclass.php
)
up
0
pollita at php dot net
11 years ago
While the method described by robinv at ecosse dot net to call a method of an arbitrarily named function will work:

eval("$classname::$methodname(\$param1,\$param2);");

There is another way to do so without using eval():

call_user_func(array($classname,$methodname),$param1,$param2);

This will do the same thing without the performance hit of eval and without the added security concerns.
up
0
frederik at spam pandora dot be
12 years ago
My approach to using class constants is by making them functions.
Instead of

$var CONSTANT = 1;

I use

function CONSTANT { return 1; }

Now, when using this:

$i = ConstantClass::CONSTANT();

You can do anything with it: comparing, addition, multiplication. The syntax is a bit weird, but it works perfectly.
up
0
pierrick at hydromel_no_spam_ dot net
12 years ago
It's possible to access class member variables:

class Test {
    var $vA = "hello world";
}

$class_var = get_class_vars(Test);
echo $class_var["vA"];

It's sound to be an ellegant way to acces them, no ? ;)
up
0
jdominic at prodigy dot net
12 years ago
According to the documentation, there is no way to have a class variable, only class functions. There should be class variables, because there's no way to implement CONSTANTS. Something like this won't work:

<?
        class Employee {

        var $ACTIVE_EMPLOYEE = 1;

        //etc..
        }

        echo Employee::ACTIVE_EMPLOYEE;

        //Also tryed:

        echo Employee::$ACTIVE_EMPLOYEE

?>

returns:
Parse error: parse error, unexpected ';', expecting '(' in /home/x/public_html/Test.php on line 9

It forces you to create an instance of the class:

$emp = new Employee();
echo $emp->ACTIVE_EMPLOYEE;
up
0
carl at thep.lu.se
12 years ago
Note that if you have two classes, 'foo' and 'bar', and a function in foo called with $instance_of_foo->func() calls bar::func2(), $this will be defined in func2, and it will point at an object of class foo. In fact, you can redefine $this to point to an object of any class before calling bar::func2() to have $this to be a reference to that object. This means that you can't have functions that can be called either as static (::) or member(->), since you won't be able to tell the difference. This is a quite unfortunate consequence of the combination of references not containing any type information and it not being possible to call an explicitly chosen base class member function (that is, if x extends y there's no clean way to call y::f() on an object of class x (The unclean way is to assign $this to $instance_of_x, call y::f(), and reset $this to its old value.)).
up
0
peter at textstore dot c() dot il
13 years ago
That's how to make class' static variable in PHP4. That means reference returned by function value() is the same for all instances of class O, thus they can share common data. This reference is common just for instances on same PHP page, of course.

<?  class O {
    function &value() {
     static $val=0;
     return $val;
    }
  }

  $o1= &new O;
  $o2= &new O;

  echo "\$o1: ".$o1->value()."<b"."r>";
  echo "\$o2: ".$o2->value()."<b"."r>";

  $ref1= &$o1->value();
  $ref1= 5;

  $ref2= &$o2->value();
  $ref2= 10;

  echo "\$o1: ".$o1->value()."<b"."r>";
  echo "\$o2: ".$o2->value()."<b"."r>";
?>
up
-1
mark@thedarkside
9 years ago
Carrying on from the previous note, it is possible to call a member function statically using a variable for the name of the class, i.e.:

<?php
class MyObject {
   function
myfunc() {
      return
"Hello! ($this)"// '$this' to determine whether it is being called statically
  
}
}

$type = "MyObject";
$object = new $type();

$message = $object->myfunc();
$message = MyObject->myfunc();
$message = call_user_func(array(&$type, "myfunc"));

O.K., so it's not using the scope resolution operator, but it does what you want... it calls 'myfunc' statically from the class named by $type.
up
-1
tango23 at inbox dot lv
10 years ago
>> That's how to make class' static variable in PHP4.

Note, that nobody seems to have a way of actually making a global static server-wide object in PHP.

All the static/class var ways above work only within a single PHP page.

If you want to do something like:

class Logger
{
   ...
   function Logger($filepath)
   ...
}

in some global include file:
$logobj = new Logger("mylogfile");

and then in all of your pages:

$logobj->log("my message");

and there is no way you can make this logobj static (such that all your pages can refer to without making unncecessary copies).

Can't be done with using uninstantiated Logger::log() funcs either, because you are not setting the logfile filepath parameter anywhere persistent.

The only kludge seems to be to use the filepath as a global variable and use Logger:: syntax.
up
-1
peterjoel.com
12 years ago
You can implement a getter/setter pair to emulate a class variable. The syntax isn't so weird:

<?

class A{
    function getVar($val=NULL){
        static $class_variable = 0;
        if($val != NULL){
            $class_variable = $val;
        }
        return $class_variable;
    }
    function setVar($val=0){
        return A::getVar($val);
    }
}

A::setVar(3);
print A::getVar();

?>
up
-2
steven at caltech dot co dot uk
12 years ago
Re: jdominic@prodigy.net 08-Aug-2002 05:49

While it would be nice to have static instance variables you can simply create a method with the same name which returns the value you require. This means you don't have to instantiate an object when you only need its static content. For example:

class Colour {

      function default () { return "black"; }
}

var $backgroundColour = Colour::default ();
To Top