I have a static function being called that is giving a strange error. Here is an example of the php code:
class foo {
public $stat;
public function __construct() {
$this->stat = stat::isValid('two');
}
}
class stat {
protected static $invalidNumbers = array('one', 'two');
function isValid($number) {
return in_array($number, static::$invalidNumbers);
}
}
$foo = new foo();
var_dump($foo->stat);
This code results in the following error:
Fatal error: Access to undeclared static property: foo::$invalidNumbers
However changing static:: to self:: makes the code behave as expected. I was under the impression that in this context using static:: should work.
Why does this error occur using static?
You begin by making a method call in a static context:
stat::isValid('two');
When you do this, PHP "remembers" the context from within which isValid was called specifically so that it can resolve what to bind to when it sees something like static:: inside the method body, determine if some property you are trying to access is visible, and in general be able to implement some OO-related language features.
The actual method isValid is not static, but PHP still allows you to call it using the static method syntax (it does give an E_STRICT warning about that). However, this has the side effect that isValid itself does not participate in modifying the curent calling context for (late) static bindings.
The result: when PHP sees static::$invalidNumbers, it still thinks you are halfway through making a static method call from within the foo class! Once you realize this, it is obvious why static:: resolves to foo:: and it ends up looking for the property at the wrong place.
If you correctly declare isValid as static
static function isValid($number) {
return in_array($number, static::$invalidNumbers);
}
then upon calling the method PHP does update its context internally and manages to bind to the intended member.
You are trying to call the method stat::isValid() statically but have not declared it static. Change the stat class to:
class stat {
protected static $invalidNumbers = array('one', 'two');
// needs to be declared static
static function isValid($number) {
return in_array($number, static::$invalidNumbers);
}
}
Note that, if you add
| E_STRICT
to your error_reporting in php.ini you would see a message like:
Strict standards: Non-static method stat::isValid() should not be called statically, assuming $this from incompatible context in ...
Declare static method properly
Replace
function isValid($number) {
With
public static function isValid($number) {
^--- here
Related
I've got a problem:
I'm writing a new WebApp without a Framework.
In my index.php I'm using: require_once('load.php');
And in load.php I'm using require_once('class.php'); to load my class.php.
In my class.php I've got this error:
Fatal error: Using $this when not in object context in class.php on line ... (in this example it would be 11)
An example how my class.php is written:
class foobar {
public $foo;
public function __construct() {
global $foo;
$this->foo = $foo;
}
public function foobarfunc() {
return $this->foo();
}
public function foo() {
return $this->foo;
}
}
In my index.php I'm loading maybe foobarfunc() like this:
foobar::foobarfunc();
but can also be
$foobar = new foobar;
$foobar->foobarfunc();
Why is the error coming?
In my index.php I'm loading maybe
foobarfunc() like this:
foobar::foobarfunc(); // Wrong, it is not static method
but can also be
$foobar = new foobar; // correct
$foobar->foobarfunc();
You can not invoke the method this way because it is not a static method.
foobar::foobarfunc();
You should instead use:
$foobar->foobarfunc();
If however, you have created a static method something like:
static $foo; // your top variable set as static
public static function foobarfunc() {
return self::$foo;
}
then you can use this:
foobar::foobarfunc();
You are calling a non-static method :
public function foobarfunc() {
return $this->foo();
}
Using a static-call :
foobar::foobarfunc();
When using a static-call, the function will be called (even if not declared as static), but, as there is no instance of an object, there is no $this.
So :
You should not use static calls for non-static methods
Your static methods (or statically-called methods) can't use $this, which normally points to the current instance of the class, as there is no class instance when you're using static-calls.
Here, the methods of your class are using the current instance of the class, as they need to access the $foo property of the class.
This means your methods need an instance of the class -- which means they cannot be static.
This means you shouldn't use static calls : you should instanciate the class, and use the object to call the methods, like you did in your last portion of code :
$foobar = new foobar();
$foobar->foobarfunc();
For more informations, don't hesitate to read, in the PHP manual :
The Classes and Objects section
And the Static Keyword page.
Also note that you probably don't need this line in your __construct method :
global $foo;
Using the global keyword will make the $foo variable, declared outside of all functions and classes, visibile from inside that method... And you probably don't have such a $foo variable.
To access the $foo class-property, you only need to use $this->foo, like you did.
If you are invoking foobarfunc with resolution scope operator (::), then you are calling it statically, e.g. on the class level instead of the instance level, thus you are using $this when not in object context. $this does not exist in class context.
If you enable E_STRICT, PHP will raise a Notice about this:
Strict Standards:
Non-static method foobar::foobarfunc() should not be called statically
Do this instead
$fb = new foobar;
echo $fb->foobarfunc();
On a sidenote, I suggest not to use global inside your classes. If you need something from outside inside your class, pass it through the constructor. This is called Dependency Injection and it will make your code much more maintainable and less dependant on outside things.
First you understand one thing, $this inside a class denotes the current object.
That is which is you are created out side of the class to call class function or variable.
So when you are calling your class function like foobar::foobarfunc(), object is not created.
But inside that function you written return $this->foo(). Now here $this is nothing. Thats why its saying Using $this when not in object context in class.php
Solutions:
Create a object and call foobarfunc().
Call foo() using class name inside the foobarfunc().
When you call the function in a static context, $this simply doesn't exist.
You would have to use this::xyz() instead.
To find out what context you're in when a function can be called both statically and in an object instance, a good approach is outlined in this question: How to tell whether I’m static or an object?
Fast method : (new foobar())->foobarfunc();
You need to load your class replace :
foobar::foobarfunc();
by :
(new foobar())->foobarfunc();
or :
$Foobar = new foobar();
$Foobar->foobarfunc();
Or make static function to use foobar::.
class foobar {
//...
static function foobarfunc() {
return $this->foo();
}
}
It seems to me to be a bug in PHP.
The error
'Fatal error: Uncaught Error: Using $this when not in object context
in'
appears in the function using $this, but the error is that the calling function is using non-static function as a static. I.e:
Class_Name
{
function foo()
{
$this->do_something(); // The error appears there.
}
function do_something()
{
///
}
}
While the error is here:
Class_Name::foo();
$foobar = new foobar; put the class foobar in $foobar, not the object. To get the object, you need to add parenthesis: $foobar = new foobar();
Your error is simply that you call a method on a class, so there is no $this since $this only exists in objects.
Just use the Class method using this foobar->foobarfunc();
I've got a problem:
I'm writing a new WebApp without a Framework.
In my index.php I'm using: require_once('load.php');
And in load.php I'm using require_once('class.php'); to load my class.php.
In my class.php I've got this error:
Fatal error: Using $this when not in object context in class.php on line ... (in this example it would be 11)
An example how my class.php is written:
class foobar {
public $foo;
public function __construct() {
global $foo;
$this->foo = $foo;
}
public function foobarfunc() {
return $this->foo();
}
public function foo() {
return $this->foo;
}
}
In my index.php I'm loading maybe foobarfunc() like this:
foobar::foobarfunc();
but can also be
$foobar = new foobar;
$foobar->foobarfunc();
Why is the error coming?
In my index.php I'm loading maybe
foobarfunc() like this:
foobar::foobarfunc(); // Wrong, it is not static method
but can also be
$foobar = new foobar; // correct
$foobar->foobarfunc();
You can not invoke the method this way because it is not a static method.
foobar::foobarfunc();
You should instead use:
$foobar->foobarfunc();
If however, you have created a static method something like:
static $foo; // your top variable set as static
public static function foobarfunc() {
return self::$foo;
}
then you can use this:
foobar::foobarfunc();
You are calling a non-static method :
public function foobarfunc() {
return $this->foo();
}
Using a static-call :
foobar::foobarfunc();
When using a static-call, the function will be called (even if not declared as static), but, as there is no instance of an object, there is no $this.
So :
You should not use static calls for non-static methods
Your static methods (or statically-called methods) can't use $this, which normally points to the current instance of the class, as there is no class instance when you're using static-calls.
Here, the methods of your class are using the current instance of the class, as they need to access the $foo property of the class.
This means your methods need an instance of the class -- which means they cannot be static.
This means you shouldn't use static calls : you should instanciate the class, and use the object to call the methods, like you did in your last portion of code :
$foobar = new foobar();
$foobar->foobarfunc();
For more informations, don't hesitate to read, in the PHP manual :
The Classes and Objects section
And the Static Keyword page.
Also note that you probably don't need this line in your __construct method :
global $foo;
Using the global keyword will make the $foo variable, declared outside of all functions and classes, visibile from inside that method... And you probably don't have such a $foo variable.
To access the $foo class-property, you only need to use $this->foo, like you did.
If you are invoking foobarfunc with resolution scope operator (::), then you are calling it statically, e.g. on the class level instead of the instance level, thus you are using $this when not in object context. $this does not exist in class context.
If you enable E_STRICT, PHP will raise a Notice about this:
Strict Standards:
Non-static method foobar::foobarfunc() should not be called statically
Do this instead
$fb = new foobar;
echo $fb->foobarfunc();
On a sidenote, I suggest not to use global inside your classes. If you need something from outside inside your class, pass it through the constructor. This is called Dependency Injection and it will make your code much more maintainable and less dependant on outside things.
First you understand one thing, $this inside a class denotes the current object.
That is which is you are created out side of the class to call class function or variable.
So when you are calling your class function like foobar::foobarfunc(), object is not created.
But inside that function you written return $this->foo(). Now here $this is nothing. Thats why its saying Using $this when not in object context in class.php
Solutions:
Create a object and call foobarfunc().
Call foo() using class name inside the foobarfunc().
When you call the function in a static context, $this simply doesn't exist.
You would have to use this::xyz() instead.
To find out what context you're in when a function can be called both statically and in an object instance, a good approach is outlined in this question: How to tell whether I’m static or an object?
Fast method : (new foobar())->foobarfunc();
You need to load your class replace :
foobar::foobarfunc();
by :
(new foobar())->foobarfunc();
or :
$Foobar = new foobar();
$Foobar->foobarfunc();
Or make static function to use foobar::.
class foobar {
//...
static function foobarfunc() {
return $this->foo();
}
}
It seems to me to be a bug in PHP.
The error
'Fatal error: Uncaught Error: Using $this when not in object context
in'
appears in the function using $this, but the error is that the calling function is using non-static function as a static. I.e:
Class_Name
{
function foo()
{
$this->do_something(); // The error appears there.
}
function do_something()
{
///
}
}
While the error is here:
Class_Name::foo();
$foobar = new foobar; put the class foobar in $foobar, not the object. To get the object, you need to add parenthesis: $foobar = new foobar();
Your error is simply that you call a method on a class, so there is no $this since $this only exists in objects.
Just use the Class method using this foobar->foobarfunc();
class Duck {
public function quack() {
$this->swim();
}
public function swim() {
echo 'I\'m swimming!';
}
}
class Plane {
public function fly() {
Duck::quack();
}
public function swim()
{
echo 'I can\'t swim! People are DROWNING!';
}
}
$plane = new Plane();
$plane->fly();
I got asked the above question and gave the answer that the output is an error illegally calling static method.
But it actually prints "I'm swimming!".
Could somebody please explain why this happens?
It works by default, but if you turn on E_STRICT you'll get
PHP Strict Standards: Non-static method Duck::quack() should not be called statically in...
PHP sees that you wanted swim() to be actually static and so it let's you simply call it.
Something to note with PHP 5.3 (and public methods):
CAN call public methods statically from anywhere INSIDE Object context (only if inside instantiated object)...even if not declared static
Duck::quack();
CANT call protected method in same scenario.
Duck::quack(); //error
protected function quack() { }
CANT call public properties (instance variables) statically from anywhere INSIDE Object context, unless declared static...
class Duck {
public $hello = 'hello there';
}
class Plane {
Duck::$hello; //error
}
CANT call public methods (or properties) statically from OUTSIDE object context..unless declared static
Duck::quack(); //error
Other languages use this type of engine flexibility, calling any public method statically as long as from inside Object context.
As mentioned (by #poitroae) it works like this by default, but if you turn on E_STRICT you'll get an error.
ALSO:
It is a known idiosyncrasy with PHP that you should'nt be allowed to call $this in this Context. The program should be under Class Context at this point (being called statically) but $this works which is akin to Object Context.
If this were a statically declared Method than calling $this would cause an instant fatal error.
Hope that helps
If I call public function using scope resolution operator, It is not giving any error.
class Parent_class
{
public function st_function()
{
echo "*************parent class************\n";
}
}
Parent_class:: st_function();
But in PHP documentation on php.net, it ig given that - Calling non-static methods statically generates an E_STRICT level warning. Also its given that - Static properties cannot be accessed through the object using the arrow operator ->
But its not giving any error. Can anyone explain?
class Parent_class
{
public static function st_function()
{
echo "*************parent class************\n";
}
}
Parent_class:: st_function();
$var = new Parent_class();
$var->st_function();
Static properties can not be accessed through the object, but not static methods.
From the doc.
Declaring class properties or methods as static makes them accessible
without needing an instantiation of the class. A property declared as
static can not be accessed with an instantiated class object (though
a static method can).
If you activate strict error reporting, you will see an error for calling a non-static method statically:
error_reporting(E_ALL | E_STRICT);
For the second part, where you call a static method non-statically, that will work because the paragraph in the manual talks about static properties, not methods. You cannot access Parent_class::static_property like Parent_class->static_property, if it had such a property.
Calling static methods of objects works fine, in that case the $var-> is just a convenience shorthand for Parent_class::.
Try this before your code:
error_reporting(E_ALL | E_STRICT);
What is the difference between these two pieces of code?
class something {
static function doit() {
echo 'hello world';
}
}
something::doit();
and the same but without the static keyword
class something {
function doit() {
echo 'hello world';
}
}
something::doit();
They both work the same is it better to use the static keywords? Am i right in understanding that it doesn't instantiate the class if you use the static method?
The second example is technically incorrect - if you turn on E_STRICT error reporting you'll see that PHP is actually throwing an error.
PHP Strict Standards: Non-static
method something::doit() should not be
called statically in...
In other words, it's being nice and letting you call the function anyway.
In addition to the other valid answers, the reason for the 2nd example working is also due to a quirk in how PHP handles objects and calls (Besides PHP 4 compatibility). Calling a non-static declared method statically from within another instance will let you access class methods on other classes as if they were local. To understand, let's take an example:
class A {
public function foo() {
echo get_class($this) . "\n";
}
}
class B {
public function bar() {
A::foo();
}
}
$a = new a();
$a->foo(); // "A"
$b = new B();
$b->bar(); // "B"
Did you see what happened there? Because you called the A::foo() method from within another class's instance, PHP treated the call as if it was on the same instance. Note that there is no relationship between A and B other than the fact that B calls A. Within A->foo(), if we did $this instanceof A (or $this instanceof self), it would fail and return false! Quite unusual...
Now, I first thought it was a bug, but after reporting it, it's apparently as designed. It's even in the docs.
Note that this will not work with E_STRICT mode enabled. It also will not work if you declare a method as static.
The difference is that static functions can be used without having to create an instance of the class.
Have a look at this great PHP OOP beginner tutorial here. It explains in more detail with an example under the Static Properties and Methods section.
Second bit shouldn't work as you should call it by
$something = new something();
$something->doit();
Static functions allows you to call a function within a class without consturcting it.
So basically if you have a class to handle users, so a function that logs the user in should be a static function, as in the constructor of that class you will probably gather the user information and you cannot do so without logging him in.
Your second example is wrong. Using a static method does not create an instance of the class. Your second example should look like this:
$x = new something();
$x->doit();
Static methods should be declared static for minimum two reasons:
a) when using E_STRICT error_reporting, calling non static method as static will generate error:
Strict standards: Non-static method something::doit() should not be called statically
b) based on keyword static some IDE's filter method possible to run at auto-complete.