{"id":862,"date":"2004-07-15T15:53:19","date_gmt":"2004-07-15T19:53:19","guid":{"rendered":"\/?p=862"},"modified":"2015-06-19T13:13:24","modified_gmt":"2015-06-19T17:13:24","slug":"php-5-object-references","status":"publish","type":"post","link":"https:\/\/mjtsai.com\/blog\/2004\/07\/15\/php-5-object-references\/","title":{"rendered":"PHP 5 Object References"},"content":{"rendered":"<p>\r\n<a href=\"http:\/\/www.php.net\">PHP 5<\/a> seems to mostly fix the most\r\nglaring problem in PHP 4, its non-intuitive handling of references.\r\nHowever, this issue is more complicated than it sounds. For starters,\r\nhere is one of the unit tests from PHP 5:\r\n<\/p>\r\n\r\n<pre>\r\n&lt;?php\r\n\r\nclass Foo {\r\n    var $name;\r\n    \r\n    function Foo() {\r\n        $this-&gt;name = \"I'm Foo!&#92;n\";\r\n    }\r\n}\r\n\r\n$foo = new Foo;\r\necho $foo-&gt;name;\r\n$bar = $foo;\r\n$bar-&gt;name = \"I'm Bar!&#92;n\";\r\n\r\n\/\/ In ZE1, we would expect \"I'm Foo!\"\r\necho $foo-&gt;name;\r\n\r\n?&gt;\r\n<\/pre>\r\n\r\n<p>\r\nWith PHP 4, this prints:\r\n<\/p>\r\n\r\n<pre>\r\nI'm Foo!\r\nI'm Foo!\r\n<\/pre>\r\n\r\n<p>\r\nWith PHP 5, it prints:\r\n<\/p>\r\n\r\n<pre>\r\nI'm Foo!\r\nI'm Bar!\r\n<\/pre>\r\n\r\n<p>\r\nTo get this result in PHP 4, you need to use the <code>&amp;<\/code> operator:\r\n<\/p>\r\n\r\n<pre>\r\n&lt;?php\r\n\r\nclass Foo {\r\n    var $name;\r\n    \r\n    function Foo() {\r\n        $this-&gt;name = \"I'm Foo!&#92;n\";\r\n    }\r\n}\r\n\r\n$foo = new Foo;\r\necho $foo-&gt;name;\r\n<em>$bar = &amp;$foo;<\/em>\r\n$bar-&gt;name = \"I'm Bar!&#92;n\";\r\n\r\n\/\/ In ZE1, we would expect \"I'm Foo!\"\r\necho $foo-&gt;name;\r\n\r\n?&gt;\r\n<\/pre>\r\n\r\n<p>\r\nThis is because PHP 4 copies objects by default; using <code>&amp;<\/code>\r\nmakes it assign by reference instead of by copy. Copying by default is\r\npretty annoying if you&rsquo;re used to other languages, but it does have the\r\nvirtue of consistency. Assignment without <code>&amp;<\/code> copies for\r\nboth scalars and objects; assignment with <code>&amp;<\/code> uses\r\nreferences for both scalars and objects.\r\n<\/p>\r\n\r\n<p>\r\nI&rsquo;ve had trouble pinning down exactly how PHP 5 changes this. As far as\r\nI can tell, object references are not mentioned in the official <a\r\nhref=\"http:\/\/www.php.net\/ChangeLog-5.php\">PHP 5 ChangeLog<\/a>. One <a href=\"http:\/\/www.sitepoint.com\/print\/1192\">article<\/a> I found says this:\r\n<\/p>\r\n\r\n<blockquote cite=\"http:\/\/www.sitepoint.com\/print\/1192\">\r\n<p>\r\nIn PHP4, references were a subject of confusion, the default behaviour,\r\nwhen passing objects around, being to copy rather than reference the\r\nobject.\r\n<\/p>\r\n\r\n<p>\r\nWith PHP5 the default behaviour is now to pass objects by reference\r\n(using the same approach as Java, in other words). What does this mean\r\nto you, the developer? Well, if you didn't understand how references\r\nworked in PHP4, you can now pretty much forget the subject completely.\r\n<\/p>\r\n<\/blockquote>\r\n\r\n<p>\r\nBut I find this confusing because the most confusing aspect of PHP 4 \r\nreferences goes unmentioned. In PHP 4, this code:\r\n<\/p>\r\n\r\n<pre>\r\n&lt;?php\r\n\r\nclass Label {\r\n    var $text;\r\n    function Label($text) {\r\n        $this-&gt;text = $text;\r\n    }\r\n}\r\n\r\n$foo = new Label(\"foo\");\r\n$bar =&amp; $foo;\r\n$bar = new Label(\"bar\");\r\nprint_r($foo);\r\n\r\n?&gt;\r\n<\/pre>\r\n\r\n<p>\r\nprints:\r\n<\/p>\r\n\r\n<pre>\r\nlabel Object\r\n(\r\n    [text] =&gt; <em>bar<\/em>\r\n)\r\n<\/pre>\r\n\r\n<p>\r\nThis odd result is <a href=\"http:\/\/us3.php.net\/manual\/en\/language.references.php\">explained<\/a> by the PHP manual thusly:\r\n<\/p>\r\n\r\n<blockquote cite=\"http:\/\/us3.php.net\/manual\/en\/language.references.php\">\r\nReferences in PHP are a means to access the same variable content by\r\ndifferent names. They are not like C pointers, they are symbol  table\r\naliases. Note that in PHP, variable name and variable content are\r\ndifferent, so the same content can have different names.  The most\r\nclose analogy is with Unix filenames and files -  variable names are\r\ndirectory entries, while variable contents is  the file itself.\r\nReferences can be thought of as hardlinking in  Unix filesystem.\r\n<\/blockquote>\r\n\r\n<p>\r\nAs noted, in PHP 4 objects and scalars were treated alike, hence this <a href=\"http:\/\/us3.php.net\/manual\/en\/language.references.whatdo.php\">other example<\/a> from the PHP manual:\r\n<\/p>\r\n\r\n<pre>\r\n$a = 1; \r\n$b =&amp; $a; \r\n$b = 2; \r\nprint \"$a $b\";\r\n\/\/ 2 2\r\n<\/pre>\r\n\r\n<p>\r\nWhen I first read about PHP 5, I thought that it made <code>&amp;<\/code> \r\nimplicit for objects. In other words, I thought that: \r\n<\/p> \r\n\r\n<pre>\r\n&lt;?php\r\n\r\nclass Label {\r\n    var $text;\r\n    function Label($text) {\r\n        $this-&gt;text = $text;\r\n    }\r\n}\r\n\r\n$foo = new Label(\"foo\");\r\n$bar = $foo;\r\n$bar = new Label(\"bar\");\r\nprint_r($foo);\r\n\r\n?&gt;\r\n<\/pre>\r\n\r\n<p>\r\nwould print:\r\n<\/p>\r\n\r\n<pre>\r\nlabel Object\r\n(\r\n    [text] =&gt; <em>bar<\/em>\r\n)\r\n<\/pre>\r\n\r\n<p>\r\nin PHP 5. I thought this because I kept reading that you don&rsquo;t have to type <code>&amp;<\/code> in PHP 5. However, it now appears that I was wrong. My tests with the just-released PHP 5 show that <code>&amp;<\/code> works in the same, arguably broken, &ldquo;hardlink&rdquo; kind of way with both PHP 4 and PHP 5. The difference is that in PHP 4, if you don&rsquo;t use <code>&amp;<\/code>, a copy of the object is made. In PHP 5, if you don&rsquo;t use <code>&amp;<\/code>, a Java-style reference is used. Thus, this code:\r\n<\/p>\r\n \r\n<pre>\r\n&lt;?php\r\n\r\nclass Label {\r\n    var $text;\r\n    function Label($text) {\r\n        $this-&gt;text = $text;\r\n    }\r\n}\r\n\r\n$foo = new Label(\"foo\");\r\n$bar = $foo;\r\n$bar = new Label(\"bar\");\r\nprint_r($foo);\r\n\r\n?&gt;\r\n<\/pre>\r\n\r\n<p>\r\nprints:\r\n<\/p>\r\n\r\n<pre>\r\nlabel Object\r\n(\r\n    [text] =&gt; <em>foo<\/em>\r\n)\r\n<\/pre>\r\n\r\n<p>\r\nin both PHP 4 and PHP 5. And this code:\r\n<\/p>\r\n\r\n<pre>\r\n&lt;?php\r\n\r\nclass Label {\r\n    var $text;\r\n    function Label($text) {\r\n        $this-&gt;text = $text;\r\n    }\r\n}\r\n\r\n$foo = new Label(\"foo\");\r\n$bar =&amp; $foo;\r\n$bar = new Label(\"bar\");\r\nprint_r($foo);\r\n\r\n?&gt;\r\n<\/pre>\r\n\r\n<p>\r\nprints:\r\n<\/p>\r\n\r\n<pre>\r\nlabel Object\r\n(\r\n    [text] =&gt; <em>bar<\/em>\r\n)\r\n<\/pre>\r\n\r\n<p>\r\nin both PHP 4 and PHP 5.\r\n<\/p>\r\n\r\n<p> The bad news is that PHP 5 is in some sense less consistent than before. There are now three different kinds of assignment (copy, hardlink, and reference copy), and scalars and objects are now treated differently. The good news is that, if I understand this correctly, you can banish <code>&amp;<\/code> from all your PHP 5 code and then use it like Java.\r\n<\/p>","protected":false},"excerpt":{"rendered":"<p>PHP 5 seems to mostly fix the most glaring problem in PHP 4, its non-intuitive handling of references. However, this issue is more complicated than it sounds. For starters, here is one of the unit tests from PHP 5: &lt;?php class Foo { var $name; function Foo() { $this-&gt;name = \"I'm Foo!&#92;n\"; } } $foo [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"apple_news_api_created_at":"","apple_news_api_id":"","apple_news_api_modified_at":"","apple_news_api_revision":"","apple_news_api_share_url":"","apple_news_coverimage":0,"apple_news_coverimage_caption":"","apple_news_is_hidden":false,"apple_news_is_paid":false,"apple_news_is_preview":false,"apple_news_is_sponsored":false,"apple_news_maturity_rating":"","apple_news_metadata":"\"\"","apple_news_pullquote":"","apple_news_pullquote_position":"","apple_news_slug":"","apple_news_sections":"\"\"","apple_news_suppress_video_url":false,"apple_news_use_image_component":false,"footnotes":""},"categories":[4],"tags":[46,359,71,1227],"class_list":["post-862","post","type-post","status-publish","format-standard","hentry","category-programming-category","tag-languagedesign","tag-php","tag-programming","tag-top-posts"],"apple_news_notices":[],"_links":{"self":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/862","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/comments?post=862"}],"version-history":[{"count":3,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/862\/revisions"}],"predecessor-version":[{"id":11527,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/862\/revisions\/11527"}],"wp:attachment":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/media?parent=862"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/categories?post=862"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/tags?post=862"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}