How to access static property of child class in php? [duplicate] - php

This question already has answers here:
Overriding class constants vs properties
(2 answers)
Inheritance of static members in PHP
(3 answers)
Closed 4 years ago.
<?php
class A{
static $var;
function test(){
var_dump(self::$var);
}
}
class B extends A{
static $var = 'something';
}
$b = new B();
$b->test();
?>
why does this print out null and how do I fix this? It works if I do not set $var as static but i need it to be accesible without creating an instance.

$b->test(); prints null because it is null. When you do this:
class B extends A{
static $var = 'something';
}
you're not actually doing anything to the $var property in your A class. The property is defined with the static keyword, and per the docs, "A property declared as static cannot be accessed with an instantiated class object (though a static method can)." Thus you cannot inherit it (or subsequently set it) from your B class.
If you want the test() method to output anything meaningful, you need to set it statically, such as:
A::$var = "something";

Related

PHP static properties and const overriding [duplicate]

This question already has answers here:
What is the difference between self::$bar and static::$bar in PHP?
(5 answers)
Closed 3 years ago.
I'm wanting to create an class inheriting (extending) another PHP class with a protected const that I want to override in my extending class.
I created a parent class (A for the example) and an inheriting class (B for the example). class A has a protected const (named CST) defined. class B overrides this const as well.
When calling a method class B inherited from A that displays self::CST, the printed value is the CST value from A, not the const CST overrided in B.
I observe the same behavior with a static property named $var.
It seems that self used in methods is always refering to the defining class (A in my example) and not the class used for calling the static method.
class A
{
protected static $var = 1;
protected const CST = 1;
public static function printVar()
{
print self::$var . "\n";
}
public static function printCST()
{
print self::CST . "\n";
}
}
class B extends A
{
protected static $var = 2;
protected const CST =2;
}
A::printVar();
A::printCST();
B::printVar();
B::printCST();
Is there a way to permit my static method printCST() to display 2 when called with B::printCST() without rewriting the method in class B and to benefit code reusability of OOP?
Dharman suggested to use static::CST instead of self::CST.
This was the solution to my problem.

How to Access the private member of class? [duplicate]

This question already has an answer here:
How to get object like value:item:private from PHP Array
(1 answer)
Closed 7 years ago.
xPostModel Object
(
[script:Model:private] => abc
)
I wanna change abc to efg how can i do it ? Is there any way ?
If you can't make changes to the class definition and there is no public setter method for the class property, and you really need to be able to directly edit the property outside the class, your only option is probably using Reflection methods, see example here: https://stackoverflow.com/a/6448613/1362634
Here is an example that should work in your case to set the private property $script in $obj of type xPostModel (where property is inherited from parent class Model):
$obj = new xPostModel();
$refProperty = new ReflectionProperty('Model', 'script');
$refProperty->setAccessible(true);
$refProperty->setValue($obj, 'def');
And here is a fully working code example with mockup class definitions to simulate the situation of the question.
<?php
error_reporting(-1);
ini_set('display_errors', 1);
class Model {
private $script = 'abc';
}
class xPostModel extends Model {}
$obj = new xPostModel();
print_r($obj); // Check original value of inherited private property
$refProperty = new ReflectionProperty('Model', 'script');
$refProperty->setAccessible(true);
$refProperty->setValue($obj, 'def');
print_r($obj); // Check that property has been changed

using self instead of this variable [duplicate]

This question already has answers here:
When should I use 'self' over '$this'?
(23 answers)
Closed 9 years ago.
I'm reading a book of php and found this code:
class Employee {
static public $NextID = 1;
public $ID;
public function _ _construct( ) {
$this->ID = self::$NextID++;
}
public function NextID( ) {
return self::$NextID;
}
}
why here is used self::$NextID++; can I use like this:
$this-ID = $this->$NextID++;
Because in php you have to reference static functions with self.
There was also an explanation on stackoverflow already: see here
When a class is called statically ie. ClassName::someMethod(), there is no "instance" of the class.
Since $this refers to the instance of the class, $this will not exist when your class is used statically. (so $this will only be available when you created an object of your class by using $var = new ClassName())
self refers to the class (not the object) so in static classes you can use self::.. to refer to properties or methods within the class.

Static within non-static method is shared between instances

