I have a base class and multiple classes that extends from the base class.
class B {}
class C extends B {}
class D extends B {}
How can I create a C or D inside the method dynamically from B? what's the best way?
For example I tried:
class B {
function hello() { echo "hello"; }
function createObject()
{
$temp = new self();
$temp->hello();
}
}
$t = new C();
$t->createObject();
You're right! But you must return your new object like:
class B {
function hello() { echo "hello"; }
function createObject()
{
$temp = new self();
$temp->hello();
return $temp; // <--- here
}
}
$t = new C();
$tNew = $t->createObject();
Related
I have object $obj (class A).
Can I convert class for $obj to B?
Perhaps there is another way.
Example:
class A
{
public $AProp = 1;
public function &Convert($ATypeName)
{
// HOW?
return $this;
}
}
class B extends A
{
public $BProp = 2;
}
$obj=new A();
$obj->Convert("B");
print_r($obj->BProp);
I wrote next solution, but it is no good.
(It looks like your post is mostly code; I add some more details)
class A
{
public $AProp = 1;
public function &Convert($ATypeName)
{
$Result = new $ATypeName; // Create new object
$Result->AProp = $this->AProp; // Copy params...
return $Result;
}
}
class B extends A
{
public $BProp = 2;
}
$obj = new A();
$obj->AProp = 3;
$obj = $obj->Convert("B");
print_r($obj);
u are trying to use c++-way of class extending.
the php-way is smth like this:
<?php
class A
{
protected $prop = 1;
public function getProp()
{
return $this->prop;
}
}
class B extends A
{
protected $prop = 2;
}
$obj=new A();
print_r($obj->getProp());
$obj=new B();
print_r($obj->getProp());
also take a look on late static bindings - http://php.net/manual/en/language.oop5.late-static-bindings.php
<?php
class A
{
public static $prop = 1;
public function getProp()
{
return static::$prop;
}
}
class B extends A
{
public static $prop = 2;
}
$obj=new A();
print_r($obj->getProp());
$obj=new B();
print_r($obj->getProp());
This is the only way:
$obj = new B();
Since inheritance is used you can access all class A func and var, like $this->Aprop
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
I have the following PHP classes:
class a {
public function vw($xc) {
return $xc;
}
}
class b extends a {
public function wv() {
echo vw() . 'from b via wv';
}
}
$d = new a;
echo $d->vw('this is a');
$c = new b;
echo $c->vw('this is a from b via a');
$c->wv();
The output I am getting is:
this is a
Why am I not getting the outputs of echo $c->vw('this is a from b via a'); and c->wv(); ?
You can access a parent's method via parent::, e.g. parent::vw(). But the method vw of class a expects a parameter, so this code snippet won't work at all. But you should get the idea of using the parent keyword.
class a {
public function vw($xc) {
return $xc;
}
}
class b extends a {
public function wv() {
echo parent::vw() . 'from b via wv';
}
}
$d = new a;
echo $d->vw('this is a');
$c = new b;
echo $c->vw('this is a from b via a');
$c->wv();
http://php.net/manual/en/keyword.parent.php
https://3v4l.org/0MkQI
In the class "b", you should write the function vw as:
public function wv(){
echo $this->vw() . "from b via wv\n";
}
Besides, in your last line the call of $c->wv() lacks a parameter:
$c->wv("I'm a missing parameter");
Try this
class a {
public tt;
public function vw($xc){
$this->tt = $xc;
return $this->tt;
}
}
class b extends a
{
public function(){
return $this->tt. 'from b via wv'
}
}
Assuming I have 2 classes
Class A {
public function doA(){
echo "Im A";
}
}
Class B {
public function doB(){
echo "Im B";
}
}
write Class C, in order that the following code runs:
$c = new C();
$c->doA();
$c->doB();
and outputs:
>> Im A
>> Im B
This was in a test, and the conditions where:
use no static calls
you can't modify class A or class B
so I wrote:
Class C {
public function doA() {
$a = new A();
$a->doA();
}
public function doB() {
$b = new B();
$b->doB();
}
}
So apparently I was wrong as it can be "more optimized"
can someone tell me how to do it?
You could keep instances of A and B instead of instantiating them each time.
class C {
private $a, $b;
public __construct() {
$this->a = new A();
$this->b = new B();
}
public function doA() {
$this->a->doA();
}
public function doB() {
$this->b->doB();
}
}
PHP has no "native" multiple inheritance, but you can achieve something similar to it by using traits.
Trait A {
public function doA(){
echo "Im A";
}
}
Trait B {
public function doB(){
echo "Im B";
}
}
Class C {
use A, B;
}
$c = new C;
$c->doA();
$c->doB();
Note that this would require at least PHP 5.4.
To do it without modifying classes, the best and optimised option would be as follows.
class C {
private $a;
private $b;
public __construct() {
$this->a = new A();
$this->b = new B();
}
public function __call($method, $arguments = array()) {
if(method_exists($this->as, $method)) {
return call_user_func(array($this->a, $method));
}
}
}
The above is also future proof, so adding new methods would also follow.
While you were told not to modify classes A and B, the correct way to do this would be by having B extend A, then having C extend B, like below.
class A {
public function doA(){
echo "Im A";
}
}
class B extends A {
public function doB(){
echo "Im B";
}
}
class C extends B {
}
$c = new C();
$c->doA();
$c->doB();
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;