PHP basic OOP question - php

class a
{
public function __construct()
{
$this->id = 123;
}
}
class b extends a
{
public function __construct()
{
echo parent::id;
}
}
How do I pass variables that are set in the first class $this to the second class?

The correct way is to simply use $this->id in your subclass. All public/protected variables are available to subclasses this way. By assigning $this->id without declaring it, you've implicitly made it public. Generally you should explicitly declare the variable in the base class to document your intent to make it public:
class a
{
public $id;
public function __construct()
{
$this->id = 123;
}
}
Just remember to call parent::__construct() before you attempt to access members set by the parent class. Unlike some languages (C++) the parent class's constructor will not be automatically invoked for you.
class b extends a
{
public function __construct()
{
parent::__construct();
echo $this->id;
}
}

You can use parent::__construct() to get things that are initialized in the parent class. If you don't have anything to initialize in the child class you can avoid __construct() in the child class and it will automatically take the parent construct.

Related

Pass arguments to parent class constructor in PHP?

I have 2 classes where parent is inherited by child.
class parentClass
{
private $table_name='';
public function __construct($argument)
{
$this->table_name=$argument;
echo $this->table_name;
}
}
class child extends parentClass
{
private $table="student";
public function __construct()
{
parent::__construct($this->table);
}
}
There is some thing like this below that has to be used but I am unable to understand how and why.
$args = func_get_args();
call_user_func_array(array($this, 'parent::__construct'), $args);
Help me as
What should be the correct code to achieve the correct logic
and please support it with a reference to gain a better understanding.
Not a direct answer, but if I read the code correctly, you don't really want to pass a variable / value to the constructor. Instead you want to pass a fixed class property like a table name.
In that case you could use a constant in the child class and set that in the parent's constructor. The child class would not need a separate constructor if that is all you want to do.
So something like:
class parentClass
{
private $table_name;
function __construct() {
$this->table_name = static::TABLE;
echo $this->table_name;
}
}
class childClass extends parentClass
{
const TABLE = "student";
}
$obj = new childClass();

How do I make a class variable automatically available to its children classes?

I have an Application class and I also have a number of separate classes that extend it. If I set a $variable in the parent Application class, How do I make it automatically available in its children?
class Application {
public $variable;
public function __construct() {
$this->variable = "Something";
}
}
class Child extends Application {
public function doSomthing() {
$mything = $variable." is cool";
return $mything;
}
}
I know I can put global $variable; in my doSomthing() method, but that is super tedious to do over and over in every method I write. Is there a way to do it where it just is available to all my child class methods?
Thanks.
You just set a property named variable in your Application class in __construct method.
If the property visibility permits (e.g. is public or protected), you can access a property potato in any children classes method with $this->potato:
class Application {
public $variable;
public function __construct() {
$this->variable = "Something";
}
}
class Child extends Application {
public function doSomthing() {
$mything = $this->variable." is cool";
return $mything;
}
}

PHP variable initiation in super class

