Is there any meaning to it?
public static function a(){
static::_b();
}
private static function _b(){
}
static here is same as self in any situation, because you cannot override a private function in the child class, right?
As Germann Arlington said in the comment. A subclass can have it's own implementation of _b() - even with a different visibility.
<?php
class Foo {
public static function a() { static::_b(); }
private static function _b() { echo 'Foo'; }
}
class FooEx extends Foo {
public static function _b() { echo 'FooEx'; }
}
FooEx::a();
prints FooEx
Related
In the documentation is this example and understand it without problems
class Bar{
public function test() {
$this->testPrivate();
$this->testPublic();
}
public function testPublic() {
echo "Bar::testPublic\n";
}
private function testPrivate() {
echo "Bar::testPrivate\n";
}
}
class Foo extends Bar{
public function testPublic() {
echo "Foo::testPublic\n";
}
private function testPrivate() {
echo "Foo::testPrivate\n";
}
}
$myFoo = new foo();
$myFoo->test();
The result is:
Bar::testPrivate
Foo::testPublic
But now redefine the test () method in the class foo
class Bar{
public function test() {
echo '<br>Im Bar::test';
$this->testPrivate();
$this->testPublic();
}
public function testPublic() {
echo "<br>Bar::testPublic\n";
}
private function testPrivate() {
echo "<br>Bar::testPrivate\n";
}
}
class Foo extends Bar{
public function test() {
echo '<br>Im Foo::test';
$this->testPrivate();
$this->testPublic();
}
public function testPublic() {
echo "<br>Foo::testPublic\n";
}
private function testPrivate() {
echo "<br>Foo::testPrivate\n";
}
}
$myFoo = new Foo();
$myFoo->test();
The result is:
Im Foo::test
Foo::testPrivate
Foo::testPublic
php allows me to override the private method testPrivate (), Why?
Why not? It's difficult to answer that question as it's just how PHP works. If you want to prohibit your methods from being overwritten then you can use the final keyword.
Additionally, in your example, if you do not declare the private method within Foo, you will get an error as Foo technically has no definition for that method. Extending classes have no visibility of any private properties or methods within their parent class.
I didn't get why the first output of the code prints "Bar::testPrivate" as we are calling the test method of the parent class using sub class's instance.So, when calling the first line of code inside the test function which is "$this->testPrivate();" should call testPrivate method of the sub class hence printing "Foo::testPrivate" and not "Bar::testPrivate".
<pre>
class Bar
{
public function test() {
$this->testPrivate();
$this->testPublic();
}
public function testPublic() {
echo "Bar::testPublic\n";
}
private function testPrivate() {
echo "Bar::testPrivate\n";
}
}
class Foo extends Bar
{
public function testPublic() {
echo "Foo::testPublic\n";
}
private function testPrivate() {
echo "Foo::testPrivate\n";
}
}
$myFoo = new foo();
$myFoo->test(); // Bar::testPrivate
// Foo::testPublic
</pre>
Your class Foo doesn't have a test() method. You can call $myFoo->test() because the method test() is inherited from class Bar. You'll have to override the method test() within class Foo just as you did with methods testPrivate() and testPublic().
You are correct that it is calling the method of the base class, but in this case Bar is your base class. Check out the example here.
If you are looking to inherit all the functions from your base (parent) class then you should explicitly call it's constructor in the child class. Otherwise you will need to override those methods. Also, when using the actual instance (i.e. you created an object) functions declared private are only available to that class. Use protected for classes that will inherit that function. e.g.:
class Foo {
public function __construct() {
echo "Foo constructed...\n";
$this->fooOnly();
}
private function fooOnly() {
echo "Called 'fooOnly()'\n"; //Only available to class Foo
}
protected function useThisFoo() {
echo "Called 'useThisFoo()'\n"; //Available to Foo and anything that extends it.
}
}
class Bar extends Foo {
public function __construct() {
parent::__construct(); //Now Bar has everything from Foo
}
public function testFooBar() {
//$this->fooOnly(); //Fail - private function
$this->useThisFoo(); //Will work - protected function is available to Foo and Bar
}
}
$bar = new Bar();
$bar->testFooBar(); //Works - public function will internally call protected function.
//$bar->fooOnly(); //Fail - private function can't be accessed in global space
//$bar->useThisFoo(); //Fail again - protected function can't be access in global space
I'm trying to accomplish this without requiring a function on the child class... is this possible? I have a feeling it's not, but I really want to be sure...
<?php
class A {
public static function who() {
echo __CLASS__;
}
public static function test() {
static::who(); // Here comes Late Static Bindings
}
}
class B extends A {
public static function who() {
echo __CLASS__;
}
}
B::test(); //returns B
?>
Use get_called_class() instead of __CLASS__. You'll also be able to replace static with self as the function will resolve the class through late binding for you:
class A {
public static function who() {
echo get_called_class();
}
public static function test() {
self::who();
}
}
class B extends A {}
B::test();
From php manual:
[...] Static method calls are resolved at compile time.
When using an explicit class name the method is already identified completely and no
inheritance rules apply. If the call is done by self then self is translated to
the current class, that is the class the code belongs to.
Here also no inheritance rules apply [...]
..so im looking for a way to emulate the standard oop inheritance with static singleton.
Code explain better:
// Normal inheritance: my goal.
class Foo{
public function test(){
echo "Foo->test()\n";
}
}
class Bar extends Foo{
public function other_test()
{
echo "Bar->other_test()\n";
}
}
$obj = new Bar();
echo get_class($obj) . "\n";
$obj->test();
$obj->other_test();
/*
Output:
Bar
Foo->test()
Bar->other_test()
*/
// How i would love to do:
class Foo2{
public static function test2()
{
echo "Foo2::test2()\n";
}
// Singleton?
public static $_instance;
public static function get_instance()
{
if(is_null(self::$_instance))
{
self::$_instance = new self();
}
return self::$_instance;
}
}
class Bar2 extends Foo2{
public static function other_test2()
{
echo "Bar2::other_test2()\n";
}
}
$obj2 = Bar2::get_instance();
echo get_class($obj2) . "\n";
$obj2::test2();
$obj2::other_test2();
/*
Output:
Foo2
Foo2::test2()
Fatal error: Call to undefined method Foo2::other_test2()
*/
echo "\n-------\n";
// How im doing actually:
interface Foo3{
public static function get_instance();
}
class Bar3 implements Foo3{
// Singleton?
public static $_instance;
public static function get_instance()
{
if(is_null(self::$_instance))
{
self::$_instance = new self();
}
return self::$_instance;
}
public static function test3()
{
echo "Bar3::test3()\n";
}
public static function other_test3()
{
echo "Bar3::other_test3()\n";
}
}
$obj3 = Bar3::get_instance();
echo get_class($obj3) . "\n";
$obj3::test3();
$obj3::other_test3();
/*
Output:
Bar3
Foo3::test3()
Bar3::other_test3()
*/
The last 'way' force me to avoid the get_instance and static variables to be placed in the parent class, so I do not consider it as a best solution.. if for some reason my get_instance() function will change in the future, i dont want to edit all classes (inheritance! inheritance! we all want inheritance!)
So, is there a way or a best practices to solve this problem?
p.s: php5.3.2
The Singleton pattern in PHP is something like this:
class Singleton {
private static $instance = null;
// Constructor is private, so class cannot be instantiazed from outside
private function __construct() {
}
public static function getInstance() {
if (static::$instance === null) {
static::$instance = new Singleton();
}
return static::$instance;
}
public static function test() {
echo 'Singleton::test()';
}
public function __sleep() {
throw new Exception('Serialization is not alowed.');
}
public function __wakeup() {
throw new Exception('Serialization is not alowed.');
}
public function __clone() {
throw new Exception('Cloning is not alowed.');
}
}
For you is important that keyword static, then this:
class B extends Singleton {
public static function test2() {
echo 'B::test2()';
}
}
$b = B::getInstance();
B::test();
B::test2();
// Singleton::test()
// B::test()
Is this you looking for?
If i extend a static class in PHP, and the parent class refers to "self::", will this refer to the self in the extended class?
So, for example
<?php
Class A
{
static $var
public static function guess(){self::$var = rand(); return $var}
}
Class B extends Class A
{
public static function getVar(){return self::$var}
}
If I ran
B::guess();
then B::getVar();
is the value for Var stored in A::$var or B::$var?
Thank you.
Late static binding was introduced in PHP 5.3, it allows you to control this behavior.
It's easy to test:
class ClassA {
public static function test(){ self::getVar(); }
public static function getVar(){ echo 'A'; }
}
class ClassB extends ClassA {
public static function getVar(){ echo 'B'; }
}
ClassA::test(); // prints 'A'
ClassB::test(); // also prints 'A'
... hope that helps :)
Additional information, usage of self or $this is different into extended classes
class ClassA {
public function test(){ self::getVar(); }
public function test2(){ $this->getVar(); }
public function getVar(){ echo 'A'; }
}
class ClassB extends ClassA {
public function getVar(){ echo 'B'; }
}
$classB = new ClassB();
$classB->test(); // prints 'A'
$classB->test2(); // prints 'B'