Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
In file A,
Class A {
__construct() {
...
lots of code
...
}
public function P() {
code here
}
}
New A();
In file B,
Class B {
__construct() {
...
lots of code
...
}
public function E() {
I need to call function P in Class A
}
}
New B();
I would like to call the function P() in function E().
Is there any way to call a function in another class?
I found several ways such as dependency injection using __construct( A $aobj ) or "extends"
However, the class A was already instantiated in file A and there're a lot of things in __counstruct so I would like to know
1) the way of refractory technique
2) fancy way to call function E() in function P().
It really depends on how class B is related to A :
no link : the function in A should be static (it doesn't interact with a specific instance of A and its properties), and you can call A::P()
the class B is a child of A :
In B class definition, you have a class B extends A and in the constructor of B, you will have a parent::__construct() to call the constructor of A.
Then you can simply call $this->P() : as B is a subclass of A, and P is public (or protected), B inherits of all methods from A
The class B uses a object of type A`
Then, you must have a $a attribute in the class B, and a $this->a = new A(); in the constructor of B. You can call P with $this->a->P();
Or if you need only temporarily A in E(), you can construct a new object $a = new A(); and call $a->P(); in the code of E
Let's say that we have file a.php which contains class A:
class A {
public function __construct()
{
}
public function P()
{
echo "It is function P";
}
}
And file b.php which contains class B, in file b.php we first include a.php
include('a.php');
class B {
private $aobj;
public function __construct(){
$this->aobj = new A();
}
public function E(){
$this->aobj->P();
}
}
$b = new B();
$b->E();
Now open the browser and http://localhost/your-project/b.php and see the result.
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 20 days ago.
Improve this question
During some workaround with some architecture I faced a question and I am wondering if this implementation follows best practice or not.
Here we have a base abstract class:
abstract class A {
protected mixed $object;
public function __construct() {
$this->loadObject()
->fuc1();
}
abstract protected function loadObject(): self;
abstract public function fuc1(): bool;
abstract public function fuc3(): iterable;
}
In this case, I want to implement Class B and C. if I create each class separately everything is fine but as far as these 2 classes have the same functions I decided to create a base class for them (BC) so codes are now like this:
class BC extends A {
protected string x;
protected string y;
protected function loadObject(): self {
throw new \Exception('Child must implement loeadObject');
}
public function fuc1(): bool {
//Some Codes
}
public function fuc3(): iterable {
//Some Codes
}
}
And Class B and Class C are like this:
class B extends BC {
protected function loadObject(): self {
$this->object = new SomeObject();
return $this;
}
}
class C extends BC {
protected function loadObject(): self {
$this->object = new SomeObject2();
return $this;
}
}
We also can not move loadObject function to class BC cuz maybe class D wants to inherit directly from class A.
We can also rely on interfaces but I was wondering if some one forget to make class B/C implement an Interface then we will have problem in class A.
So is it a good practice that we throw exceptions in the class BC and force other developers to don't forget to overwrite the loadObject function?
This is not a good practice, if you doesn't need to implement the loadObject method in the BC class, you should keep it abstract.
abstract class BC extends A {
protected string $x;
protected string $y;
public function fuc1(): bool {
}
public function fuc3(): iterable {
}
}
I have 2 classes declared like in the example below.
class A{
protected $process;
public function __construct() {
......
$this->process=new B();
}
public function do_something(){
....
}
}
class B{
// content not important
// I need to call do_something from class A
}
My question is, how can I call from class B the method do_something() from class A? Is it possible?
From your example it is impossible for instance of B to know that it is instantiated and stored by an instance of class A. You need to create that connection explicitly in some way.
I didn't think this would even work, but apparently you can pass instance of A to B before A is even done with its constructor:
class A {
protected $process;
public function __construct() {
$this->process = new B( $this );
}
public function do_something() {
var_dump( 'do_something' );
}
public function test() {
$this->process->test();
}
}
class B {
public function __construct( A $a ) {
$this->a = $a;
}
public function test() {
$this->a->do_something();
}
}
$a = new A();
$a->test(); // do_something
It's hard to give an advice on what the best approach for your particular case would be, as we don't know what either A or B does.
There's a few ways to achieve this. One way would be to make B and extension of A - thereby allowing all methods of the class A to be callable on the object B. Another way is to create a new object of A inside B and call that method. Or you can pass
Here's an example where B is extended from A. By doing this, all properties and methods of A can be called on B, unless overwritten in B.
class A {
public function doSomething(){
echo "doSomething() called in A";
}
}
class B extends A {
public function someMethod() {
$this->doSomething();
}
}
$b = new B();
$b->someMethod();
The above would output doSomething() called in A.
Or, you can create an object A and call that method inside B.
class B {
public function someMethod() {
$a = new A();
$a->do_something();
}
}
$b = new B();
$b->someMethod();
After reading all the answers and doing some research i think that the best method for me was the use of Traits
"Traits are a mechanism for code reuse in single inheritance languages such as PHP. A Trait is intended to reduce some limitations of single inheritance by enabling a developer to reuse sets of methods freely in several independent classes living in different class hierarchies."
So i declared a Trait with the method do_something and call that method from Both class A and Class B
Thanks
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
Why is the following code returning NULL? I am trying to get the parent method to return a value of a property inside the parent class but for some reason it is returning null.
class A {
public $greeting;
public function __construct($message){
$this->greeting = $message;
}
public function getGreeting(){
print 1;
return $this->greeting;
}
}
class B extends A{
public function __construct(){
}
public function getGreetingMessage(){
parent::getGreeting();
}
}
$classA = new A('Hello world');
$classB = new B();
var_dump($classB->getGreetingMessage());
In the parent method "1" is being printed so I know the method is being called
Because the greeting message is not set in class b. so greeting message returns null.
1) return parent::getGreeting();
2) $classA and $classB are different instances. Whatever you set in $classA is not accessible in $classB
3) constuctor of the parent is not called from classB and, moreover, you do not provide any arguments in initialization of classB (look at 2) above)
class A {
public $greeting;
public function __construct($message){
$this->greeting = $message;
}
public function getGreeting(){
print 1;
return $this->greeting;
}
}
class B extends A{
public function __construct($message){
parent::__construct($message);
// or $this->greeting = $message;
}
public function getGreetingMessage(){
return parent::getGreeting();
}
}
$classA = new A('Hello world');
$classB = new B('Hello world 2');
var_dump($classB->getGreetingMessage());
You have to call the parent's constructor in the child class, otherwise the parent constructor is not run and the class isn't properly initialized:
class B extends A{
public function __construct($message){
parent::__construct($message);
}
So you most likely want this
$classB=new B('Hello World');
This question already has answers here:
Use global variables in a class
(4 answers)
Closed 10 years ago.
I'm starting with OOP in PHP and there is something I'd like to do. Let me show an example:
classes.php
<?php
class a {
public function a() {
echo 'a';
}
}
class b {
public function calla() {
$x->a();
}
}
?>
index.php
<?php
include('classes.php');
$x = new a();
$d = new b();
$d->calla();
?>
Is this possible? I know I can do something like:
class b {
public function calla($object) {
$object->a();
}
}
and
$d->calla($x);
but is the first example possible to do?
So you want to use $x as global variable? Syntax is the same, object or not:
class b {
public function calla() {
$GLOBALS['x']->a();
}
}
... or:
class b {
public function calla() {
global $x;
$x->a();
}
}
Of course, it's a horrible design that injects hard to track dependencies and will probably lead to unexpected side effects and head-scratching.
Additionally, a() is a poor method name for class a because it's the PHP 4 syntax for constructors. If you run this code:
<?php
class a {
public function a() {
echo 'a';
}
}
class b {
public function calla() {
$GLOBALS['x']->a();
}
}
$x = new a();
$d = new b();
$d->calla();
... you'll see that a() runs twice. Guess why?
I think I understand what you're trying to ask but you're mixing up parameters visibility concept with object passing in class methods. So let's clean up...
In your classes.php file the method calla() of the class b as absolutely nothing to do with class a, unless $x itself is an instance of the class a.
In your index.php file you instantiate $x as class a, but it is a global variable, and the class b has no visibility on it. Moreover, your call to $d->calla() would return an error because you are accessing a private method from outside.
Your third example gets closer to the solution, passing the instance to the calla() method helps class b seing the instance of class a, I guess you want to edit your index.php file to:
<?php
include('class.php');
$x = new a();
$d = new b();
$d->calla($x);
?>
But this still won't work until you change the private methods to public ones.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
It's possible to do this if the class B NOT extended the class A but the class A call a new class B
class A{
public $lang;
public function __construct($lang) {
$this->lang=$lang;
}
public function new_B(){
return new B();
}
}
class B{
public function __construct() {
echo 'lang='.A::$lang;
}
}
$root=new A('eng');
$root->new_B();
You seem to have a mixup of concepts here. The $lang property of A is an instance level variable (since it is not defined as static), therefore you cannot access it statically as you are trying to. If you were to declare the variable as static then you would have access to it, but if you have multiple instances of class A that change it, it will change on the class level, rather than instance level.
Is A::$lang common to all A objects you will create? Then make this variable static. If not you can pass A::$lang as parameter to the B constructor. That is
class A{
public $lang;
public function __construct($lang) {
$this->lang=$lang;
}
public function new_B(){
return new B($this->lang);
}
}
class B{
public function __construct($lang) {
echo 'lang='.$lang;
}
}
Following is making A::$lang static:
class A{
public static $lang;
public function __construct($lang) {
self::$lang=$lang;
}
public function new_B(){
return new B();
}
}
class B{
public function __construct() {
echo 'lang='.A::$lang;
}
}
change the class B like this:
class B extends A{
public function __construct() {
echo 'lang='.$this->$lang; // you can use parent variables like this
}
}