I'm having a method inside a class, in which I want to initialize a static variable.
1/ when I initialize the variable, then affect it to some other value using the $this keyword, it works. E.g.:
class Test {
// ...
function test($input_variable)
{
static $my_static_variable = null;
if (!isset($my_static_variable))
$my_static_variable = $this->someFunction($input_variable);
// ... some further processing
}
}
2/ However, when I try to directly initialize / construct the variable with the $this keyword, there is a syntax error : unexpected '$this' (T_VARIABLE):
class Test {
// ...
function test($input_variable)
{
static $my_static_variable = $this->someFunction($input_variable); // *** syntax error, unexpected '$this' (T_VARIABLE)
// ... some further processing
}
}
Is 1/ a good way to initialize a static variable?
Why is 2/ not allowed, as it is supposed to do the exact same thing than in 1/?
I'm using PHP 5.5.21 (cli) (built: Jul 22 2016 08:31:09).
Thanks
You can't use $this on a static variable. You can use self with scope resolution operator (::) instead.
Here is the example:
class Foo {
public static $my_stat;
static function init() {
self::$my_stat= 'My val';
}
}
Static variable and function can be accessed without instantiation of the class. You can not use $this to access the variable or function declared as static.
You have to use scope resolution operator:: to access variable and functions declared as static.
For variables:-
class A
{
static $my_static = 'foo';
public function staticValue() {
return self::$my_static;// Try to use $this here insted of self:: you will get error
}
}
class B extends A
{
public function fooStatic() {
return parent::$my_static;
}
}
Use to the following to access the variable:-
print A::$my_static
For functions:-
class A {
public static function aStaticMethod() {
// ...
}
}
You can call the function as follows:-
A::aStaticMethod();
I think I have the answer. In the php documentation, it is stated the following:
Static variables may be declared as seen in the examples above. From
PHP 5.6 you can assign values to these variables which are the result
of expressions, but you can't use any function here, what will cause a
parse error.
So I guess this also holds for PHP 5.5.
As #MagnusEriksson pointed out, I could have used a class property as well. However, I don't want my variable to be accessed somewhere else apart from the test() method.
BTW, somehow the same thing is stated for static properties in the doc:
Static properties cannot be accessed through the object using the
arrow operator ->.
Like any other PHP static variable, static properties may only be
initialized using a literal or constant before PHP 5.6; expressions
are not allowed. In PHP 5.6 and later, the same rules apply as const
expressions: some limited expressions are possible, provided they can
be evaluated at compile time.
Related
<?php
class c1
{
public static function f1()
{
return "hello";
}
public static $a=10;
public function f2()
{
echo $this->f1(); //prints "hello"
echo $this->a;//ERROR:Undefined property: c1::$a in C:\wamp\www\class_in_php\example5.php on line 14
}
}
$obj1=new c1;
$obj1->f2();
?>
Why can't we access a static variable of a class using $this or an object of that class???
But we can access a static function of that class using $this or an object of that class.
What is the reason behind such a phenomenon?
You should use self:: instead of $this-> to access static members.
The reason is that $this refers to the current instance of the class, while static members are part of the class itself, not of the instance.
A static variable belongs not to an "instance" but to the class itself. When you have in actual "instance" of the class at runtime, then and only then does the $this pointer make sense: it means "this instance that I find myself inside right now"... how could you use the $this pointer to reference something that doesn't exist outside of an instance?
When I first learned C++ it was with (Metacomco I think) a system that actually used a huge pile of C preprocessor macros to simulate objects and it was very enlightening to see and hence understand that the $this (this in C++) is in fact just an extra parameter passed as the first parameter to all method functions:
this->foo("Hello");
this->bar(42, "Finished");
is actually executed like this:
foo(this_ptr, "Hello");
bar(this_ptr, 42, "Finished");
and inside the foo() function any reference to a method variable such as:
this->status
is nothing more than a reference to a pointer dereferenced variable:
this_ptr->status
So you can see that trying to access a static variable from a this pointer is going to blow because it just isn't a member of that particular chunk of memory. That's how things "used to work" but I think the explanation is still a good one.
Hope that help!
:)
Why can't we access a static variable of a class using $this or an object of that class? But we can access a static function of that class using $this or an object of that class.
Well, we can, however you used the wrong syntax.
Wrong:
echo $this->a;
Right:
$this::$a;
As c1::$a is a static class variable, you need to use the right syntax, that is with double-colon :: and then the dollar-sign ($) to denote the variable: $this::$a.
However, do not get fooled by that syntax too easy, because the reason that
$this->f1()
works while c1::f1() is a static function is because of backwards compatibility as before PHP version 5 there were no static class methods (as those explicitly defined by the static keyword) and with the very first PHP 5 version -> could be used to call static class methods.
However to access static class variables via $this is a PHP 5.3+ syntax feature, so much newer.
Example code (run against multiple PHP versions):
<?php
/**
* #link http://stackoverflow.com/a/24059368/367456
*/
class c1
{
public static function f1()
{
return "hello";
}
public static $a = 10;
public function f2()
{
echo $this->f1(); // prints "hello"
echo $this->a; // Strict Standards: Accessing static property c1::$a as non static
echo $this::$a; // prints "10" (PHP <= 5.2.17: Parse error)
}
}
$obj1 = new c1;
$obj1->f2();
class A{
static $var = true;
function f(){
}
}
vs
class A{
function f(){
static $var = true;
}
}
There doesn't seem to be any difference. Are there any advantages of using one over the other?
Note that $var would be used in the f() function only. I understand that declaring it in the class header is required if the variable needs to be used in multiple functions
If you only use the static variable in the f function, there's only a scope difference, that means no difference as long as you don't try to use it elsewhere.
When used in local scope, the static variable value is kept between each function call. See Static variables part of this page.
Thanks insertusernamehere for pointing that out.
In the later example you may only use the var inside the f function. The other is accessible anywhere from inside the class A::var or outside A::var
Why in PHP you can access static method via instance of some class but not only via type name?
UPDATE: I'm .net developer but i work with php developers too. Recently i've found this moment about static methods called from instance and can't understand why it can be usefull.
EXAMPLE:
class Foo
{
public static Bar()
{
}
}
We can accept method like this:
var $foo = new Foo();
$foo.Bar(); // ??????
In PHP
the class is instantiated using the new keyword for example;
$MyClass = new MyClass();
and the static method or properties can be accessed by using either scope resolution operator or object reference operator. For example, if the class MyClass contains the static method Foo() then you can access it by either way.
$MyClass->Foo();
Or
MyClass::Foo()
The only rule is that static methods or properties are out of object context. For example, you cannot use $this inside of a static method.
Class Do {
static public function test() {
return 0;
}
}
use like this :
echo Do::test();
Why in PHP you can access static method via instance of some class but not only via type name?
Unlike what you are probably used to with .NET, PHP has dynamic types. Consider:
class Foo
{
static public function staticMethod() { }
}
class Bar
{
static public function staticMethod() { }
}
function doSomething($obj)
{
// What type is $obj? We don't care.
$obj->staticMethod();
}
doSomething(new Foo());
doSomething(new Bar());
So by allowing access to static methods via the object instance, you can more easily call a static function of the same name across different types.
Now I don't know if there is a good reason why accessing the static method via -> is allowed. PHP (5.3?) also supports:
$obj::staticMethod();
which is perhaps less confusing. When using ::, it must be a static function to avoid warnings (unlike ->, which permits either).
In PHP, while you're allowed to access the static method by referencing an instance of the class, you don't necessarily need to do so.
For example, here is a class with a static function:
class MyClass{
public static function MyFunction($param){
$mynumber=param*2;
return $mynumber;
}
You can access the static method just by the type name like this, but in this case you have to use the double colon (::), instead of "->".
$result= MyClass::MyFunction(2);
(Please note you can also access the static method via an instance of the class as well using "-->"). For more information: http://php.net/manual/en/language.oop5.static.php
In PHP 7 it seems to be absolutely necessary for you to be able to do $this->staticFunction(). Because, if this code is written within an abstract class and staticFunction() is also abstract in your abstract class, $this-> and self:: deliver different results!
When executing $this->staticFunction() from a (non-abstract) child of the abstract class, you end up in child::staticFunction(). All is well.
However, executing self::staticFunction() from a (non-abstract) child of the abstract class, you end up in parent::staticFunction(), which is abstract, and thusly throws an exception.
I guess this is just another example of badly designed PHP.
Or myself needing more coffee...
I am looking through some php code and I see this "::" notation that i have no idea what it means...also what the & in the front of the call
$mainframe =& JFactory::getApplication('site');
$sql="SELECT rt.member_id ,rt.commission,rt.sales,kt.store_id,kt.user_id FROM jos_report
rt JOIN jos_kingdom_tickets kt WHERE rt.member_id=kt.ticket_id";
$db =& JFactory::getDBO();
thanks in advance
::, the scope resolution operator, is used for referencing static members and constants of a class. It is also used to reference a superclass's constructor. Here is some code illustrating several different uses of the scope resolution operator:
<?php
class A {
const BAR = 1;
public static $foo = 2;
private $silly;
public function __construct() {
$this->silly = self::BAR;
}
}
class B extends A {
public function __construct() {
parent::__construct();
}
public static function getStuff() {
return 'this is tiring stuff.';
}
}
echo A::BAR;
echo A::$foo;
echo B::getStuff();
?>
A little trivia: The scope resolution operator is also called "paamayim nekudotayim", which means "two dots twice" in hebrew.
& in the context of your example isn't doing anything useful if you are using php 5 or greater and should be removed. In php 4, this used to be necessary in order to make sure a copy of the returned object wasn't being used. In php 5 object copies are not created unless clone is called. And so & is not needed. There is still one case where & is still useful in php 5: When you are iterating over the elements of an array and modifying the values, you must use the & operator to affect the elements of the array.
You can use it to reference static methods from a class without having to instantiate it.
For example:
class myClass {
public static function staticFunction(){
//...
}
public function otherFunction(){
//...
}
}
Here you could use myClass::staticFunction() outside of the class, but you would have to create a new myClass object before using otherFunction() in the same way.
:: is the scope operator in PHP, c++, but not in Java. In this case, it is used to call a static method of a class. A static method is a method which can be called from outside the class, even when you don't have an instance of it.
& indicates that rather than making a copy of what the function returns, it takes the reference to the object returned. In this case, they seem to return singleton objects which are used in the application, e.g. to interface with the database (in the second case)
It's the scope operator, used for referencing constants or static methods under classes. So:
class C {
const D = 2;
}
echo C::D; // 2
In your case, it calls a method of the class not tied to a particular instance.
I have seen function called from php classes with :: or ->.
eg:
$classinstance::function
or
$classinstance->function
whats the difference?
:: is used for scope resolution, accessing (typically) static methods, variables, or constants, whereas -> is used for invoking object methods or accessing object properties on a particular object instance.
In other words, the typical syntax is...
ClassName::MemberName
versus...
$Instance->MemberName
In the rare cases where you see $variable::MemberName, what's actually going on there is that the contents of $variable are treated as a class name, so $var='Foo'; $var::Bar is equivalent to Foo::Bar.
http://www.php.net/manual/en/language.oop5.basic.php
http://www.php.net/manual/language.oop5.paamayim-nekudotayim.php
The :: syntax means that you are calling a static method. Whereas the -> is non-static.
MyClass{
public function myFun(){
}
public static function myStaticFun(){
}
}
$obj = new MyClass();
// Notice how the two methods must be called using different syntax
$obj->myFun();
MyClass::myStaticFun();
Example:
class FooBar {
public function sayHi() { echo 'Hi!'; }
public /* --> */ static /* <-- */ function sayHallo() { echo 'Hallo!'; }
}
// object call (needs an instance, $foobar here)
$foobar = new FooBar;
$foobar->sayHi();
// static class call, no instance required
FooBar::sayHallo(); // notice I use the plain classname here, not $foobar!
// As of PHP 5.3 you can write:
$nameOfClass = 'FooBar'; // now I store the classname in a variable
$nameOfClass::sayHallo(); // and call it statically
$foobar::sayHallo(); // This will not work, because $foobar is an class *instance*, not a class *name*
::function is for static functions, and should actually be used as:
class::function() rather than $instance::function() as you suggest.
You can also use
class::function()
in a subclass to refer to parent's methods.
:: is normally used for calling static methods or Class Constants. (in other words, you don't need to instantiate the object with new) in order to use the method. And -> is when you've already instantiated a object.
For example:
Validation::CompareValues($val1, $val2);
$validation = new Validation;
$validation->CompareValues($val1, $val2);
As a note, any method you try to use as static (or with ::) must have the static keyword used when defining it. Read the various PHP.net documentation pages I've linked to in this post.
With :: you can access constants, attributes or methods of a class; the variables and methods need to be declared as static, otherwise they do belong to an instance and not to the class.
And with -> you can access attributes or methods of an instance of a class.