That's the problem, how can I call a class variable from a class function? Let me explain better:
<?php
class Mine
{
private $g = 'gg';
const COSTANTE = 'valo';
public static function sayHello()
{
echo self::COSTANTE;
echo '<br>';
echo $this->g;
}
}
$h = new Mine();
$h->sayHello();
$h::sayHello();
?>
when I run this, it just print the constant COSTANTE.... Why it doesn't print the variable g?
Turn on error reporting ( error_reporting ( E_ALL ); ), and you should receive the following error:
Fatal error: Using $this when not in object context
The pseudo-variable $this is a reference to the calling object, and is available from within an object context.
self is used to access the current class, since static functions can be called without the actual object instance, when the method is called statically $this reference does not exists.
A method declared as static can be accessed with an instantiated class object ( but it is always executed in a static context ), a property declared as static cannot.
valo will be printed but gg and will not.
The issue is because you have used a non-static variable in a static method which will raise a FATAL error and will stop execution. This is because there is no object context.
Its not encouraged to use non-static variable inside static methods but, in case you need to use one, you have to create an object first.
Your sayHello function will be something like
public static function sayHello()
{
echo self::COSTANTE;
echo '<br>';
$mineObject = new Mine;
echo $mineObject->g;
}
I will also suggest keep error reporting and display errors ON while developing so that you can have a better idea of whats happening out there.
error_reporting(E_ALL);
ini_set('display_errors', 'ON');
Related
I'm not so sure what the following object instantiation is called but it comes from a article that i'm reading.
class foo
{
function out()
{
return 'hello';
}
}
echo (new foo())->out();
The object is instantiated automatically and calls the out method. But what i dont really understand is when i rename the out() method into a fictitious method i get an error like this:
example:
class foo
{
function out()
{
return 'hello';
}
}
echo (new foo())->ou();
Fatal error: Call to undefined method foo::ou() in ...
Is this method somehow being called as a static method?
The :: does not stand for static method, this is a missconception. The :: is a "scope resolution operator", it denotes the identification of a method by its class predicated full name.
So this simply means: "method 'ou' as defined by class 'foo'". Not more, not less.
No. The error just indicates that the method doesn't exist. It always shows the :: for this error, no matter whether you call the method in a static way or not. You would get the same error if you changed the code to:
$foo = new foo();
echo $foo->ou();
Second code example as per request in comments:
$moo = new moo(); // Parentheses optional, I guess
$foo = new foo($moo);
$foo->out();
I have found different information regarding static variables in PHP but nothing that actually explains what it is and how it really works.
I have read that when used within a class that a static property cannot be used by any object instantiated by that class and that a static method can be used by an object instantiated by the class?
However, I have been trying to research what a static variable does within a function that is not in a class. Also, does a static variable within a function work somewhat like closure in javascript or am I totally off in this assumption?
I have read that when used within a class that a static property cannot be used by any object instantiated by that class
It depends on what you mean by that. eg:
class Foo {
static $my_var = 'Foo';
}
$x = new Foo();
echo $x::$my_var; // works fine
echo $x->my_var; // doesn't work - Notice: Undefined property: Foo::$my_var
and that a static method can be used by an object instantiated by the class???
Yes, an instantiated object belonging to the class can access a static method.
The keyword static in the context of classes behave somewhat like static class variables in other languages. A member (method or variable) declared static is associated with the class and rather than an instance of that class. Thus, you can access it without an instance of the class (eg: in the example above, I could use Foo::$my_var)
However, I have been trying to research what a static variable does within a function that is not in a class.
Also, does a static variable within a function work somewhat like closure in javascript or am I totally off in this assumption.
Outside of classes (ie: in functions), a static variable is a variable that doesn't lose its value when the function exits. So in sense, yes, they work like closures in JavaScript.
But unlike JS closures, there's only one value for the variable that's maintained across different invocations of the same function. From the PHP manual's example:
function test()
{
static $a = 0;
echo $a;
$a++;
}
test(); // prints 0
test(); // prints 1
test(); // prints 2
Reference: static keyword (in classes), (in functions)
static has two uses in PHP:
First, and most commonly, it can be used to define 'class' variables/functions (as opposed to instance variables/functions), that can be accessed without instantiating a class:
class A {
public static $var = 'val'; // $var is static (in class context)
public $other_var = 'other_val'; // non-static
}
echo A::$var; // val
echo A::$other_var // doesn't work (fatal error, undefined static variable)
$a = new A;
echo $a->var // won't work (strict standards)
echo $a->other_var // other_val
Secondly, it can be used to maintain state between function calls:
function a() {
static $i = 0;
$j = 0;
return array($i++, $j++);
}
print_r(a()); // array(0, 0)
print_r(a()); // array(1, 0)
print_r(a()); // array(2, 0)
//...
Note that declaring a variable static within a function works the same regardless of whether or not the function is defined in a class, all that matters is where the variable is declared (class member or in a function).
A static variable in a function is initialized only in the first call of that function in its running script.
At first i will explain what will happen if static variable is not used
<?php
function somename() {
$var = 1;
echo $var . "<br />";
$var++;
}
somename();
somename();
somename();
?>
If you run the above code the output you gets will be 1 1 1 . Since everytime you called that function variable assigns to 1 and then prints it.
Now lets see what if static variable is used
<?php
function somename() {
static $var = 1;
echo $var . "<br />";
$var++;
}
somename();
somename();
somename();
?>
Now if you run this code snippet the output will be 1 2 3.
Note: Static keeps its value and stick around everytime the function is called. It will not lose its value when the function is called.
class Student {
static $total_student = 0;
static function add_student(){
return Student::$total_student++;
}
}
First: for the add_student function, the best practice is to use static not public.
Second: in the add_student function, we are using Student::$total_student,not use $this->total_student. This is big different from normal variable.
Third:static variable are shared throughout the inheritance tree.
take below code to see what is the result:
class One {
static $foo ;
}
class Two extends One{}
class Three extends One{}
One::$foo = 1;
Two::$foo = 2;
Three::$foo = 3;
echo One::$foo;
echo Two::$foo;
echo Three::$foo;`
http://codepad.viper-7.com/ezvlkQ
So, I'm trying to figure out:
...?php
$object = new A();
class A
{
static public $foo = 'bar';
function displayFoo()
{
echo $this->$foo;
}
}
A::displayFoo();
A->displayFoo();
?>
About this, how many errors can you find? Can you tell me what they are in real human terms? I can't really interpret what is and what is not okay from the validator that codepad uses...
I’ve updated your code here http://codepad.viper-7.com/UaUE4g
Error 1:
echo $this->$foo;
This should read:
echo self::$foo;
.. as it is static.
Error 2:
A::displayFoo();
The method is an instance method :: is used for access to static methods.
Error 3:
A->displayFoo();
This is an error because A is undefined and if it was it should have read $A. This would be okay:
$object->displayFoo();
.. as $object is an instance of class A.
Next step, consult the manual on the topic static.
Not sure where to start. Static methods belong to the class, normal methods belong to an object, an instantiation of that class. For example, you can have:
Class A {
static public $foo = 'WOOHOOO';
static function displayFoo() {
echo self::$foo;
}
}
echo A::displayFoo();
This works because you're calling the displayFoo method belonging to class A. Or you can do this:
Class A {
public $foo = "WOOHOO";
public function displayFoo() {
echo $this->foo;
}
}
$obj = new A();
$obj->displayFoo();
Now you're creating an object based on the class of A. That object can call its methods. But the object doesn't have static methods. If you were to declare the function static, it would not be available to $obj.
You can't do:
A->displayFoo()
at all, under any circumstances, ever. The -> operator assumes an object, and A can't be an object because its not a variable.
You can read up on static class members in the manual here:
http://php.net/static
Pay close attention to the examples.
class t {
public function tt()
{
echo 1;
}
}
t::tt();
See?The non-static function can also be called at class level.So what's different if I add a static keyword before public?
Except that, if you try to use $this in your method, like this :
class t {
protected $a = 10;
public function tt() {
echo $this->a;
echo 1;
}
}
t::tt();
You'll get a Fatal Error when calling the non-static method statically :
Fatal error: Using $this when not in object context in ...\temp.php on line 11
i.e. your example is a bit too simple, and doesn't really correspond to a real-case ;-)
Also note that your example should get you a strict warning (quoting) :
Calling non-static methods statically
generates an E_STRICT level warning.
And it actually does (At least, with PHP 5.3) :
Strict Standards: Non-static method t::tt() should not be called statically in ...\temp.php on line 12
1
So : not that good ;-)
Still, statically calling a non-static method doesnt't look like any kind of good practice (which is probably why it raises a Strict warning), as static methods don't have the same meaning than non-static ones : static methods do not reference any object, while non-static methods work on the instance of the class there're called on.
Once again : even if PHP allows you to do something (Maybe for historical reasons -- like compatibility with old versions), it doesn't mean you should do it !
The Static Keyword
Because static methods are callable without an instance of the object created, the pseudo-variable $this is not available inside the method declared as static.
Static properties cannot be accessed through the object using the arrow operator ->.
Calling non-static methods statically generates an E_STRICT level warning.
Just because you can call non-static methods statically doesn't mean you should. It's bad form.
In general a static method is also called class method while a non-static method is also called object method or instance method.
The difference between a class method and an object method is that class methods can only access class properties (static properties) while object methods are used to access object properties (properties of the very same class instance).
Static methods and properties are used to share common data over or for all instances of that specific class.
You could, for example, use a static property to keep track of the number of instances:
class A {
private static $counter = 0;
public function __construct() {
self::counter = self::counter + 1;
}
public function __destruct() {
self::counter = self::counter - 1;
}
public static function printCounter() {
echo "There are currently ".self::counter." instances of ".__CLASS__;
}
}
$a1 = new A();
$a2 = new A();
A::printCounter();
unset($a2);
A::printCounter();
Note that the static property counter is private so it can only be accessed by the class itself and instances of that class but not from outside.
A main difference that has not been mentioned relates to polymorphic behavior.
Non static methods, when redeclared in a derived class, override the base class method, and allow polymorphic behavior based on the type of the instance they are called on. This is not the case for static methods.
PHP 5.3 introduced the concept of late static binding which can be used to reference the called class in a context of static inheritance.
Yes, the critical difference is that methods declared static do not have access to the object-context variable, $this.
Additionally, invocation of a non-static method when not in object context will trigger an E_STRICT error event. When enabled, that event’s default behavior is to output a message to the error log (or STDERR), but it will allow the program to continue running.
Also, any attempt to reference $this when not in an object context will trigger an E_ERROR event. That event’s behavior is to output a message to the error log (or STDERR) and to exit the program with status 255.
For example:
<?php
error_reporting(-1);
//error_reporting(E_ALL);
class DualNature {
public static function fnStatic() {
if ( isset( $this ) ) {
// never ever gets here
$myValue = $this->_instanceValue;
} else {
// always gets here
$myValue = self::$_staticValue;
}
return $myValue;
}
public function fnInstance() {
if ( isset( $this ) ) {
// gets here on instance (->) reference only
$myValue = $this->_instanceValue;
} else {
// gets here in all other situations
$myValue = self::$_staticValue;
}
return $myValue;
}
public static function fnStaticDeath() {
return $this->_instanceValue;
}
private static $_staticValue = 'no access to $this';
private $_instanceValue = '$this is available';
}
$thing = new DualNature();
echo "==========\n";
printf("DualNature::fnStatic(): \"%s\"\n", DualNature::fnStatic() );
echo "==========\n";
printf("\$thing::fnStatic(): \"%s\"\n", $thing::fnStatic() );
echo "==========\n";
printf("\$thing->fnStatic(): \"%s\"\n", $thing->fnStatic() );
echo "==========\n";
printf("DualNature::fnInstance(): \"%s\"\n", DualNature::fnInstance() );
echo "==========\n";
printf("\$thing::fnInstance(): \"%s\"\n", $thing::fnInstance() );
echo "==========\n";
printf("\$thing->fnInstance(): \"%s\"\n", $thing->fnInstance() );
echo "==========\n";
printf("\$thing->fnStaticDeath(): \"%s\"\n", $thing->fnStaticDeath() );
echo "==========\n";
echo "I'M ALIVE!!!\n";
The output of the above is:
==========
PHP Strict Standards: Non-static method DualNature::fnInstance() should not be called statically in example.php on line 45
DualNature::fnStatic(): "no access to $this"
==========
$thing::fnStatic(): "no access to $this"
==========
$thing->fnStatic(): "no access to $this"
PHP Strict Standards: Non-static method DualNature::fnInstance() should not be called statically in example.php on line 47
==========
DualNature::fnInstance(): "no access to $this"
==========
$thing::fnInstance(): "no access to $this"
==========
$thing->fnInstance(): "$this is available"
==========
PHP Fatal error: Using $this when not in object context in example.php on line 29
Changing the error reporting level to E_ALL will suppress the default E_STRICT warning messages (the event will still be propagated), but the invalid reference to $this will still cause a fatal error and will exit the program.
Besides the syntax and functional differences there is also a performance difference that matters.
You can refer to this more or less detailed comparison of static and non-static methods in PHP.
Up until the yesterday I though that both of these methods for accessing a class where identical. Google turned up noting (either that or my keywords were bad). What is the difference between accessing a class by defining a new instance of the class rather than just calling the class methods directly.
I hardly understood what I just ask, since I have not a clue what I'm asking but allow me to give a few examples to help out.
For as long as I have been using classes in PHP I have been defining a instance of the class then accessing the methods from that variable. Here is an example:
<?php
class Myclass
{
public function my_method() {
return "This is my method";
}
}
$myclass = new Myclass();
echo $myclass->my_method(); // output: This is my method
?>
What is the difference between that and doing this?
<?php
class Myclass
{
public function my_method() {
return "This is my method";
}
}
echo Myclass::my_method(); // output: This is my method
?>
I hope I was clear enough. If not a brief synopsis would be - What is the difference between creating a new instance of a class then calling a method of the class with "$class->mymethod();," or just directly calling the method like so: "Myclass::mymethod();"?
Thanks in advance.
The :: notation is used to call the function as static. See these pages from the PHP manual for more info:
http://www.php.net/manual/en/language.oop5.paamayim-nekudotayim.php
http://php.net/manual/en/language.oop5.static.php.
In essence, static functions are just like regular functions outside classes. The function is not in object context when called as such, so the pseudo-variable $this is not available.
Note that the function should be declared as static if you are planning on calling it as such:
class SomeClass {
static public function StaticFunction() {
...
}
}
The Myclass::my_method() call should be throwing an E_STRICT warning, as you're calling a non-static method in a static context.
Static methods are methods that belong to the class rather than to the instance. These methods cannot access any non-static variables, as they have no reference for them (because non-static variables belong to the instance, not the class).
After using Java and C#, I'm mildly disturbed that this isn't considered an E_WARNING or E_ERROR, particularly since E_STRICT is not logged by default.
First, you should understand the difference between a class and an object, or a class and an instance of a class.
For example, where class is "Circle", an instance might be "this particular circle". Class Circle might have members $center and $radius - every point has these. But the values of these are different for every point.
$class->mymethod() is a call to an instance method, for instance $circle->Length(). You are saying something to a particular instance of an object. This method will have access to class members - variables that belong to the instance. In PHP you gain access to these instance variables using keyword $this.
For instance $circle->Length() might be implemented as return 2*Pi*$this->radius;
What happens when you say Circle::Length()? Nothing. This is syntax for calling static methods. Because you did not say which circle. Circle as a class does not have length.
Static method is declared with keyword static. Whatever it does it has no access to any instances of the class. It's something that a class as a whole does.
For instance, if you want to calculate length of the circle without actually creating one, then there might be static function calculateLength($radius) in the class circle. And you would call it as Circle::calculateLength($myRadius)
In my opinion you should not even think about static methods until you understand the non-static ones.
http://www.php.net/manual/en/language.oop5.paamayim-nekudotayim.php
I don't think you can call methods that way. I thought that was how you called static members of the class.
In my understanding when you create an instance of the class you are creating an object and so you call methods/properties from that object.
When you call a method/property via a static call you are calling on the class itself.
So if you have something like this:
class acs {
public $var = 'bla';
}
and then you do
$a = new acs();
$b = new acs();
echo $a->var . '<br>';
echo $b->var . '<br>';
$a->var = 'hey';
$b->var = 'Yooo';
echo $a->var . '<br>';
echo $b->var . '<br>';
You now have 2 instances of class acs which started with the same values but now have different values.
But if you have this:
class acs {
public static $var = 'bla';
}
And then do:
$a = new acs();
$b = new acs();
echo $a->var . '<br>';
echo $b->var . '<br>';
$a->var = 'hey';
$b->var = 'Yooo';
echo $a->var . '<br>';
echo $b->var . '<br>';
echo acs::$var;
What you are doing is:
You create the instances as before.
You echo nothing, because the public property var does not exist.
You create the public property var in both the instances
You echo their values (hey and Yoo)
You echo the static property var (which is 'bla' and has not changed)
Hope this helps!