My question is concerning the inheritance mechanisms in object oriented PHP. If I want a class variable to be initialized in a super class in its constructor and all children classes to make use of initialized variable, I can't do this in the constructor of the superclass, since the superclasses constructor is not implicitly called by the children classes constructor, as in Java. If I have to manually call the super classes constructor from every children constructor, I do not have any benefit from simply doing the initialization in every children classes constructor.
How can I solve this problem? Any ideas?
class superclass {
protected $a;
function __construct() {
$this->a = new Foo();
}
}
class childrenclass1 extends superclass {
function __construct() {
do_something;
}
function childrenfunction() {
$this->a->method(); // not initalized;
}
}
Like Java, the superclass constructor is only called automatically when the child classes don't implement their own constructor. Alternatively, the initial property values can be declared as part of the class definition if they're a constant expression.
So, basically, your choices are:
Initialize the variable with a non-dynamic value in the parent class:
protected $var = 123;
Use parent::__construct() in all child classes that implement their own constructor. This is still better than initializing those properties in each child class, because using the parent's constructor doesn't duplicate code.
If the inheritance depth is 2 (i.e. only parent and child) you could drop the child constructor and define an initialization method:
class Parent
{
public function __construct()
{
...
$this->initialize();
}
protected function initialize() {}
}
class Child extends Parent
{
protected final function initialize()
{
...
}
}
The benefit to not doing the initialization in every child class constructor is that the logic of what to initialize it to can be kept in a single place - in the parent constructor. Calling the parent constructor from every child constructor can be tedious, but at least it's not duplicating the logic.
Your other option is to make the variable private, and use a method to access it from the child classes. The method can initialize it if needed, and then return the value.
class superclass {
private $a;
protected function getA() {
if (!($this->a instanceof Foo)) {
$this->a = new Foo();
}
return $this->a;
}
}
class childrenclass1 extends superclass {
public function childrenfunction() {
$this->getA()->method();
}
}
...don't forget to access your variable or method using $this. You can't leave that out in PHP like you can in Java.
It's a good practice to call parent constructor because it can initialize some variables or do other usefull things. But if you don't want to write in any child constructor parent::__construct() you can avoid write child constructor and move everything to a special method init. It will look like as:
class A {
public function __construct() {
do smt
}
}
class B extends A {
public function init() {
do smt
}
}
$b = new B();
$b->init();

Access parent properties in child using $this

I am trying to create a simple MVC my personal use and I could really use an answer to this simple question
class theParent extends grandParent{
protected $hello = "Hello World";
public function __construct() {
parent::__construct();
}
public function route_to($where) {
call_user_func(array("Child", $where), $this);
}
}
class Child extends theParent {
public function __construct() {
parent::__construct();
}
public function index($var) {
echo $this->hello;
}
}
$x = new theParent();
$x->route_to('index');
Now Child::index() this throws a fatal error: Using $this when not in object context but if I were to use echo $var->hello, it works just fine.
I know I can use $var to access all properties in the parent, but I would rather use $this.
By writing call_user_func(array("Child", $where), $this) you are calling the method statically. But as your method isn't static you need some kind of object instance:
call_user_func(array(new Child, $where), $this);
Documentation on callback functions.
You don't have an instance of Child to call a non-static method upon when you're doing $x->route_to('index'); The way you're calling the method, without having made an instance first, is implied static.
There are two ways to correct it. Either make the Child class's methods static:
class Child extends theParent {
public function __construct() {
parent::__construct();
}
static public function index($var) {
echo self::$hello;
}
}
...or make an instance of the child class for the parent to use:
class theParent extends grandParent{
protected $hello = "Hello World";
private $child = false
public function __construct() {
parent::__construct();
}
public function route_to($where) {
if ($this->child == false)
$this->child = new Child();
call_user_func(array($this->child, $where), $this);
}
}
Of course, both of these samples are rather generic and useless, but you see the concept at hand.
$this gives you access to everything visible/accessible in the current object. That can either be in the class itself (this) or any of it's parents public or protected members/functions.
In case the current class overrides something of a parent class, you can access the parent method explicitly using the parent keyword/label, whereas you add :: to it regardless if it is not a static method.
Protected variables exist only once, so you can not use parent to access them.
Is this info of use?

Creating a var from data created by another class

I am having problems creating a variable with data from another class. Here is what I am doing...
<?PHP
class Customers extends Controller {
private $foo = $this->session->userdata('foo');
}
You probably want something more like this:
class Customers extends Controller
{
private $foo;
public function __construct()
{
parent::__construct();
$this->foo = $this->session->userdata('foo');
}
}
It's hard to know for sure without knowing more about your project.
You can set it with constructor because you are inhering from parent class:
class Customers extends Controller {
private $foo = null;
function __construct(){
parent::__construct();
$this->foo = $this->session->userdata('foo');
}
}
This is not possible: $this doesn't exist at the moment when you define the class, and you can't call functions at all at this point at all.
You will need to assign $foo in the constructor, after $this->session has been initialized. (#konforce beat me to the example.)

Categories