How do I can access base class variables in another classes wich are loaded into base class?
Base class example
class base {
public $get;
public function __get( $name ) {
require_once $name . '.php';
$this->name = new $name( $this );
return $this->name;
}
public function __construct( $varfromphplib ) {
$this->varfromphplib = $varfromphplib;
$this->get = explode( "/", $_SERVER['REQUEST_URI'] );
}
}
$class = new base( $varfromphplib );
another class example (loaded into base class with __get)
class another {
public function showGet() {
//there I wanna return base class $this->get;
}
public function getLibClass(){
//there I wanna return $varfromphplib variable with baseclass prefix or not if can
}
}
//usage in base class
$this->another->showGet( );
I don't know how to be able to acces base class variables like $get in "another" class
Hope someone will be able to help me with this.
If one class is inherited from the other (A extends B) you can call variables from the parent class by using $this->variable. Note that this only works if the inheriting class doesn't have an own constructor and doesn't have a variable by the same name.
If any of that keeps you from using $this, you can always call the parent classes variables just like you would call any public variables from unrelated classes.
i.e.: A has protected variable $a and B extends A but has an own variable named $b.
$objA = new A();
echo "A->a = ".$objA->a;
Related
class A {
public function f(){
$this->ar[0] = 'something';
}
}
For example, how can function f be called such that $this->ar will refer to an array declared outside of class A? Assume that A is not inheriting ar.
Edit:
I tried to simplify the question. The actual code I'm looking at is
the function index in opencart's ControllerStartupStartup class
The function index is using $this to access class instances that aren't defined in that class: $this->db,$this->config, and $this->tax.
They are not declared in the parent class Controller either.
The function is being called with call_user_func_array(array($controller, $this->method), $args); in the Action class.
Maybe you can make "ar" known and provide it in the class as setter, so the instance ar is known and you can address it with $this
class A {
$ar = array();
public function f(){
$this->ar[0] = 'something';
}
}
// INSTANCE with Setter
$ar[0]='whatever';
$class = new A();
$class->ar = &$ar;
$class->f();
echo $ar[0];
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();
I have 4 classes, 1 of them is the main class that holds all the general objects.
3 others are situation classes (for the lack of a better word, as they are included in different parts of the script as needed)
I would like to access all three classes' methods and objects from the main class (or at least just the methods) AND access the main class' methods and variables from the other three classes, AND share the access between all the classes, so that I can call any method of any class from any class.
I know I can make the other three classes members of the main class like this:
class Main
{
public $test = 'test';
public function __construct ($classA, $classB, $classC)
{
$this -> classA = $classA;
$this -> classB = $classB;
$this -> classC = $classC;
echo 'Main just got constructed!';
}
public function test()
{
echo $this -> test;
}
}
class A extends Main
{
public function TestA()
{
echo 'In Class A';
}
}
class B extends Main
{
public function __construct()
{
echo 'B just got constructed!';
}
public function TestB()
{
echo 'In Class B';
}
}
class C extends Main
{
public function TestC()
{
echo 'In Class C';
// can we access B from here? probably not.
// would B::TestB() work?
B::TestB();
// yes it does.
// but is there any other way of accessing the method? like $this -> TestB()? apart from extending the B class to C.
// Is there any downside to using this way of accessing methods and variables? what are the cons?
}
}
$A = new A;
$B = new B;
$C = new C;
$Main = new Main ($A, $B, $C);
$C -> TestC();
$Main -> classC -> TestC();
The first issue with this is, extending the Main class to other classes throws warnings because of the missing arguments for __construct() in the Main class:
Warning: Missing argument 1 for Main::__construct()
The other concern is that if I use this method, then all three classes have to be initiated before the Main Class. But My script requires the main class to be executed at the very start as it establishes connections to mysql and sets environment variables etc. Plus it is not necessary that all three classes will be used at the same time, so in some part of the websites, only one class is required and it is pointless to initiate the other classes in those parts. (I have more than 4 classes, this is just to make things simpler). In that case, how do I make the other classes members of Main after it has been initiated?
Another thing, extending Main class thrice in other classes seems to initiate Main class thrice in separately.. which is resetting the main class' objects and they are not the same when accessed with other classes. I found out about that issue when the test code threw "Main just got constructed!" thrice and it was setting the variables to their default values. How to avoid that? I would like the Main class' variables to have same values across all the other classes.. kind of like global variables.
Well, as you have objects "injected" later or before Main instance is created, maybe you want add um method register in Main class. Also, as long as each class must have access to onother (such as linking) you could add an attribute (maybe $main) with instance of Main class.
I think it could be useful:
<?php
class A
{
/**
* #var Main
*/
public $main; # Main class
public function test()
{
#$this->main->aInstance->someMethod();
#$this->main->bInstance->someMethod();
// ...
return __METHOD__;
}
}
class B
{
/**
* #var Main
*/
public $main;
public function test()
{
return __METHOD__;
}
}
class Main
{
public $objectPool = array();
public function __construct(array $objects = array())
{
foreach ($objects as $object) {
$object->main = $this;
# add...
$this->addObject($object);
}
}
public function addObject($object)
{
$this->objectPool[ get_class($object) ] = $object;
}
public function getObject($classname)
{
if (array_key_exists($classname, $this->objectPool)) {
return $this->objectPool[$classname];
}
return null; # Or raise an Excetion?
}
public function test()
{
return get_class($this);
}
}
$obj = array(new A, new B);
$main = new Main($obj);
var_dump($main->getObject('B')->main->test());
var_dump($main->getObject('B')->test());
var_dump($obj[1]->main->getObject('A')->test());
However, I think these objects know much about each (which is not a good idea - bad design, actually).
Here goes the runnable code: http://3v4l.org/Y19Kr
Still trying to figure out oop in PHP5. The question is, how to access a parent's static variable from an extended class' method. Example below.
<?php
error_reporting(E_ALL);
class config {
public static $base_url = 'http://example.moo';
}
class dostuff extends config {
public static function get_url(){
echo $base_url;
}
}
dostuff::get_url();
?>
I thought this would work from experience in other languages.
It's completely irrelevant that the property is declared in the parent, you access it the way you access any static property:
self::$base_url
or
static::$base_url // for late static binding
Yes, it's possible, but actually should be written like this:
class dostuff extends config {
public static function get_url(){
echo parent::$base_url;
}
}
But in this case you can access it both with self::$base_url and static::$base_url - as you don't redeclare this property in the extending class. Have you done it so, there would have been a distinction:
self::$base_url would always refer to the property in the same class that line's written,
static::$base_url to the property of the class the object belongs to (so called 'late static binding').
Consider this example:
class config {
public static $base_url = 'http://config.example.com';
public function get_self_url() {
return self::$base_url;
}
public function get_static_url() {
return static::$base_url;
}
}
class dostuff extends config {
public static $base_url = 'http://dostuff.example.com';
}
$a = new config();
echo $a->get_self_url(), PHP_EOL;
echo $a->get_static_url(), PHP_EOL; // both config.example.com
$b = new dostuff();
echo $b->get_self_url(), PHP_EOL; // config.example.com
echo $b->get_static_url(), PHP_EOL; // dostuff.example.com
$model = new static($variable);
All these are within a method inside a class, I am trying to technically understand what this piece of code does. I ran around in the Google world. But can't find anything that leads me to an answer. Is this just another way of saying.
$model = new static $variable;
Also what about this
$model = new static;
Does this mean I'm initializing a variable and settings it's value to null but I am just persisting the variable not to lose the value after running the method?
static in this case means the current object scope. It is used in late static binding.
Normally this is going to be the same as using self. The place it differs is when you have a object heirarchy where the reference to the scope is defined on a parent but is being called on the child. self in that case would reference the parents scope whereas static would reference the child's
class A{
function selfFactory(){
return new self();
}
function staticFactory(){
return new static();
}
}
class B extends A{
}
$b = new B();
$a1 = $b->selfFactory(); // a1 is an instance of A
$a2 = $b->staticFactory(); // a2 is an instance of B
It's easiest to think about self as being the defining scope and static being the current object scope.
self is simply a "shortcut name" for the class it occurs in. static is its newer late static binding cousin, which always refers to the current class. I.e. when extending a class, static can also refer to the child class if called from the child context.
new static just means make new instance of the current class and is simply the more dynamic cousin of new self.
And yeah, static == more dynamic is weird.
You have to put it in the context of a class where static is a reference to the class it is called in. We can optionally pass $variable as a parameter to the __construct function of the instance you are creating.
Like so:
class myClass {
private $variable1;
public function __construct($variable2) {
$this->variable1 = $variable2;
}
public static function instantiator() {
$variable3 = 'some parameter';
$model = new static($variable3); // <-this where it happens.
return $model;
}
}
Here static refers to myClass and we pass the variable 'some parameter' as a parameter to the __construct function.
You can use new static() to instantiate a group of class objects from within the class, and have it work with extensions to the class as well.
class myClass {
$some_value = 'foo';
public function __construct($id) {
if($this->validId($id)) {
$this->load($id);
}
}
protected function validId($id) {
// check if id is valid.
return true; // or false, depending
}
protected function load($id) {
// do a db query and populate the object's properties
}
public static function getBy($property, $value) {
// 1st check to see if $property is a valid property
// if yes, then query the db for all objects that match
$matching_objects = array();
foreach($matching as $id) {
$matching_objects[] = new static($id); // calls the constructor from the class it is called from, which is useful for inheritance.
}
return $matching_objects;
}
}
myChildClass extends myClass {
$some_value = 'bar'; //
}
$child_collection = myChildClass::getBy('color','red'); // gets all red ones
$child_object = $child_collection[0];
print_r($child_object); // you'll see it's an object of myChildClass
The keyword new is used to make an object of already defined class
$model = new static($variable);
so here there is an object of model created which is an instance of class static