I've come across some unexpected behavior with static variables defined inside object methods being shared across instances. This is probably known behavior, but as I browse the PHP documentation I can't find instances of statically-defined variables within object methods.
Here is a reduction of the behavior I've come across:
<?php
class Foo {
public function dofoo() {
static $i = 0;
echo $i++ . '<br>';
}
}
$f = new Foo;
$g = new Foo;
$f->dofoo(); // expected 0, got 0
$f->dofoo(); // expected 1, got 1
$f->dofoo(); // expected 2, got 2
$g->dofoo(); // expected 0, got 3
$g->dofoo(); // expected 1, got 4
$g->dofoo(); // expected 2, got 5
Now, I would have expected $i to be static per instance, but in reality $i is shared between the instances. For my own edification, could someone elaborate on why this is the case, and where it's documented on php.net?
This is the very definition of static.
If you want members to be specific to an instance of an object, then you use class properties
e.g.
<?php
class Foo
{
protected $_count = 0;
public function doFoo()
{
echo $this->_count++, '<br>';
}
}
Edit: Ok, I linked the documentation to the OOP static properties. The concept is the same though. If you read the variable scope docs you'll see:
Note: Static declarations are resolved in compile-time.
Thus when your script is compiled (before it executes) the static is "setup" (not sure what term to use). No matter how many objects you instantiate, when that function is "built" the static variable references the same copy as everyone else.
I agree that the current PHP documentation is not sufficiently clear on exactly what "scope" means for a static variable inside a non-static method.
It is of course true (as hobodave indicates) that "static" generally means "per class", but static class properties are not exactly the same thing as static variables within a (non static) method, in that the latter are "scoped" by method (every method in a class can have its own static $foo variable, but there can be at most one static class member named $foo).
And I would argue that although the PHP 5 behavior is consistent ("static" always means "one shared instance per class"), it is not the only way that PHP could behave.
For example, most people use static function variables to persist state across function calls, and for global functions the PHP behavior is exactly what most everyone would expect. So it is certainly possible to imagine a PHP interpreter that maintains the state of certain method variables across method invocation and does so "per instance", and that's actually what I also expected to happen the first time I declared a local method variable to be static.
That is what static is, it's the same variable across all instances of the class.
You want to write this so that the variable is a private member of the instance of the class.
class Foo {
private $i = 0;
public function dofoo() {
echo $this->i++ . '<br>';
}
}
The static keyword can be used with variables, or used with class methods and properties. Static variables were introduced in PHP 4 (I think, it might have been earlier). Static class members/methods were introduced in PHP 5.
So, per the manual, a static variable
Another important feature of variable scoping is the static
variable. A static variable exists only in a local function
scope, but it does not lose its value when program execution
leaves this scope.
This is consistant with the behavior you described. If you want a per instance variable, used a regular class member.
Ups 7 years it a long time but anyway here it goes.
All classes have a default constructor why am I saying this?!?
Because if you define a default behaviour in constructor each instance of the class will be affected.
Example:
namespace Statics;
class Foo
{
protected static $_count;
public function Bar()
{
return self::$_count++;
}
public function __construct()
{
self::$_count = 0;
}
}
Resulting in:
require 'Foo.php';
use Statics\Foo;
$bar = new Foo();
echo $bar->bar().'<br>';
echo $bar->bar().'<br>';
echo $bar->bar().'<br>';
$barcode = new Foo();
echo $barcode->bar().'<br>';
echo $barcode->bar().'<br>';
echo $barcode->bar().'<br>';
0
1
2
0
1
2
Every new instance from the upper class will start from 0!
The static count behaviour will NOT be shared across the multiple instances as it will be starting from the value assigned in constructor.
If you need to share data across multiple instances all you need to do is to define a static variable and assign default data outside the constructor!
Example:
namespace Statics;
class Foo
{
//default value
protected static $_count = 0;
public function Bar()
{
return self::$_count++;
}
public function __construct()
{
//do something else
}
}
Resulting in:
require 'Foo.php';
use Statics\Foo;
$bar = new Foo();
echo $bar->bar().'<br>';
echo $bar->bar().'<br>';
echo $bar->bar().'<br>';
$barcode = new Foo();
echo $barcode->bar().'<br>';
echo $barcode->bar().'<br>';
echo $barcode->bar().'<br>';
0
1
2
3
4
5
As you can see the results are completely different, the memory space allocation is the same in between class instances but it can produce different results based on how you define default value.
I hope it helped, not that the above answers are wrong but I felt that it was important to understand the all concept from this angle.
Regards, from Portugal!

Calling Variable Class / Method Programmatically

I have a method in a variable named class that I need to call dynamically, how can I call this:
$foo = "object"
Where object is a specific class
How do I call this in PHP?
$foo::method()
The wording of the question is confusing but from what I understand, if you want to set $foo to a specific class, lets call it Foo you can do this:
$foo = new Foo;
Here is our class Foo
class Foo {
public $aMemberVar = 'aMemberVar Member Variable';
public $aFuncName = 'aMemberFunc';
function aMemberFunc() {
print 'Inside `aMemberFunc()`';
}
}
If you want to access a class variable Foo and set it to a variable you can do this:
$myVar = 'aMemberVar';
print $foo->$myVar //prints "aMemberVar Member Variable"
Also to clarify $foo::method() implies that $foo is a static class, and static classes cannot be instantiated but they can call on its class method method() by using the scope resolution operator (::)
Hope this helps.
$$foo::method();
See PHP variable variables

Categories