In the sample code below, the method test() in parent class Foo is overridden by the method test() in child class Bar. Is it possible to call Foo::test() from Bar::test()?
class Foo
{
$text = "world\n";
protected function test() {
echo $this->text;
}
}// class Foo
class Bar extends Foo
{
public function test() {
echo "Hello, ";
// Cannot use 'parent::test()' because, in this case,
// Foo::test() requires object data from $this
parent::test();
}
}// class Bar extends Foo
$x = new Bar;
$x->test();
Use parent:: before method name, e.g.
parent::test();
See parent
parent::test();
(see Example #3 at http://www.php.net/manual/en/language.oop5.paamayim-nekudotayim.php)
Just set visibility levels at $text property.
private $text = "world\n";
Calling a parent method may be considered bad practice or code smell and may indicate programming logic that can be improved in a way, that the child doesn't have to call the parent. A good generic description is provided by Wikipedia.
An implementation without calling parent would look like:
abstract class Foo
{
$text = "world\n";
public function test() {
$this->test_child();
echo $this->text;
}
abstract protected function test_child();
}// class Foo
class Bar extends Foo
{
protected function test_child() {
echo "Hello, ";
}
}// class Bar extends Foo
$x = new Bar;
$x->test();
Judging by your comments on the pastebin, I'd say you can't.
Maybe if you had something like this?
class foo {
public function foo($instance = null) {
if ($instance) {
// Set state, etc.
}
else {
// Regular object creation
}
}
class foo2 extends foo {
public function test() {
echo "Hello, ";
// New foo instance, using current (foo2) instance in constructor
$x = new foo($this);
// Call test() method from foo
$x->test();
}
}
Related
In the sample code below, the method test() in parent class Foo is overridden by the method test() in child class Bar. Is it possible to call Foo::test() from Bar::test()?
class Foo
{
$text = "world\n";
protected function test() {
echo $this->text;
}
}// class Foo
class Bar extends Foo
{
public function test() {
echo "Hello, ";
// Cannot use 'parent::test()' because, in this case,
// Foo::test() requires object data from $this
parent::test();
}
}// class Bar extends Foo
$x = new Bar;
$x->test();
Use parent:: before method name, e.g.
parent::test();
See parent
parent::test();
(see Example #3 at http://www.php.net/manual/en/language.oop5.paamayim-nekudotayim.php)
Just set visibility levels at $text property.
private $text = "world\n";
Calling a parent method may be considered bad practice or code smell and may indicate programming logic that can be improved in a way, that the child doesn't have to call the parent. A good generic description is provided by Wikipedia.
An implementation without calling parent would look like:
abstract class Foo
{
$text = "world\n";
public function test() {
$this->test_child();
echo $this->text;
}
abstract protected function test_child();
}// class Foo
class Bar extends Foo
{
protected function test_child() {
echo "Hello, ";
}
}// class Bar extends Foo
$x = new Bar;
$x->test();
Judging by your comments on the pastebin, I'd say you can't.
Maybe if you had something like this?
class foo {
public function foo($instance = null) {
if ($instance) {
// Set state, etc.
}
else {
// Regular object creation
}
}
class foo2 extends foo {
public function test() {
echo "Hello, ";
// New foo instance, using current (foo2) instance in constructor
$x = new foo($this);
// Call test() method from foo
$x->test();
}
}
I have large class foo, that I want to split to two separate classes (and files);
My class foo uses contruct function and noumerous $this references.
I need a second class bar to be an extension for original foo class, so I could still use contruction with additional parameter if to include bar class;
$includeBar = true;
$foo = new foo($config, $includeBar);
I've tried putting it this way:
Class bar extends foo {
public function barFunction(){
//some function of bar
}
}
Class foo {
public function __construct($config, $includeBar = true) {
if ($includeBar) {
include_once 'bar.php';
}
}
}
But when I call:
$foo = new foo($config, true);
$foo->barFunction();
It fails, saying
PHP Fatal error: Uncaught Error: Call to undefined method foo::barFunction()
What am I doing wrong? pls help, got stuck
It should be the other way round.
Bar is your base class, that contains all the methods that every sub class also needs. Foo is the extention, the extras, so Foo extends Bar.
<?php
// file bar.php
Class Bar {
public function __construct($config) {
$this->config = $config;
}
public function barFunction() {
echo "I'm everybody ".$this->config['msg'];
}
}
// file foo.php
require_once('bar.php');
Class Foo extends Bar {
public function fooOnly() {
echo "I'm foo ".$this->config['msg'];
}
}
// consuming file index.php
include('foo.php');
$config = array('msg'=>'and I need coffee');
$foo = new foo($config);
$foo->barFunction(); // we can call this, because foo extends bar
// this won't work:
$bar = new Bar($config);
$bar->fooOnly();
// but this:
$bar->barFunction();
$foo->fooOnly();
(all the includes/requires can be omitted when using a proper autoloader!)
If you want reuse class methods or separate class method implementation I think you can use trait and then you can use keyword use to require functions to your class.
For example:
<?php
class Base {
public function sayHello() {
echo 'Hello ';
}
}
trait SayWorld {
public function sayHello() {
parent::sayHello();
echo 'World!';
}
}
class MyHelloWorld extends Base {
use SayWorld;
}
$o = new MyHelloWorld();
$o->sayHello();
?>
The above example will output:
Hello World!
OK - What I'm trying to do is kind of convoluted and I'm not sure if its even possible or if there is another "proper" way to do this but here it is in a nutshell:
class foo {
var $testvar = "foo";
function doTest() {
echo $this->testvar . "\n";
$t = new bar;
$t->updateParent();
echo $this->testvar;
}
}
class bar extends foo {
function updateParent() {
$this->testvar = "bar";
}
}
/*
What I get:
foo
foo
What I want:
foo
bar
*/
The reason I'm doing this is I'm designing a template engine and basically for my purposes the foo class is the main class that has the bulk of my application code. The system is designed so the users can create their own template php files which are loaded by the application within the context of a foo method. I want to set all the properties and methods of foo to private save for certain ones that will be protected and thus accessible to bar. The point being I want the users template php code to have access to only a limited number of functions of the parent class when I include their code.
A better example would be:
class foo {
protected $db;
private $settings;
function SomeAction() {
// some code that results in a template needing to be loaded
// code that determines the template file
$template = new bar;
$template->loadTemplate($file);
}
}
class bar extends foo {
function loadTemplate($file) {
//if file exists
require($file);
// has access $db driver class (without creating a new instance of it)
// does not have access to the $settings property
}
}
Any Ideas?
It seems strange to me that you are extending the foo class just to give access of $db may be some more properties. but this doesn't make sense to me. You should pass the dependency to both classes.
class foo {
protected $db;
private $settings;
function SomeAction(bar $bar) {
// some code that results in a template needing to be loaded
// code that determines the template file
$bar->loadTemplate($file);
}
}
class bar {
function loadTemplate($file, Gateway $db) {
// use $db here
//if file exists
require($file);
}
}
I believe you're looking for parent
Give this a try:
class foo {
var $testvar = "foo";
function doTest() {
echo $this->testvar . "\n";
$t = new bar;
$t->updateParent();
echo $this->testvar;
}
}
class bar extends foo {
function updateParent() {
parent::testvar = "bar";
}
}
/*
What I get:
foo
foo
What I want:
foo
bar
*/
try this
<?php
class foo {
var $testvar = "foo";
function doTest() {
echo $this->testvar . "\n";
$R =$this->updateParent();
echo $R;
}
}
class bar extends foo {
function __construct()
{
parent:: doTest();
}
function updateParent() {
$testvar = "bar";
return $testvar;
}
}
$t = new bar;
Instead of using the literal name of the base class in your code, you should be using the special name parent, which refers to the name of your base class as given in the extends declaration of your class
Every object instance is also an instance of it's parent.
You make all properties private in the parent and offer secured access through public methods. All public methods will be available to child classes as if they were their own, without access to private properties.
class foo {
private $db;
public function dbSelect() {
return $this->db->select();// Example
}
}
class bar extends foo {
public function loadTemplate($file) {
require($file);
$selected = $this->dbSelect();
}
}
I've got a class
class foo {
function do_something() {
load();
}
function load() {
//things
echo 'load from foo';
}
}
And another class that extends foo (a child class):
class bar extends foo {
function load() {
//things
echo 'load from bar (child)';
}
}
And then:
$obj = new bar();
What I want to know is how can I call $obj->do_something() such that the method uses the child 'load' method instead of the method declared in the foo class.
So, I want the output to be:
$obj->do_something();
Output: load from bar (child)
Is this possible with PHP?
Thanks!
You need to qualify the object context with $this. Unlike some other languages, PHP requires that you qualify the instance explicitly with $this for all method calls from within an object.
class foo {
function do_something() {
// load();
$this->load();
}
function load() {
echo 'load from foo';
}
}
class bar extends foo {
function load() {
echo 'load from bar (child)';
}
}
$obj = new bar();
$obj->do_something();
In your code (merely calling load()) the language was looking for a globally defined function named load, which of course wouldn't work (or in worse cases, would but incorrectly)
As another answer points out, you must similarly qualify static methods though the use of self or static (which I would suggest you read up on to understand the binding differences)
From an inheriting class, in an overriding method, you can also use parent to invoke the parent classes' definition of the method:
class bar extends foo {
function load() {
parent::load(); // right here
echo 'load from bar (child)';
}
}
This will invoke the parent's version of the load method, and continue execution with the child classes' definition.
I would recommend use abstract function if you want to have such a tight coupling of methods. it's going to require high maintenance and you are creating some tight couplings between classes.
i would recommend creating an abstract function in the parent that each of the children will implement with it's own logic.
Even then if you want change your parent class function to this
function do_something(){
if(method_exists($this, 'test')){
$this->test();
}
}
you can use abstract class and abstract method:
abstract class Foo{
function test() {
$this->method();
}
abstract function method();
}
class Test extends Foo {
function method() {
echo 'class Test';
}
}
$test = new Test();
$test->test();
Try this
class foo {
function do_something() {
static::load();
}
function load() {
//things
echo 'load from foo';
}
}
class bar extends foo {
function load() {
//things
echo 'load from bar (child)';
}
}
$obj = new bar;
$obj->do_something();
I have the following setup:
<?php
class core {
static $var1;
}
class parent extends core {
function getStatic() {
return parent::$var1;
}
}
class child extends parent {
function getStatic() {
// I want to access core static var, how can i do it?
//return parent::$var1;
}
}
?>
I need to be able to use parent::$var1 but from within class child.. is this possible? Am I missing something?
Just reference it as self... PHP will automatically go up the chain of inheritance until it finds a match
class core {
protected static $var1 = 'foo';
}
class foo extends core {
public static function getStatic() {
return self::$var1;
}
}
class bar extends foo {
public static function getStatic() {
return self::$var1;
}
}
Now, there will be an issue if you don't declare getStatic in bar. Let's take an example:
class foo1 extends core {
protected static $var1 = 'bar';
public static function getStatic() {
return self::$var1;
}
}
class bar1 extends foo1 {
protected static $var1 = 'baz';
}
Now, you'd expect foo1::getStatic() to return bar (and it will). But what will Bar1::getStatic() return? It'll return bar as well. This is called late static binding. If you want it to return baz, you need to use static::$var1 instead of self::$var1 (PHP 5.3+ only)...
core::$var1 seems best for your needs...
The biggest problem here is that you're using the keyword parent as a class name. This makes it completely ambiguous whether your calls to parent::$var1 are intended to point to that class, or to the parent of the calling class.
I believe, if you clean this up, you can achieve what you want. This code prints 'something', for example.
class core {
static $var1 = 'something';
}
class foo extends core {
function getStatic() {
return parent::$var1;
}
}
class bar extends foo {
function getStatic() {
// I want to access core static var, how can i do it?
return parent::$var1;
}
}
$b = new bar ();
echo $b->getStatic ();
It also works if you use core:: instead of parent::. Those two will behave differently, though, if you declare a static $var1 inside of the foo class as well. As is it's a single, inherited variable.