How i can run method $this->ob->getVar() inside class B function C here ? I get no. Did i must transfer string to constructor ?
<?php
class A{
public $tabb = array('1'=>'one', '2'=>'two');
public $index;
public function setVar($v){
$this->index = $v;
}
public function getVar(){
return $this->index;
}
public function arr(){
return $this->tabb;
}
}
class B{
public $tab;
public function __construct($var){
$this->ob=new A;
$this->tab = $var;
}
public function C(){
return $this->D($this->tab, $this->ob->getVar());
}
public function D($l, $j){
if(is_array($l) && isset($j)){
print 'yes';
} else {
print 'no';
}
}
}
$obb = new A;
$obb->setVar('onetwo');
$k = $obb->arr();
$obbb = new B($k);
$obbb->C();
?>
First, for the sake of convention your B class should declare a private variable of $obj, but that is not necessary in PHP.
Second, your B class is just creating a new instance of A in its constructor. So you have two different A classes. The once inside B never has its index property populated.
If you wanted to have the A object created outside the B object you'll have to pass it in like this:
$obbb = new B($k, $obb);
So now your new B constructor is something like this:
public function __construct($var, $someObject){
if (!empty($someObject)) {
$this->ob = $someObject;
}
else {
$this->ob=new A;
}
$this->tab = $var;
}
Related
abstract class X
{
private $v;
protected function setV($v)
{
$this->v = $v;
}
public function getV()
{
return $v;
}
}
class A extends X
{
public function doIt()
{
parent::setV(1);
}
}
class B extends X
{
public function doIt()
{
parent::setV(2);
}
}
$a = new A();
$a->doIt();
$b = new A();
$b->doIt();
but if I want to use getV(), I can both call
$a->getV() and $b->getV()
which sounds silly. Which one to use? To be honest, I would like to see something like that:
X::getV();
which is not possible, an instance must be exists/
It depends on "what do you want". Firstable, it's possible to use X::getV() method, but you need to make v member and getV method static, as shown below.
<?php
abstract class X
{
private static $v;
protected static function setV($v)
{
self::$v = $v;
}
public static function getV()
{
return self::$v;
}
}
class A extends X
{
public function doIt()
{
self::setV(2);
}
}
class B extends X
{
public function doIt()
{
self::setV(1);
}
}
$a = new A();
$a->doIt();
echo X::getV();
// prints 2
// but be aware, that ANY instance of X children class will change the same X::$v value
$b = new B();
$b->doIt();
echo X::getV();
// prints 1
Static members (like X::$v) are stored only once, they are "binded" to the class, not to the instance of this class.
<?php
class Foo
{
public static $v = 5;
}
$instance1 = new Foo();
$instance2 = new Foo();
echo Foo::$v;
echo $instance1::$v;
echo $instance2::$v;
// prints 5, 5, 5
$instance1::$v = 10;
echo Foo::$v;
echo $instance1::$v;
echo $instance2::$v;
// prints 10, 10, 10
In PHP (Symfony 3);
I want to reference an existing object A in another object B which class extends the one of object A, like this:
class A {
private $property1;
private $property2;
public function __construct($p1,$p2){
$this->property1 = $p1;
$this->property2 = $p2;
}
}
class B extends A {
private $property3;
public function __construct($objectA,$p3){
$this = $objectA;
$this->property3 = $p3;
}
}
$a = new A('p1','p2');
$b = new B($a,'p3');
This does not work and throw the following error at the statement $this = $objectA:
Compile Error: Cannot re-assign $this
Which are documented and explain there and there. I am looking for a workaround.
You must call parent constructor and also make property1 and property2 visible in class B
<?php
class A {
private $property1;
private $property2;
public function __construct($p1,$p2){
$this->property1 = $p1;
$this->property2 = $p2;
}
public function getProperty1()
{
return $this->property1;
}
public function getProperty2()
{
return $this->property2;
}
}
class B extends A {
private $property3;
public function __construct($objectA,$p3){
parent::__construct($objectA->getProperty1(), $objectA->getProperty2());
$this->property3 = $p3;
}
}
$a = new A('p1','p2');
$b = new B($a,'p3');
See it live here: http://sandbox.onlinephpfunctions.com/code/705bf1827da2bdf10f8d961ee1cb6fbdd88bc663
As an alternative, you could use __call magic method to forward all cals to class A:
<?php
class A {
private $property1;
private $property2;
public function __construct($p1,$p2){
$this->property1 = $p1;
$this->property2 = $p2;
}
}
class B extends A {
private $property3;
private $a;
public function __construct($objectA,$p3){
$this->a = $objectA;
$this->property3 = $p3;
}
public function __call($name, $arguments)
{
return call_user_func_array(array($this->a, $name), $arguments);
}
}
$a = new A('p1','p2');
$b = new B($a,'p3');
Based on how to clone object to child class in php
Using get_object_vars on the parent object, you can get an array of properties keys and values. You can then loop through them and assign them to the child object:
<?php
class A {
protected $property1;
protected $property2;
public function __construct($p1,$p2){
$this->property1 = $p1;
$this->property2 = $p2;
}
}
class B extends A {
private $property3;
public function __construct($objectA,$p3){
//$this = $objectA;
$objValues = get_object_vars($objectA); // return array of object values
foreach($objValues AS $key=>$value)
{
$this->$key = $value;
}
$this->property3 = $p3;
echo $this->property1;
}
}
$a = new A('p1','p2');
$b = new B($a,'p3');
This does not work with private properties, they need to be at least of protected level.
I ended up managing it like that:
class B extends A{
public function __construct($objectA){
foreach($this as $k => $v){
if(isset($objectA->{$k})){
$this->{$k} = &$objectA->{$k};
}
}
}
}
Compare to #Antony answer, notice it has & in front of $objectA->{$k}: $this->{$k} = &$objectA->{$k};. As I understood it, with &, any change on $objectB of properties belonging to the extended class A applies to $objectA.
I am aware it is not perfect and quite hacky but it does the job I need. Thanks for the input given by everybody.
I have 3 classes:
Class A - Parent Class
Class B - Child Class
Class C - Class to be used in Class A
I want to use functions from class C using variables from my Child class.
<?php
class A
{
public function __construct()
{
$this->load();
}
public function load()
{
$class = new C();
$class->test = $this->test;
$this->c = $class;
}
}
class B extends A
{
public function __construct()
{
parent::__construct();
}
}
class C
{
public function display()
{
echo $this->test;
}
}
$b = new B();
$b->test = 1;
$b->c->display();
Your problem is here:
$class->test = $this->test;
You are attempting to use a property that is not yet defined, because when you do this:
$b->test = 1;
the constructor has already been called, and there's nothing in your classes to update C with the value of B's test property.
You can solve this in a couple of different ways.
1) Send the value in B's constructor, and pass it down the entire chain:
class A
{
public function __construct($test)
{
$this->load($test);
}
public function load($test)
{
$class = new C();
$class->test = $test;
$this->c = $class;
}
}
class B extends A
{
public function __construct($test)
{
parent::__construct($test);
}
}
class C
{
public function display()
{
echo $this->test;
}
}
$b = new B(123);
$b->c->display();
2) Add a method to B that will update C's property:
<?php
class A
{
public function __construct()
{
$this->load();
}
public function load()
{
$class = new C();
$this->c = $class;
}
}
class B extends A
{
public function __construct()
{
parent::__construct();
}
public function setTest($test)
{
$this->c->test = $test;
}
}
class C
{
public function display()
{
echo $this->test;
}
}
$b = new B();
$b->setTest(123);
$b->c->display();
Or perhaps a combination of both.
I'm not sure with my approach. A have two classes and call functions of first class in second class like this:
class A {
public function aClassFunction() {...}
}
class B {
private $aClass;
public function __construct() {
$this->aClass = new A();
}
public function bClassFunction() {
$test = $this->aClass->aClassFunction();
}
}
It just works, but looks "suspiciously".
You can use dependency injection in B class. That approach helps you mocking classes in test.
class B {
private $aClass;
public function __construct(A $a) {
$this->aClass = $a;
}
public function bClassFunction() {
$test = $this->aClass->aClassFunction();
}
}
$b = new B(new A());
Looks "suspiciously" like a dependency. Why not Inject the Dependency?
class B {
private $aClass;
public function __construct($object) {
$this->aClass = $object;
}
public function bClassFunction() {
$test = $this->aClass->aClassFunction();
}
}
we have two class A & B:
class A{
var $settings;
function getinfo(){
$settings['domain']="mydomain";
$settings['pass']="1234";
return $settings;
}
}
class B extends A{
$ads = A::getinfo();
function makeurl(){
return "template/".$ads['domain'];
}
}
now i have an instance of B in my page, but i need "pass" , maybe some code like this:
$theme=new B();
$mypass = $theme->A->getinfo;
echo $mypass[$pass];
I know this code is full of faults , but i could not write a better one. is there any solution to access to password without making an instance of A?
Yes. It is as simple as this:
$theme = new B();
$mypass = $theme->getinfo();
echo $mypass['pass'];
You can also improve your classes a bit:
class A
{
var $settings;
function getinfo()
{
$this->settings['domain'] = "mydomain";
$this->settings['pass'] = "1234";
return $this->settings;
}
}
class B extends A
{
function makeurl()
{
$this->getinfo();
return 'template/' . $this->settings['domain'];
}
}
Why not call the settings variable in A from the B instance since B is a subclass of A?
Try this code:
<?php
class A
{
var $settings;
function getinfo()
{
$settings['domain'] = "mydomain";
$settings['pass'] = "1234";
return $settings;
}
}
class B extends A
{
function makeurl()
{
$ads = $this->getinfo();
return "template/" . $ads['domain'];
}
}
$theme=new B();
$mypass = $theme->getinfo();
echo $mypass['pass'];
What about making settings a public static variable in A? By making it a class variable you won't need an instance of A.
class A {
public static $settings;
// getter and setter methods here
}
// code elsewhere
echo A::$settings['pass'];
Also because your class B extends A it inherits the methods and properties, so you could call
$theme = new B();
$mySettings = $theme->GetInfo();
if B extends A, all protected and public members of A are inherited into B, so you can access them directly.
class A {
protected $foo;
public function __construct() { $this->foo = 1; }
}
class B extends A {
public function bar() {
echo $this->foo;
}
}
$b = B();
$b->bar();
If I understand you correctly, you're pretty close:
$theme=new B();
$settings = $theme->getinfo();
$mypass = $settings['pass'];
echo $mypass;