tags:

views:

149

answers:

5

I have a class in php that creates another class, and I want this child class to be able to call the parent class, but without passing $this as an argument to the child class. I don't want to make the parent class global either. Is there a way to call the parent class, somehow like parent->function or something similar?

A: 

It’s kind of hacking, but try to analyze debug_backtrace()

Maciej Łebkowski
+4  A: 

I think what you call a parent-child relationship is just a composition (the 'parent' holds an instance of an unrelated in the hierarchy class, the 'child'). If my assumption is correct, then this smells bad because the two classes would be tightly coupled and that points to bad design somewhere (the 'parent', the 'child' or both).

Less smelly alternatives:

  • Get needed data from the 'child' and call the method in the 'parent' with that data
  • Pass the data the 'parent' holds to the 'child' and put the method there so the 'child' can call it
  • Call the method in the 'parent' and pass the result to the 'child'
  • Use inheritance if it makes sense so both the 'parent' and the 'child' become really parent and child and both have the method, then the 'parent' wouldn't need to create a 'child', you would directly use a child in the code.
Vinko Vrsalovic
+2  A: 

As Maciej says, this is pretty hackish, and I wouldn't recommend it, but it is possible:

<?php

    class B 
    {
     function B() {
      $trace = debug_backtrace();
      $trace[1]['object']->y();
     }
    }

    class A 
    {
     function x() {
      $z = new B;
     }
     function y() {
      printf("hi");
     }
    }

    $test = new A;
    $test->x();

?>
Daniel
+1 for not resisting the temptation to show the evil ways :)
Vinko Vrsalovic
+1. you probably just introduced the poor successor of the OP to a world of pain and made several enemies among seasoned coders, just because the OP is too lazy to implement setParent();
Schnalle
@Schnalle, hey! there's a pretty disclaimer on top! :)
Daniel
true. but better don't post your address in your profile, just to be safe :)
Schnalle
A: 

(...) but without passing $this as an argument to the child class

heavens, WHY? "look ma, i can pee without holding'im with my hands. oops, now it happened again. great."

it could be so simple, but i suppose we'll never know why this is forbidden. my guess is, you just don't understand OOP (as your confusion between class and instance hierarchies suggests), and you're too lazy to learn it. Ceci n'est pas une pipe!

look:

<?php
    class AClass {
        public $parent = false;

        public function setParent($parent) {
            $this->parent = $parent;
        }

        public function createChild() {
            $newInstance = new AClass();
            $newInstance->setParent($this);
        }
    }
?>

yes, it's that easy! you now have the parent.

or is it, because you're not allowed to modify the parent class?
there's a secret, but i'll tell you:

0th level cantrip for evil warlocks: inheritance, also known as "class B extends A {}".

i apologize in advance for being a mean, sarcasic, unhelpful ass, but if i'd really stood behind the apology, i wouldn't have written that answer.

BUT i promise to vote your question up (and apologize honestly) if you can give us a good reason why passing a reference is forbidden.

Schnalle
I think you may have cracked...?
ck
sorry, i regulary snap when people say: "help me, i need to do x, but not the obvious, easy, well-tested, accepted way, because ... because i don't want to or no-reason-given!"
Schnalle
seesh, now i already feel bad. but i'm still interested in the "why".
Schnalle
By the way, I really don't find the setParent() solution pretty. You really don't want to give the child access to the whole parent, just to what's really needed.
Vinko Vrsalovic
but it hasn't got access to the whole parent, just the public properties and methods. *everything* has that much access.
Schnalle
I meant that you almost never need ALL methods and properties just to call a single method. If you do, you have bigger problems, which have better solutions than passing the whole instance.
Vinko Vrsalovic
to be honest, i don't even know a different way - besides wrapper/helper classes - until proper anonymous first class functions with closures are available (>=5.3).
Schnalle
Redesign so you don't need to call a method written elsewhere. You pass the data to the child and only the data or ... (read my answer).
Vinko Vrsalovic
A: 

I Don't do enough PHP to know if this is possible but could you not pass a delegate/callback in to the constructor of the object? This way you don't have the whole object there just a reference to the method that you want to call!

HTH

OneSHOT

OneSHOT