I try to call getTest() function inside Child class.
First I initialize instance of Ext class so I assume main property $ext should now contain it. But Child class does not inherit it and obtained error message is:
Call to a member function getTest() on a non-object
Where is the issue?
<?php
$A = new Main;
class Main
{
protected $ext = null;
function __construct()
{
$this->ext= new Ext();
new Child;
}
}
class Child extends Main
{
function __construct()
{
echo $this->ext->getTest();
}
}
class Ext extends Main
{
public function getTest()
{
return "cool";
}
}
?>
I know that to solve it other way I can use:
class Child
{
private $Main;
function __construct( &$Main ) { ... }
}
but I would like to understand why that does not work..
At the moment on construct the object the atribute don't have a value yet.
You need call to the parent constructor before use the attribute
function __construct()
{
parent::__construct();
echo $this->ext->getTest();
}
Related
I'm learning PHP and I'm stuck i the following code:
<?php
class dogtag {
protected $Words;
}
class dog {
protected $Name;
protected $DogTag;
protected function bark() {
print "Woof!\n";
}
}
class poodle extends dog {
public function bark() {
print "Yip!\n";
}
}
$poppy = new poodle;
$poppy->Name = "Poppy";
$poppy->DogTag = new dogtag;
$poppy->DogTag->Words = "My name is
Poppy. If you find me, please call 555-1234";
var_dump($poppy);
?>
This is what I got:
PHP Fatal error: Uncaught Error: Cannot access protected property poodle::$Name
This looks strange to me as I should access protected vars and functions from child classes.
Could please someone explain where I'm wrong?
Many thanks.
Protected variables can indeed be accessed from the child class. However you aren't accessing your variable from inside the child class.
If you make the variables public you can access them from outside the class.
Documentation: http://php.net/manual/en/language.oop5.visibility.php
Example:
Class Dog {
private $privateProperty = "private"; //I can only be access from inside the Dog class
protected $protectedProperty = "protected"; //I can be accessed from inside the dog class and all child classes
public $publicProperty = "public"; //I can be accessed from everywhere.
}
Class Poodle extends Dog {
public function getProtectedProperty(){
return $this->protectedProperty; //This is ok because it's inside the Poodle (child class);
}
}
$poodle = new Poodle;
echo $poodle->publicProperty; //This is ok because it's public
echo $poodle->getProtectedProperty(); //This is ok because it calls a public method.
You can't access the property 'Words', you need to make it public
you could add magic methods to your class - that would allow you to access and manipulate the private properties from outside the class.
class foo{
private $bah;
public function __construct(){
$this->bah='hello world';
}
public function __get( $name ){
return $this->$name;
}
public function __set( $name,$value ){
$this->$name=$value;
}
public function __isset( $name ){
return isset( $this->$name );
}
public function __unset( $name ){
unset( $this->$name );
}
}
$foo=new foo;
echo $foo->bah;
$foo->bah='banana';
echo $foo->bah;
Suppose that I've this class:
class Loader
{
function library($name)
{
require $name . '.php';
}
}
and now I include the class foo ($name) inside my controller, like this:
class Controller
{
function __construct()
{
$this->load = new Loader();
}
}
class Child_Controller extends Controller
{
function __construct()
{
parent::__construct();
$this->load->library('foo');
init();
}
}
is possible, for example, access to the included class inside $this? Like:
class Child_Controller extends Controller
{
//..construct above..
function init()
{
$this->print('some text');
}
}
where print is a method of foo, the class included:
class Foo
{
function print($message)
{
echo "your message: " . $message;
}
}
So, summing, I want include in the child controller, in $this, all the method of the included class by the Loader class extended by the base controller. Is this possible?
Or another idea would be create dynamically in the Child_Controller, a property that take the name of the included class, so, for call the method of foo I can do something like:
$this->Foo->print('some text');
No, you can't do that however you can do something similar in storing Foo in a generic property like this:
class Child_Controller
{
private $lib;
function __construct()
{
parent::__construct();
$this->lib = $this->load->library('Foo');
$this->init();
}
function init()
{
$this->lib->print('Hello World!');
}
}
If you want to instantiate multiple libraries then rather than using a dynamic name for the variable you should use an array with the library name as the key, like this:
class Child_Controller
{
private $libs = [];
function __construct()
{
parent::__construct();
$this->libs['Foo'] = $this->load->library('Foo');
$this->init();
}
function init()
{
$this->libs['Foo']->print('Hello World!');
}
}
If you can't use an array and absolutely must use a variable name you can do that like this:
class Child_Controller
{
function __construct()
{
$var = 'Foo';
$this->{$var} = $this->load->library($var);
$this->init();
}
function init()
{
$this->Foo('Hello World!');
}
}
There are already many threads about this kind of problem, but for some reason i can't get it to work.
In TestClass::test(), $db is NULL.
The $db value is set in App construct and I'm trying to recover that value from an extended class function. (so i don't need to set $db everytime everywhere).
Some help would be greatly appreciated, thanks.
File : index.php
<?php
include('classes/App.class.php');
$oApp = new App();
echo TestClass::test();
?>
File : App.class.php
<?php
class App {
protected $db;
public function __construct () {
include_once("CAutoLoader.class.php");
$oCAutoLoader = new CAutoLoader();
$this->db = "someValue";
}
}
?>
File : TestClass.class.php
<?php
class TestClass extends App
{
function __construct () {
}
public static function test () {
return $db;
}
}
?>
File : CAutoLoader.class.php
<?php
class CAutoLoader {
CONST CLASS_EXTENSION = '.class.php';
public function __construct () {
spl_autoload_register(array($this, 'loader'));
}
private function loader ($className) {
include $className . self::CLASS_EXTENSION;
}
}
?>
You forgot a this in your TestClass and a static method cannot access non-static properties. Remove the static keyword and return the right value.
public function test() {
return $this->db;
}
Edit:
If you meant to retrieve the instance of the db via a static method you must declare the variable as static.
class App {
protected static $db = 'hey';
...
}
class TestCase extends App {
public static function test() {
return parent::$db;
}
}
echo TestCase::test(); // returns hey
I wanna call a Child Method in Main Class without declare new child();
class main {
function __construct() {
}
public function test() {
}
}
class child extends main {
function __construct() {
}
function childmethod() {
return "test";
}
}
$main = new main();
$main->childmethod();
best wishes
Make class as abstract and declare the method you want to call from child class as abstract.
abstract class main {
function __construct() {
}
public function test() {
return "test";
}
abstract function childmethod();
}
class child extends main {
function __construct() {
}
function childmethod() {
return "childmethod";
}
}
$main = new child();
echo $main->childmethod();// echoes childmethod
echo $main->test();// echoes test
If I correctly understand what you're asking for, you cannot do it and it's a mistake in the project idea.
If you need to call a child method in the parent, it means the method should go in the parent.
There's no way to call a method of an object without instantiate the object, unless you create a static method
I need to access a property of a parent inside a function of the child class. A static variable can accessed with parent:: but how can I access a non-static parent variable when the child class has a variable with the same name?
class My_parent{
$name = "Praeep";
}
class My_child extends My_parent {
$name ="Nadeesha";
function show_name() {
// need to access $name of the parent just referring the parent variable
}
}
You can either declare the variable in the parent class with a protected modifier or provide a getter. The getter approach would be prefered to ensure encapsulation.
class My_parent{
private $name = "Praeep";
public function getName() {
return $this->name;
}
}
class My_child extends My_parent {
public function show_name() {
echo $this->getName();
}
}
If you also want the property to be mutable consider providing a setter as well.
Add a construct function to your parent class and define your variable inside this function.
class My_parent{
public $name;
public function __construct(){
$this->name= "Praeep";
}
}
If your child class has a construct function too, you need to invoke the parents construct function manually. However a class doesn't have to have a construct function so I commented it out for simplicity.
class My_child extends My_parent {
// public function __construct(){
// parent::__construct();
// }
public function show_name(){
echo $this->name;
}
}
$c=new My_child();
$c->show_name();
EDIT:
well in fact you don't need the construct function in the parent class.
class My_parent{
public $name= "Praeep";
}
class My_child extends My_parent {
public function show_name(){
echo $this->name;
}
}
$c=new My_child();
$c->show_name();