why php allow to overwriting private method? - php

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.

Related

Setting a static variable to a function php class

I'd like to set the value of my static variable to a function. But the __construct never runs with static calls. So what's an alternate route I can do to set this variable so I can re-use it many times in my class?
function sayhey(){
return 'hey';
};
// my class i do control
class Class1 {
private static $myvar;
public function __construct(){
self::$myvar = sayhey();
}
public static function func1(){
echo '<pre>'; print_r(self::$myvar); echo '</pre>';
}
}// end class
// how can i make this work if the __construct never runs for static calls?
Class1::func1();
// obviously this works
//$class1 = new Class1();
//$class1->func1();
Try this
<?php
function sayhey(){
return 'hey';
};
// my class i do control
class Class1 {
private static $myvar;
public function __construct(){
self::$myvar = sayhey();
//echo '<pre>11 '; print_r(self::$get_cart_contents); echo '</pre>';
}
public static function func1(){
echo '<pre>';
self::$myvar = self::$myvar ?? sayhey();
print_r ( self::$myvar );
echo '</pre>';
}
}// end class
Class1::func1();
You need at some point to initialise the static property. As the constructor is useless for static methods, this 'replaces' the work done by creating an init() method (also static) which is called when self::$myvar is null (using self::$myvar ?? self::init()...
function sayhey(){
return 'hey';
};
// my class i do control
class Class1 {
private static $myvar;
public static function init(){
self::$myvar = sayhey();
return self::$myvar;
}
public static function func1(){
echo '<pre>'; print_r(self::$myvar ?? self::init()); echo '</pre>';
}
}// end class
// how can i make this work if the __construct never runs for static calls?
Class1::func1();
You can also save the function name in the variable instead of the result of the call.
function sayhey(){
return 'hey';
};
class Class1 {
private static $myvar;
public static function set($fct){
self::$myvar = $fct;
}
public static function func(){
$result = (self::$myvar)();
return $result;
}
}
Class1::set('sayhey');
echo Class1::func(); //hey
I suspect traits are better.
trait myfunctions{
public static function sayhey(){
return 'hey';
}
}
class Class1 {
use myfunctions;
}
class Class2 {
use myfunctions;
public static function fct1(){
return self::sayhey();
}
}
echo Class1::sayhey(); //hey
echo Class2::sayhey(); //hey
echo Class2::fct1(); //hey

PHP Object Oriented Programming Oops Issues

I am trying to implement a code somewhat like below but not able to understand one issue, as per my understanding it should have printed the data like this:
Foo::testPrivate
Foo::testPublic
But its displaying output as ::
Bar::testPrivate
Foo::testPublic
The code is::
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();
Can somebody please explain this?
As per my Understanding
Displaying output is right because of you are created object of "Foo" class and then after call test() function is inside the "Bar" class
In test() function of Bar class is call testPrivate() using "this" keyword so call the function in same class and testPrivate() is also private so that's why display result like :
Bar::testPrivate
Foo::testPublic
Make changes to private function testPrivate() { } to public function testPrivate() in both the class for displayed your accepted result
Result after made this changes is :
Foo::testPrivate
Foo::testPublic

Please help me with this oop code on php.net site

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

Static:: on private members

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

How to get child class name from parent class

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();

Categories