0

This is a follow up question on the following answer : Parent Object in php

class A {
    protected function doSomeStuff(){
       echo 'a method that all children will need to call';
    }
}

class B {
    protected $_parent;
    public function __construct($parent) {
       $this->_parent = $parent;
    }
    public function doSomeLocalStuff() {
       $this->_parent->doSomeStuff(); // Fatal Error
    }
}

$a = new A(); // will be used for other children as well.
$b = new B($a);
$b->doSomeLocalStuff();

In the above code, parent object Injection was used, allowing class B to be initialized using a specific instance of class A, but class B wont be able to access class A protected properties or methods (e.g., doSomeStuff()).

But by mixing the above with inheritance, we get the best of both worlds :)

class B extends A {
    protected $_parent;
    public function __construct($parent) {
       $this->_parent = $parent;
    }
    public function doSomeLocalStuff() {
       $this->_parent->doSomeStuff(); // Works :)
    }
}

So, is this acceptable ? .. any drawbacks ?

P.S: I'm trying to implement a non-static factory pattern.

Clarification

Consider this, I'm trying to design a class which will be used for calling an external API. We've over 400 different calls, divided into 10 categories (billing, customers, products ... ).

All the 400 calls shares the same parent-url, username/password and some other common properties.

So, instead of putting the 400 method in one big class, I decided to divide them into 10 classes, with a parent class handling common functions (e.g., authentication, url construction, web call ... ), then created a factory pattern, where I can load only needed classes/categories on run-time.

Something like :

$apiCall = new parentPlusFactory(); 
          //contains common methods and a mechanism to load sub-classes
$apiCall->setAPIuserName("user");
$apiCall->setAPIpassword("pass");
$apiCall->useClass('customers')->doSomeCustomerStuff();
$apiCall->useClass('products')->doSomeProductStuff();

That's why I need to share the same parent class instance.

2
  • I don't see why you would want to pass the parent to the constructor when you could just create a new B being an A. If you dont overwrite the methods of A in B you can just keep using them and if you need to add some stuff you can still access them with the parent keyword. Commented Oct 2, 2011 at 9:42
  • Well, I need to share the same class A instance across child classes. Commented Oct 2, 2011 at 14:01

2 Answers 2

1

There is no friend keyword in PHP, like in C++. You could check this discussion for a way to implement friend classes.

But do you really need that function to be declared protected?

Sign up to request clarification or add additional context in comments.

4 Comments

As you mentioned, there's neither friend classes nor a solid work around in PHP. And that parent method must be protected as it has to be called by a child.
And it really couldn't be public?
Yes, as the parent class holds the main logic, which doesn't make sense when called out of context/child classes.
Class A methods are a constructor for an API, where they contain the main logic (connection, username/password ..etc), while other child classes contains actual API methods. I'll try to clarify it more in the question body.
0

In general you should favor composition over inheritance. To me your use case sounds like B should not be extending A at all, but instead you should have two separate classes.

Now, PHP 5.4 will have "horizontal reuse", also known as "traits", where it will be possible to "include" a trait into your class.

trait A
{
    public function doSomeStuff()
    {
        echo 'doing some stuff';
    }
}

class B
{
    use A;

    public function doSomeLocalStuff()
    {
        $this->doSomeStuff();
    }
}

class C
{
    use A;

    public function doSomeLocalStuff()
    {
        echo 'Doing something completely different here';
    }
}

See also PHP manual: traits and PHP 5.4 beta1 released.

2 Comments

The only reason for extending A, is using its protected methods. A method handling api-web-calls in A should only be accessed by one of this specific api sub-classes.
On a second thought .. I'll try to re-design the class using only composition, as it seems the logical way to go.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.