How to get the class that created the current object? - php

I would like to prevent foo() from being executed by any other class than B. How can I check which class created object A?
<?php
class A
{
public function foo()
{
if (.... B ) // what should be on the dotts?
echo 'I\'m created by class B, which is fine';
else
echo 'Execution of foo() is not allowed';
}
}
class B
{
public function go()
{
$a = new A;
$a->foo();
}
}
class C
{
public function go()
{
$a = new A;
$a->foo();
}
}
$b = new B;
$b->go(); // result: I\'m created by class B, which is fine
$c = New C;
$c->go(); // result: 'Execution of foo() is not allowed'

A commonly asked question (e.g. How to get called function name in __construct without debug_backtrace), but in a well-designed application it shouldn't be necessary for a class to know where it's being called from, or to prevent being instantiated when requested.
If you need this type of restriction, then make your class a private attribute of the main class that is permitted to access it.
If you absolutely have to do it, pass the caller through as an argument to the method in preference to the horrendously inefficient debug_backtrace method.

Declare foo in class B instead and make it private and, optionally, final. Why would want to define in A a method that can only be called by B?

Related

How to pass object to another class?

I have class B. In this class I create object classB(). And I have a question how can I pass this new classB() to another class ?
class A
{
public classB $classB;
public function __construct()
{
$this->classB = new classB();
}
}
class C
{
public function example()
{
/// here I want to object new classB() created in class A
}
}
If I take your code, only slightly altered:
class A
{
public $b;
public function __construct()
{
$this->b = new B();
}
}
Then continue to create an object from that class:
$a = new A();
Then I can access the public property b, which is an object of class B, like so:
$accessB = $a->b;
Now if you want to use property b in another class you can do:
class C
{
public function example($anObject)
{
// here you can use $anObject
}
}
$c = new C();
$c->example($a->b);
That's all there is to it.
Please, next time you want to provide an example, make it meaningful. So instead of say "class A" call it, for instance, "class Car", and "class Wheel". Using meaningful class names, that clearly relate to each other, helps to understand what you're doing and helps to get away from abstract code.

PHP - Call a method from the class where i instantiated my object

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

Variables in Classes

I stumbled across a very wired error in php:
class A {
public $var = "test";
public function __construct() {
$this->var = "test2";
$b = new B;
$b->method();
}
}
class B extends A {
public function method() {
$c = new C;
$c->method();
}
}
class C extends B {
public function method() {
echo $this->var;
}
}
$a = new A;
I get the output "test", but I do not know why, cause the variable var should be overwritten in Class A.
If I output $var in Class A it says "test2", if I output it in Class B it says "test"…
The code on your question won't work because of the circular references (eg: $b = new B in A's constructor), which will cause PHP to run out of memory. You really shouldn't be instantiating children classes in a parent class.
That being said, by what you are describing, it sounds like you are defining a constructor in B, which overrides the parent constructor. In PHP children classes don't implicitly call the parent constructor (unlike in languages like Java).
So, it just inherits the original value for $var (ie: "test"), which is never changed. If you are overriding __construct() in B, you'll have to explicitly call the parent constructor, like:
class B extends A {
public function __construct() {
parent::__construct();
}
}
And that should give you "test2" when you do something like:
$b = new B;
echo $b->var;
See this demo: http://ideone.com/Q9Bp8
What is the best way to have 3 classes, where the third and second can access variables of the first class?
The answer is, it depends on what you are doing. It sounds like you are not understanding how OOP works, which is a bigger problem. In general you only use inheritance when the children classes could reuse code from the parent class, and/or there is some sort of is-a or has-a relationship.
If your classes don't fit this model, just make the 3 classes independent, and hold a reference to the first class in your other classes. For example:
class A {
public $n = 0;
public function change($n) {
$this->n = $n;
}
}
class B {
public function __construct($a) {
$this->my_a = $a;
}
public function get() {
return $this->my_a->n;
}
}
$a = new A();
$b = new B($a):
echo $b->get(); // 0
$a->change(10);
echo $b->get(); // 10
See this demo: http://codepad.org/xL1Dzs0W

Call function of class ONE from class TWO without extend?

If i have two classes A, B and one does not extend another they are separate but both loaded into script can i still reference function in A from B?
class A {
function one() {
echo "Class A";
}
}
class B {
function two() {
echo "Class B";
A::one();
}
}
$a new A;
$b = new B;
$b->two();
On the face of it, yes, you can do this. However, function one() in class A needs to be declared as static for your call notation to work. (This makes it a class method.)
The other alternative, suggested by the last lines in your code, is for the instance $b to call a function in instance $a. Such functions are called instance methods and are how you normally interact with an object. To access these methods, they must be declared as public. Methods declared as private can only be called by other methods inside that class.
There are several ways to call an instance method in your code. These are the obvious two you can pass in $a as a parameter to the function, or you can create an instance of class A inside your method.
What are you actually trying to achieve?
You can define it like this.
class A {
public static function one() {
echo "Class A";
}
}
class B {
function two() {
echo "Class B";
A::one();
}
}
$a new A;
$b = new B;
$b->two();
You can define one as static, but why would you do such a thing?

Object of class A cannot be create directly but only by class B

class A
{
public function foo()
{
}
}
class B
{
$a = new A;
public function go()
{
}
}
I want A object cannot be created directly.But only by class B.
How i can do this.
Why would you need that?
Remember - a class is a defacto factory for objects, and the object should do things, and it should do them with passed params and available instance variables which means you should pass everything the object needs to the constructor and you should not care about the fact that the object can be created by everybody.
Seriously.
Sounds like you want to extend an abstract class.
abstract class A {
protected function foo() {
echo "Hello world!";
}
}
class B extends A {
public function go() {
$this->foo();
}
}
$obj = new B;
$obj->foo(); // error - cannot call a protected method directly
$obj->go(); // echo's "Hello world!"
If you really want to do this, check factory design pattern. I think it will what you are asking for. There we will have a separate factory class for managing object creation.

Categories