Re: [PHP] Weird behaviour with references to objects...
Ernest E Vogelsinger [EMAIL PROTECTED] wrote in message news:5.1.1.6.2.20021108175627.00b44880;mail.vogelsinger.at... This is clearly said in your PHP.ini file: ; Whether to enable the ability to force arguments to be passed by reference ; at function call time. This method is deprecated and is likely to be ; unsupported in future versions of PHP/Zend. The encouraged method of ; specifying which arguments should be passed by reference is in the function ; declaration. You're encouraged to try and turn this option Off and make ; sure your scripts work properly with it in order to ensure they will work ; with future versions of the language (you will receive a warning each time ; you use this feature, and the argument will be passed by value instead of by ; reference). allow_call_time_pass_reference = On ...god has spoken :) yup that's one hell of an argument :) I'd rather have the abilty to pass A reference like foo($a) and have the opportunity to choose at runtime if I want to use a reference here or not, but it's how they say... -- O Ernest E. Vogelsinger (\) ICQ #13394035 ^ http://www.vogelsinger.at/ -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Weird behaviour with references to objects...
At 03:36 08.11.2002, Tim Molendijk said: [snip] begin first code snippet ?php /* New Container object created. At the same time it sets a Child object in its $child attribute. (This is indicated by passing TRUE.) */ $testContainer1 = new Container(TRUE); Ahh - culprit 1: You said the container is creating a child instance - I assume it's done in the constructor... What you're doing here is to create a clone when assigning new()'s result to $testContainer1. You should rather $testContainer1 = new Container(TRUE); Note the ampersand here - if you don't you'll get a clone. Rule for references: If your object does something in its constructor, use a reference assignment for new class() Below the code for the classes Container en Child. begin third code snippet ?php class Container { var $children; var $property; // stuff deleted function load() { $newChild = new Child(1); Again - make this $newChild = new Child(1); function add($child) { /* Here a reference of $this (the Container object) is assigned to $child's $parent attribute. */ $child-parent = $this; /* Here $child (the newly created Child object) is assigned to the container's $child property. */ $this-child = $child; } But you don't pass $child by reference! Make this function ($child) If you don't pass $child as a reference, the line $child-parent = $this; will set the parent value of the clone that's passed as an argument, and leave the original $child unmodified! Crosscheck all of your class code (and the code utilizing it) it you're always passing references. Ref's work like a charm until you mess up at a single location. Well, having made my way from C/C++ to PHP I'd rather deal with pointers, but unfortunately PHP doesn't have them. So keep an eye open .-) -- O Ernest E. Vogelsinger (\)ICQ #13394035 ^ http://www.vogelsinger.at/ -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Weird behaviour with references to objects...
with the reference you simply are re-refering the old internal values of the class. No, it is not reccomened to do so, unless, of course, you have a very good reason to. -- Maxim Maletsky [EMAIL PROTECTED] Martin Towell [EMAIL PROTECTED] wrote... : I remember reading somewhere (can't remember where though, maybe the php.net web site??) that if you use $this in a constructor (or any methods the constuctor calls), then you should instantiate the object using new otherwise you get a copy of the object that's just been created and not the actual new object (if that's not too confusing...) It's to do with the way the assignment operator works.. -Original Message- From: Tim Molendijk [mailto:tawm;wanadoo.nl] Sent: Friday, November 08, 2002 4:14 PM To: [EMAIL PROTECTED] Subject: Re: [PHP] Weird behaviour with references to objects... Hi all, First of all, thank you for the suggestions. Actually I accidently found a solution to the problem... Not that I understand it now, I just found a way to cope with it. By changing the first line of the first code snippet: $testContainer1 = new Container(TRUE); into: $testContainer1 = new Container(TRUE); the problem is gone! Don't ask me WHY this is the solution. In my Container-add() method I assign A REFERENCE of the Container object ($this) to $child-parent so I don't see why creating the Container object by reference is useful... If anyone has additional information on this subject feel free to post! Thanks everyone! Tim. Mike Mannakee [EMAIL PROTECTED] wrote in message news:20021108044622.68446.qmail;pb1.pair.com... This sounds like a matter that ought to make it to the programmers who code PHP itself. In the meantime can you code around it now that you know the bug is there? Mike Marco Tabini [EMAIL PROTECTED] wrote in message news:1036725595.21741.868.camel;localhost.localdomain... I'm not sure if my answer is going to be of much help, but I think this has to do with the way PHP handles references and copies of objects--it uses what I understand is a lazy copy mechanism, and thus the results on object manipulations can yield odd results. There was a discussion on a similar problem on PHP-DEV a while back--if you search the forums you should be able to find it. Hope this helps... Marco - php|architect -- The Monthly Magazine For PHP Professionals Come visit us on the web at http://www.phparch.com! On Thu, 2002-11-07 at 21:36, Tim Molendijk wrote: First of all I would like to say that I know this is a lot of text but I would be very pleased if you take a little time to read it nevertheless. The situation described below is not complicated at all... = Hello all, I'm dealing with this really weird problem which occurs when dealing with references within objects pointing to other objects. I'm trying to find out what it is now for a few days and I still don't get it. I minimised the code around the problem and it's weirder than ever. I would really appreciate it when you could take a look... I'm pretty experienced at PHP but perhaps you know something that I don't know. We have two different classes: Container and Child. Container objects contain a Child object in its $child property. A Child object has a $parent property, which contains a *reference* to the Container object by which it is held. So $containerObject should be the *same* as $containerObject-child-parent. To test this Container objects have a $property property. When changing this property the difference between one object and identical/cloned objects becomes visible. Now take a look at the following code. The indented text is code, the rest are comments. The code for the class Container and class Child are also included. Please scroll down or take a look at the attached file. begin first code snippet ?php /* New Container object created. At the same time it sets a Child object in its $child attribute. (This is indicated by passing TRUE.) */ $testContainer1 = new Container(TRUE); /* The Container object is created, the Child object is set and its reference to the Container object is set. Now it prints $testContainer1-property and $testContainer-child-parent-property. These should have an identical value because they should be from the same object (not cloned/identical, but the same). This is the result: property = 'state 1' child-parent-property = 'state 1' So this is as expected, no problem... yet. */ $testContainer1-printState(); /* Now $testContainer1's $property property is changed into another value
Re: [PHP] Weird behaviour with references to objects...
Ernest E Vogelsinger [EMAIL PROTECTED] wrote in message news:5.1.1.6.2.20021108092657.02befe20;mail.vogelsinger.at... At 03:36 08.11.2002, Tim Molendijk said: [snip] Ahh - culprit 1: You said the container is creating a child instance - I assume it's done in the constructor... What you're doing here is to create a clone when assigning new()'s result to $testContainer1. You should rather $testContainer1 = new Container(TRUE); Note the ampersand here - if you don't you'll get a clone. Rule for references: If your object does something in its constructor, use a reference assignment for new class() Ernest, Before your post I accidently found out a solution: $testContainer1 = new Container(TRUE) instead of $testContainer1 = new Container(TRUE); When I found this out I didn't understand WHY this was the solution... Thanks to your comments I DO understand why... I suddenly see every jigsaw piece fall in place :D The difference between the first code snippet (that with $testContainer1) and the second code snippet (that with $testContainer2) is that in code snippet 2 the Container object is already constructed and assigned to $testContainer2 when loading it. Then when it is loaded $this (in add()) refers to the object in $testContainer2 so no problem occurs. But in code snippet 1 the Container object loads itself before it is assigned to $testContainer1. During this process $this (in add()) refers to the object that is being created. And now the core is: the object that is being created is *not* the same object as the one that is assigned to $testContainer1!! So the references to the created object will not refer to $testContainer1!! That's it!!! I completely understand... Thanks a lot Ernest! Again - make this $newChild = new Child(1); But you don't pass $child by reference! Make this function ($child) If you don't pass $child as a reference, the line $child-parent = $this; will set the parent value of the clone that's passed as an argument, and leave the original $child unmodified! This is not true in my case, because instead of doing: function add($child) { ... } I do: function add($child) { ... } and then call it with: $this-add($child); This has the same result... As far as I know I doesn't matter whether you put an ampersand before the variable in your function definition or your in your function call. Crosscheck all of your class code (and the code utilizing it) it you're always passing references. Ref's work like a charm until you mess up at a single location. Well, having made my way from C/C++ to PHP I'd rather deal with pointers, but unfortunately PHP doesn't have them. So keep an eye open .-) The problem is solved and I completely understand why now. This last thing is thanks to you Ernest. Regards, Tim -- O Ernest E. Vogelsinger (\)ICQ #13394035 ^ http://www.vogelsinger.at/ -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Weird behaviour with references to objects...
At 16:48 08.11.2002, Tim Molendijk spoke out and said: [snip] The problem is solved and I completely understand why now. This last thing is thanks to you Ernest. [snip] Glad it works - you're very welcome :) -- O Ernest E. Vogelsinger (\) ICQ #13394035 ^ http://www.vogelsinger.at/
Re: [PHP] Weird behaviour with references to objects...
One more: At 16:48 08.11.2002, Tim Molendijk spoke out and said: [snip] This is not true in my case, because instead of doing: function add($child) { ... } I do: function add($child) { ... } and then call it with: $this-add($child); This has the same result... As far as I know I doesn't matter whether you put an ampersand before the variable in your function definition or your in your function call. [snip] True for now, but this is officially deprecated. Functions or methods accepting a reference are required to be prototyped that way - this helps you not to forget to pass by reference. You really should modify your functions using reference parameters when declaring them, if you're using references... -- O Ernest E. Vogelsinger (\) ICQ #13394035 ^ http://www.vogelsinger.at/
Re: [PHP] Weird behaviour with references to objects...
Ernest E Vogelsinger [EMAIL PROTECTED] wrote in message news:5.1.1.6.2.20021108165218.03238948;mail.vogelsinger.at... One more: True for now, but this is officially deprecated. Functions or methods accepting a reference are required to be prototyped that way - this helps you not to forget to pass by reference. You really should modify your functions using reference parameters when declaring them, if you're using references... Yes I know it is poor programming habits to do like I did... But I have a reason for it. I have quite a lot methods that accept objects *optional*. So f.e.: --- class Product { var $language; function Product($language = FALSE) { $this-language = $language; } } --- Now to make this possible it becomes impossible to do what you suggest: function Product($language = FALSE) is not allowed. And in my application this optional arguments functionality is very important. So I have preferred this over the decent habit. -- O Ernest E. Vogelsinger (\) ICQ #13394035 ^ http://www.vogelsinger.at/ -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Weird behaviour with references to objects...
At 17:04 08.11.2002, Tim Molendijk spoke out and said: [snip] Yes I know it is poor programming habits to do like I did... But I have a reason for it. I have quite a lot methods that accept objects *optional*. So f.e.: --- class Product { var $language; function Product($language = FALSE) { $this-language = $language; } } --- Now to make this possible it becomes impossible to do what you suggest: function Product($language = FALSE) is not allowed. And in my application this optional arguments functionality is very important. So I have preferred this over the decent habit. [snip] You might always simply omit the parameter when calling the function (you'll get a notice about that if enabled). You just cannot pass constants: function Product($language) { ... } // ok, but gives a notice Product(); // will fail Product('ger'); If you keep your code like it is be warned that it may break with a future version of PHP. -- O Ernest E. Vogelsinger (\) ICQ #13394035 ^ http://www.vogelsinger.at/
Re: [PHP] Weird behaviour with references to objects...
Ernest E Vogelsinger [EMAIL PROTECTED] wrote in message news:5.1.1.6.2.20021108170633.00b8cb60;mail.vogelsinger.at... You might always simply omit the parameter when calling the function (you'll get a notice about that if enabled). You just cannot pass constants: function Product($language) { ... } // ok, but gives a notice Product(); // will fail Product('ger'); ok well that's an idea indeed... i'll think about it. If you keep your code like it is be warned that it may break with a future version of PHP. why do you think it won't be supported by future versions? all i do is passing an object by reference. because in this case this function always should accept its argument as a reference and therefore is bad programming habit does not mean the php construction is bad or weird!?! -- O Ernest E. Vogelsinger (\) ICQ #13394035 ^ http://www.vogelsinger.at/ -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Weird behaviour with references to objects...
At 17:32 08.11.2002, Tim Molendijk spoke out and said: [snip] why do you think it won't be supported by future versions? all i do is passing an object by reference. because in this case this function always should accept its argument as a reference and therefore is bad programming habit does not mean the php construction is bad or weird!?! [snip] This is clearly said in your PHP.ini file: ; Whether to enable the ability to force arguments to be passed by reference ; at function call time. This method is deprecated and is likely to be ; unsupported in future versions of PHP/Zend. The encouraged method of ; specifying which arguments should be passed by reference is in the function ; declaration. You're encouraged to try and turn this option Off and make ; sure your scripts work properly with it in order to ensure they will work ; with future versions of the language (you will receive a warning each time ; you use this feature, and the argument will be passed by value instead of by ; reference). allow_call_time_pass_reference = On ...god has spoken :) I'd rather have the abilty to pass A reference like foo($a) and have the opportunity to choose at runtime if I want to use a reference here or not, but it's how they say... -- O Ernest E. Vogelsinger (\) ICQ #13394035 ^ http://www.vogelsinger.at/
[PHP] Weird behaviour with references to objects...
First of all I would like to say that I know this is a lot of text but I would be very pleased if you take a little time to read it nevertheless. The situation described below is not complicated at all... = Hello all, I'm dealing with this really weird problem which occurs when dealing with references within objects pointing to other objects. I'm trying to find out what it is now for a few days and I still don't get it. I minimised the code around the problem and it's weirder than ever. I would really appreciate it when you could take a look... I'm pretty experienced at PHP but perhaps you know something that I don't know. We have two different classes: Container and Child. Container objects contain a Child object in its $child property. A Child object has a $parent property, which contains a *reference* to the Container object by which it is held. So $containerObject should be the *same* as $containerObject-child-parent. To test this Container objects have a $property property. When changing this property the difference between one object and identical/cloned objects becomes visible. Now take a look at the following code. The indented text is code, the rest are comments. The code for the class Container and class Child are also included. Please scroll down or take a look at the attached file. begin first code snippet ?php /* New Container object created. At the same time it sets a Child object in its $child attribute. (This is indicated by passing TRUE.) */ $testContainer1 = new Container(TRUE); /* The Container object is created, the Child object is set and its reference to the Container object is set. Now it prints $testContainer1-property and $testContainer-child-parent-property. These should have an identical value because they should be from the same object (not cloned/identical, but the same). This is the result: property = 'state 1' child-parent-property = 'state 1' So this is as expected, no problem... yet. */ $testContainer1-printState(); /* Now $testContainer1's $property property is changed into another value. /* $testContainer1-property = 'state 2'; /* Now $testContainer1-child-parent-property should also have value 'state 2', but it HAS NOT! This is the result: property = 'state 2' child-parent-property = 'state 1' Obviously $testContainer1-child-parent-property is not the same object as $testContainer1, but a clone! */ $testContainer1-printState(); ? end first code snippet Well, this is the whole problem... Why on earth isn't it a reference, while I really did assign it as a reference in the code (see class code). Now to make the whole thing even weirder, take a short look at the following code. It is almost completely the same as above, except that instead of giving the Container constructor the command to assign a Child object to the $child property, this command is given manually by calling method load() -- which is the method that Container constructor uses to load the Child object. begin second code snippet ?php /* Here the Container object is created again. But now no TRUE is passed because we don't want the Container constructor method to create and assign a Child object to the $child property. */ $testContainer2 = new Container; /* In the first code snippet load() is called from the Container constructor method. So in fact nothing has changed, except the fact that load() is called from the client scope instead of the Container object scope now. */ $testContainer2-load(); $testContainer2-printState(); $testContainer2-property = 'state 2'; /* After $property has been modified again, $testContainer2's state is printed again, and now the result is DIFFERENT!!!: property = 'loaded state 2' child-parent-property = 'loaded state 2' This is the CORRECT result!!! This is what we also expected from the first code snippet!!! And this while the executed codes are in fact identical!!! How on earth is this possible?!? */ $testContainer2-printState(); ? end second code snippet Well, this is the contradiction I wanted to show you all. I don't see the logics of it all, but ofcourse I could be missing one obvious thing... actually I hope so, because I need the construction as in the first code snippet. Below the code for the classes Container en Child. begin third code snippet ?php class Container { var $children; var $property; function Container($load = FALSE) { $this-property = 'not loaded'; if ($load) { $this-load(); } } function load() { $newChild = new Child(1); $this-add($newChild);
Re: [PHP] Weird behaviour with references to objects...
I'm not sure if my answer is going to be of much help, but I think this has to do with the way PHP handles references and copies of objects--it uses what I understand is a lazy copy mechanism, and thus the results on object manipulations can yield odd results. There was a discussion on a similar problem on PHP-DEV a while back--if you search the forums you should be able to find it. Hope this helps... Marco - php|architect -- The Monthly Magazine For PHP Professionals Come visit us on the web at http://www.phparch.com! On Thu, 2002-11-07 at 21:36, Tim Molendijk wrote: First of all I would like to say that I know this is a lot of text but I would be very pleased if you take a little time to read it nevertheless. The situation described below is not complicated at all... = Hello all, I'm dealing with this really weird problem which occurs when dealing with references within objects pointing to other objects. I'm trying to find out what it is now for a few days and I still don't get it. I minimised the code around the problem and it's weirder than ever. I would really appreciate it when you could take a look... I'm pretty experienced at PHP but perhaps you know something that I don't know. We have two different classes: Container and Child. Container objects contain a Child object in its $child property. A Child object has a $parent property, which contains a *reference* to the Container object by which it is held. So $containerObject should be the *same* as $containerObject-child-parent. To test this Container objects have a $property property. When changing this property the difference between one object and identical/cloned objects becomes visible. Now take a look at the following code. The indented text is code, the rest are comments. The code for the class Container and class Child are also included. Please scroll down or take a look at the attached file. begin first code snippet ?php /* New Container object created. At the same time it sets a Child object in its $child attribute. (This is indicated by passing TRUE.) */ $testContainer1 = new Container(TRUE); /* The Container object is created, the Child object is set and its reference to the Container object is set. Now it prints $testContainer1-property and $testContainer-child-parent-property. These should have an identical value because they should be from the same object (not cloned/identical, but the same). This is the result: property = 'state 1' child-parent-property = 'state 1' So this is as expected, no problem... yet. */ $testContainer1-printState(); /* Now $testContainer1's $property property is changed into another value. /* $testContainer1-property = 'state 2'; /* Now $testContainer1-child-parent-property should also have value 'state 2', but it HAS NOT! This is the result: property = 'state 2' child-parent-property = 'state 1' Obviously $testContainer1-child-parent-property is not the same object as $testContainer1, but a clone! */ $testContainer1-printState(); ? end first code snippet Well, this is the whole problem... Why on earth isn't it a reference, while I really did assign it as a reference in the code (see class code). Now to make the whole thing even weirder, take a short look at the following code. It is almost completely the same as above, except that instead of giving the Container constructor the command to assign a Child object to the $child property, this command is given manually by calling method load() -- which is the method that Container constructor uses to load the Child object. begin second code snippet ?php /* Here the Container object is created again. But now no TRUE is passed because we don't want the Container constructor method to create and assign a Child object to the $child property. */ $testContainer2 = new Container; /* In the first code snippet load() is called from the Container constructor method. So in fact nothing has changed, except the fact that load() is called from the client scope instead of the Container object scope now. */ $testContainer2-load(); $testContainer2-printState(); $testContainer2-property = 'state 2'; /* After $property has been modified again, $testContainer2's state is printed again, and now the result is DIFFERENT!!!: property = 'loaded state 2' child-parent-property = 'loaded state 2' This is the CORRECT result!!! This is what we also expected from the first code snippet!!! And this while the executed codes are in fact identical!!! How on earth is this possible?!? */ $testContainer2-printState(); ? end second code
Re: [PHP] Weird behaviour with references to objects...
Hi, Friday, November 8, 2002, 12:36:03 PM, you wrote: TM First of all I would like to say that I know this is a lot of text but I TM would be very pleased if you take a little time to read it nevertheless. The TM situation described below is not complicated at all... TM = TM Hello all, TM I'm dealing with this really weird problem which occurs when dealing with TM references within objects pointing to other objects. I'm trying to find out TM what it is now for a few days and I still don't get it. I minimised the code TM around the problem and it's weirder than ever. I would really appreciate it TM when you could take a look... I'm pretty experienced at PHP but perhaps you TM know something that I don't know. TM We have two different classes: Container and Child. Container objects TM contain a Child object in its $child property. A Child object has a $parent TM property, which contains a *reference* to the Container object by which it TM is held. TM So $containerObject should be the *same* as $containerObject-child-parent. TM To test this Container objects have a $property property. When changing this TM property the difference between one object and identical/cloned objects TM becomes visible. TM Now take a look at the following code. The indented text is code, the rest TM are comments. The code for the class Container and class Child are also TM included. Please scroll down or take a look at the attached file. TM begin first code snippet TM ?php TM /* New Container object created. At the same time it sets a Child object in TM its $child attribute. (This is indicated by passing TRUE.) */ TM $testContainer1 = new Container(TRUE); TM /* The Container object is created, the Child object is set and its TM reference to the Container object is set. Now it prints $testContainer1-property and $testContainer-child-parent-property. These TM should have an identical value because they should be from the same object TM (not cloned/identical, but the same). TM This is the result: TM property = 'state 1' child-parent-property = 'state 1' TM So this is as expected, no problem... yet. */ TM $testContainer1-printState(); TM /* Now $testContainer1's $property property is changed into another value. TM /* TM $testContainer1-property = 'state 2'; TM /* Now $testContainer1-child-parent-property should also have value TM 'state 2', but it HAS NOT! TM This is the result: TM property = 'state 2' child-parent-property = 'state 1' TM Obviously $testContainer1-child-parent-property is not the same object as TM $testContainer1, but a clone! */ TM $testContainer1-printState(); TM ? TM end first code snippet TM Well, this is the whole problem... Why on earth isn't it a reference, while TM I really did assign it as a reference in the code (see class code). TM Now to make the whole thing even weirder, take a short look at the following TM code. It is almost completely the same as above, except that instead of TM giving the Container constructor the command to assign a Child object to the TM $child property, this command is given manually by calling method load() -- TM which is the method that Container constructor uses to load the Child TM object. TM begin second code snippet TM ?php TM /* Here the Container object is created again. But now no TRUE is passed TM because we don't want the Container constructor method to create and assign TM a Child object to the $child property. */ TM $testContainer2 = new Container; TM /* In the first code snippet load() is called from the Container constructor TM method. So in fact nothing has changed, except the fact that load() is TM called from the client scope instead of the Container object scope now. */ TM $testContainer2-load(); TM $testContainer2-printState(); TM $testContainer2-property = 'state 2'; TM /* After $property has been modified again, $testContainer2's state is TM printed again, and now the result is DIFFERENT!!!: TM property = 'loaded state 2' child-parent-property = 'loaded state 2' TM This is the CORRECT result!!! This is what we also expected from the first TM code snippet!!! And this while the executed codes are in fact identical!!! TM How on earth is this possible?!? */ TM $testContainer2-printState(); TM ? TM end second code snippet TM Well, this is the contradiction I wanted to show you all. I don't see the TM logics of it all, but ofcourse I could be missing one obvious thing... TM actually I hope so, because I need the construction as in the first code TM snippet. TM Below the code for the classes Container en Child. TM begin third code snippet TM ?php
Re: [PHP] Weird behaviour with references to objects...
This sounds like a matter that ought to make it to the programmers who code PHP itself. In the meantime can you code around it now that you know the bug is there? Mike Marco Tabini [EMAIL PROTECTED] wrote in message news:1036725595.21741.868.camel;localhost.localdomain... I'm not sure if my answer is going to be of much help, but I think this has to do with the way PHP handles references and copies of objects--it uses what I understand is a lazy copy mechanism, and thus the results on object manipulations can yield odd results. There was a discussion on a similar problem on PHP-DEV a while back--if you search the forums you should be able to find it. Hope this helps... Marco - php|architect -- The Monthly Magazine For PHP Professionals Come visit us on the web at http://www.phparch.com! On Thu, 2002-11-07 at 21:36, Tim Molendijk wrote: First of all I would like to say that I know this is a lot of text but I would be very pleased if you take a little time to read it nevertheless. The situation described below is not complicated at all... = Hello all, I'm dealing with this really weird problem which occurs when dealing with references within objects pointing to other objects. I'm trying to find out what it is now for a few days and I still don't get it. I minimised the code around the problem and it's weirder than ever. I would really appreciate it when you could take a look... I'm pretty experienced at PHP but perhaps you know something that I don't know. We have two different classes: Container and Child. Container objects contain a Child object in its $child property. A Child object has a $parent property, which contains a *reference* to the Container object by which it is held. So $containerObject should be the *same* as $containerObject-child-parent. To test this Container objects have a $property property. When changing this property the difference between one object and identical/cloned objects becomes visible. Now take a look at the following code. The indented text is code, the rest are comments. The code for the class Container and class Child are also included. Please scroll down or take a look at the attached file. begin first code snippet ?php /* New Container object created. At the same time it sets a Child object in its $child attribute. (This is indicated by passing TRUE.) */ $testContainer1 = new Container(TRUE); /* The Container object is created, the Child object is set and its reference to the Container object is set. Now it prints $testContainer1-property and $testContainer-child-parent-property. These should have an identical value because they should be from the same object (not cloned/identical, but the same). This is the result: property = 'state 1' child-parent-property = 'state 1' So this is as expected, no problem... yet. */ $testContainer1-printState(); /* Now $testContainer1's $property property is changed into another value. /* $testContainer1-property = 'state 2'; /* Now $testContainer1-child-parent-property should also have value 'state 2', but it HAS NOT! This is the result: property = 'state 2' child-parent-property = 'state 1' Obviously $testContainer1-child-parent-property is not the same object as $testContainer1, but a clone! */ $testContainer1-printState(); ? end first code snippet Well, this is the whole problem... Why on earth isn't it a reference, while I really did assign it as a reference in the code (see class code). Now to make the whole thing even weirder, take a short look at the following code. It is almost completely the same as above, except that instead of giving the Container constructor the command to assign a Child object to the $child property, this command is given manually by calling method load() -- which is the method that Container constructor uses to load the Child object. begin second code snippet ?php /* Here the Container object is created again. But now no TRUE is passed because we don't want the Container constructor method to create and assign a Child object to the $child property. */ $testContainer2 = new Container; /* In the first code snippet load() is called from the Container constructor method. So in fact nothing has changed, except the fact that load() is called from the client scope instead of the Container object scope now. */ $testContainer2-load(); $testContainer2-printState(); $testContainer2-property = 'state 2'; /* After $property has been modified again, $testContainer2's state is printed again, and now the result is
Re: [PHP] Weird behaviour with references to objects...
Hi all, First of all, thank you for the suggestions. Actually I accidently found a solution to the problem... Not that I understand it now, I just found a way to cope with it. By changing the first line of the first code snippet: $testContainer1 = new Container(TRUE); into: $testContainer1 = new Container(TRUE); the problem is gone! Don't ask me WHY this is the solution. In my Container-add() method I assign A REFERENCE of the Container object ($this) to $child-parent so I don't see why creating the Container object by reference is useful... If anyone has additional information on this subject feel free to post! Thanks everyone! Tim. Mike Mannakee [EMAIL PROTECTED] wrote in message news:20021108044622.68446.qmail;pb1.pair.com... This sounds like a matter that ought to make it to the programmers who code PHP itself. In the meantime can you code around it now that you know the bug is there? Mike Marco Tabini [EMAIL PROTECTED] wrote in message news:1036725595.21741.868.camel;localhost.localdomain... I'm not sure if my answer is going to be of much help, but I think this has to do with the way PHP handles references and copies of objects--it uses what I understand is a lazy copy mechanism, and thus the results on object manipulations can yield odd results. There was a discussion on a similar problem on PHP-DEV a while back--if you search the forums you should be able to find it. Hope this helps... Marco - php|architect -- The Monthly Magazine For PHP Professionals Come visit us on the web at http://www.phparch.com! On Thu, 2002-11-07 at 21:36, Tim Molendijk wrote: First of all I would like to say that I know this is a lot of text but I would be very pleased if you take a little time to read it nevertheless. The situation described below is not complicated at all... = Hello all, I'm dealing with this really weird problem which occurs when dealing with references within objects pointing to other objects. I'm trying to find out what it is now for a few days and I still don't get it. I minimised the code around the problem and it's weirder than ever. I would really appreciate it when you could take a look... I'm pretty experienced at PHP but perhaps you know something that I don't know. We have two different classes: Container and Child. Container objects contain a Child object in its $child property. A Child object has a $parent property, which contains a *reference* to the Container object by which it is held. So $containerObject should be the *same* as $containerObject-child-parent. To test this Container objects have a $property property. When changing this property the difference between one object and identical/cloned objects becomes visible. Now take a look at the following code. The indented text is code, the rest are comments. The code for the class Container and class Child are also included. Please scroll down or take a look at the attached file. begin first code snippet ?php /* New Container object created. At the same time it sets a Child object in its $child attribute. (This is indicated by passing TRUE.) */ $testContainer1 = new Container(TRUE); /* The Container object is created, the Child object is set and its reference to the Container object is set. Now it prints $testContainer1-property and $testContainer-child-parent-property. These should have an identical value because they should be from the same object (not cloned/identical, but the same). This is the result: property = 'state 1' child-parent-property = 'state 1' So this is as expected, no problem... yet. */ $testContainer1-printState(); /* Now $testContainer1's $property property is changed into another value. /* $testContainer1-property = 'state 2'; /* Now $testContainer1-child-parent-property should also have value 'state 2', but it HAS NOT! This is the result: property = 'state 2' child-parent-property = 'state 1' Obviously $testContainer1-child-parent-property is not the same object as $testContainer1, but a clone! */ $testContainer1-printState(); ? end first code snippet Well, this is the whole problem... Why on earth isn't it a reference, while I really did assign it as a reference in the code (see class code). Now to make the whole thing even weirder, take a short look at the following code. It is almost completely the same as above, except that instead of giving the Container constructor the command to assign a Child object to the $child property, this command is given manually by calling method load() -- which is the method that
RE: [PHP] Weird behaviour with references to objects...
I remember reading somewhere (can't remember where though, maybe the php.net web site??) that if you use $this in a constructor (or any methods the constuctor calls), then you should instantiate the object using new otherwise you get a copy of the object that's just been created and not the actual new object (if that's not too confusing...) It's to do with the way the assignment operator works.. -Original Message- From: Tim Molendijk [mailto:tawm;wanadoo.nl] Sent: Friday, November 08, 2002 4:14 PM To: [EMAIL PROTECTED] Subject: Re: [PHP] Weird behaviour with references to objects... Hi all, First of all, thank you for the suggestions. Actually I accidently found a solution to the problem... Not that I understand it now, I just found a way to cope with it. By changing the first line of the first code snippet: $testContainer1 = new Container(TRUE); into: $testContainer1 = new Container(TRUE); the problem is gone! Don't ask me WHY this is the solution. In my Container-add() method I assign A REFERENCE of the Container object ($this) to $child-parent so I don't see why creating the Container object by reference is useful... If anyone has additional information on this subject feel free to post! Thanks everyone! Tim. Mike Mannakee [EMAIL PROTECTED] wrote in message news:20021108044622.68446.qmail;pb1.pair.com... This sounds like a matter that ought to make it to the programmers who code PHP itself. In the meantime can you code around it now that you know the bug is there? Mike Marco Tabini [EMAIL PROTECTED] wrote in message news:1036725595.21741.868.camel;localhost.localdomain... I'm not sure if my answer is going to be of much help, but I think this has to do with the way PHP handles references and copies of objects--it uses what I understand is a lazy copy mechanism, and thus the results on object manipulations can yield odd results. There was a discussion on a similar problem on PHP-DEV a while back--if you search the forums you should be able to find it. Hope this helps... Marco - php|architect -- The Monthly Magazine For PHP Professionals Come visit us on the web at http://www.phparch.com! On Thu, 2002-11-07 at 21:36, Tim Molendijk wrote: First of all I would like to say that I know this is a lot of text but I would be very pleased if you take a little time to read it nevertheless. The situation described below is not complicated at all... = Hello all, I'm dealing with this really weird problem which occurs when dealing with references within objects pointing to other objects. I'm trying to find out what it is now for a few days and I still don't get it. I minimised the code around the problem and it's weirder than ever. I would really appreciate it when you could take a look... I'm pretty experienced at PHP but perhaps you know something that I don't know. We have two different classes: Container and Child. Container objects contain a Child object in its $child property. A Child object has a $parent property, which contains a *reference* to the Container object by which it is held. So $containerObject should be the *same* as $containerObject-child-parent. To test this Container objects have a $property property. When changing this property the difference between one object and identical/cloned objects becomes visible. Now take a look at the following code. The indented text is code, the rest are comments. The code for the class Container and class Child are also included. Please scroll down or take a look at the attached file. begin first code snippet ?php /* New Container object created. At the same time it sets a Child object in its $child attribute. (This is indicated by passing TRUE.) */ $testContainer1 = new Container(TRUE); /* The Container object is created, the Child object is set and its reference to the Container object is set. Now it prints $testContainer1-property and $testContainer-child-parent-property. These should have an identical value because they should be from the same object (not cloned/identical, but the same). This is the result: property = 'state 1' child-parent-property = 'state 1' So this is as expected, no problem... yet. */ $testContainer1-printState(); /* Now $testContainer1's $property property is changed into another value. /* $testContainer1-property = 'state 2'; /* Now $testContainer1-child-parent-property should also have value 'state 2', but it HAS NOT! This is the result: property = 'state 2' child-parent-property = 'state 1' Obviously $testContainer1-child-parent-property is not the same object as $testContainer1, but a clone! */ $testContainer1