kael.shipman Posted July 22, 2007 Share Posted July 22, 2007 Hey everyone, Sorry in advance for this being so long, but it's really just a lot of clarification. I'm having some trouble with variable referencing between related classes. I thought about using the extends keyword in my child class, but it's not so much an extension of the parent as it is a child in and of itself. The point of having the two classes is to group many distinct and unrelated instances of the child class under a blanket name and other information kept in the parent class. I do admit, however, that I'm too new to OOP to actually say with certainty that extends isn't what I need, so if you see it working, let me know! At any rate, though, what I can't get to work is the sharing of variables between classes. In the example below, I only want there to be ONE memory location for $testVar and one for $errLog (within the classes, that is - the global $errLog can have its own space). I don't want any copies of those variables to exist, but indeed copies are being made and I can't figure out how to prevent that. Take a look: Instantiations: <?php $errLog = array('test error'); //Add something to the global error Log $a = new A; //Instantiate A $b = $a->setB(); //Instantiate B within A $b->chngVar('kah'); //Change the shared variable $testVar and add to the shared error Log echo "\n".$a->testVar; //Check for the change $a->finish(); //Merge shared local errLog with global errLog echo "\n"; var_dump($errLog); //output global errLog ?> Class Definitions: <?php class A { //Parent class var $testVar,$b,$errLog; function A() { $this->testVar = 'cha'; $this->errLog = array(); $this->b = array(); } function setB() { $b = &new B($this->testVar,$this->errLog); $this->b[] = $b; echo " --- Test var should be changed: $this->testVar"; return $b; } function finish() { global $errLog; foreach($b as $chld) { $chld->finish(); } $errLog = array_merge($errLog,$this->errLog); } } class B { //Child class var $errLog,$testVar; function B(&$testVar,&$errLog) { //Capture REFERENCES to the parent class's passed variables $this->errLog = $errLog; $this->testVar = $testVar; //Output demonstrative text echo "Changing Test Var from '$this->testVar'"; $this->testVar = 'nah'; echo " to '$this->testVar'"; } function chngVar($var) { $this->testVar = $var; $this->errLog[] = 'Variable Changed'; } function finish() { //Finish up } } ?> The above code should display the following sequence of events: --ESTABLISH INSTANCE OF A --sets $testVar to 'cha' --sets $errLog to new array --ESTABLISH INSTANCE OF B --sets B::testVar to reference A::testVar --sets B::errLog to reference A::errLog --Output (B outputs) Changing Test Var from 'cha' to 'nah' (and A then outputs) --- Test var should be changed: 'nah' --RUN B::CHNGVAR('kah') --sets shared testVar to 'kah' --adds 'Variable Changed' to shared errLog --OUTPUT SHARED A::testVar kah --RUN A::FINISH() --runs B::finish() (empty function) on each instance of B --merges A::errLog with global errLog --OUTPUT GLOBAL ERRLOG array(2) { [0]=>string(10) "test error", [1]=>string(16) "Variable Changed" } Instead, however, it seems to follow this sequence: --ESTABLISH INSTANCE OF A --sets $testVar to 'cha' --sets $errLog to new array --ESTABLISH INSTANCE OF B --sets B::testVar to EQUAL A::testVar --sets B::errLog to EQUAL A::errLog --Output (B outputs) Changing Test Var from 'cha' to 'nah' (and A then outputs) --- Test var should be changed: 'cha' --RUN B::CHNGVAR('kah') --sets B::testVar to 'kah' --adds 'Variable Changed' to B::errLog --OUTPUT SHARED A::testVar cha --RUN A::FINISH() --runs B::finish() (empty function) on each instance of B --merges A::errLog with global errLog --OUTPUT GLOBAL ERRLOG array(2) { [0]=>string(10) "test error" } As you can see, it's simply using copies of the two variables instead of the reference that I passed. Any ideas as to how I might change that? Thanks for bearing with the huge freakin' post. -kael Quote Link to comment Share on other sites More sharing options...
KevinM1 Posted July 22, 2007 Share Posted July 22, 2007 In PHP, the extends keyword is used to invoke inheritance. If class B truly is a child of class A (that is, you want B to have the properties and methods of class A), then using extends is the way to go. As far as your error is concerned, I'm not sure if this is the cause of your problem, but I believe you have a syntax error in B's constructor. Try: <?php function &B(&$testVar,&$errLog) { //Capture REFERENCES to the parent class's passed variables $this->errLog = $errLog; $this->testVar = $testVar; //Output demonstrative text echo "Changing Test Var from '$this->testVar'"; $this->testVar = 'nah'; echo " to '$this->testVar'"; } ?> The '&' before B tells the function to return a reference. More info can be found at: http://us.php.net/manual/en/language.references.return.php Quote Link to comment Share on other sites More sharing options...
kael.shipman Posted July 23, 2007 Author Share Posted July 23, 2007 Thanks for the reply! However, I think the reference to class B is passed when I call it with the & in front of 'new', like "$b = &new B;" (http://us.php.net/manual/en/language.oop.newref.php). Besides, I don't think that's quite the problem I'm having. The class is being referenced fine, but what's being copied are the two variables that I pass to B's constructor, A::testVar and A::errLog. I've been beating my head against the wall forever on this! No fun! Any other help? Oh, and the reason I didn't want B to be a true child of A is because I don't want the methods of A to pass down to B; just those two specific class variables. -kael Quote Link to comment Share on other sites More sharing options...
kael.shipman Posted July 23, 2007 Author Share Posted July 23, 2007 Alright, update: It looks like it may actually just be a bug involving the internal variable referencing in general. To clarify that remarkably vague and elusive statement, what I mean is this: Instead of passing the class variable $this->testVar by reference to the constructor of B, I passed the entire object by passing simply $this. When I did that, I was able to access the variable through B::parentObject, which is the B-class variable that I assigned to the reference of the A object. When I changed $this->parentObject->testVar (where $this is called within B), it changed A::testVar as desired. (sorry to use different functions, but I had to simplify during my testing): <?php class cha { var $testVar; function cha() { $this->testVar = 'nah'; } function newOne() { $ref = &new gah($this); return $ref; } } class gah { var $parentObject; function gah(&$po) { $this->parentObject = $po; } function chngVar($var) { $this->parentObject->testVar = $var; } } $cha = new cha(); $gah = $cha->newOne(); $gah->chngVar('new Value!'); echo $cha->testVar; //Outputs the EXPECTED value, "new Value!" ?> So the only difference between what I did above and what I want to do in the end is that I want to pass a VARIABLE from class A by reference instead of the entire object. I suspect it may have something to do with the way the '->' works. Would using the whole scope resolution dealy work (the :: sign)? To be honest, I don't actually know what that's for, so maybe that's the answer. Help! [move]A Marquee!! What an obnoxious option to include on a forum!! (No offense, forum guys; this place is great anyway)[/move] Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.