Understanding PHP5's Object Model

Not for 'how-to' coding questions but PHP theory instead, this forum is here for those of us who wish to learn about design aspects of programming with PHP.

Moderator: General Moderators

Post Reply
russellr
Forum Newbie
Posts: 5
Joined: Wed Apr 28, 2010 12:05 am

Understanding PHP5's Object Model

Post by russellr »

Hi,

I need some education....

Assume a function SetGlob that sets a global variable, and a function GetGlob that returns its value.

Now look at this code:

Code: Select all

// code that creates a variable called $foo
SetGlob($foo);
echo GetGlob();
// code that changes $foo
echo GetGlob();
In PHP4 it works the same regardless or whether $foo is a scalar or object. The first output and second output are identical.

In PHP5, the behaviour differs depending on whether $foo is an object or a scalar. If it's a scalar, then it works the same as PHP4. If it's an object, it works differently (different output).

Can someone please explain why that change in PHP's object model (from PHP4 to PHP5) was a good idea?

Here's the actual code along with results:

Code: Select all

<?php
class   Holder
{
    var     $value;

    function    Holder($value)
    {
        $this->value = $value;
    }
};

function    SetGlob($var)
{
    global  $GlobVar;

    $GlobVar = $var;
}

function    GetGlob()
{
    global  $GlobVar;

    if (is_object($GlobVar))
        return ($GlobVar->value);
    else
        return ($GlobVar);
}

$str = "foo";
SetGlob($str);
echo "<p>Expecting 'foo': ".GetGlob();
$str = "bar";
echo "<p>Expecting 'foo': ".GetGlob();

$foo = new Holder("foo");
SetGlob($foo);
echo "<p>Expecting 'foo': ".GetGlob();
$foo->value = "bar";
echo "<p>Expecting 'foo': ".GetGlob();
?>
Results in PHP4:

Code: Select all

Expecting 'foo': foo
Expecting 'foo': foo
Expecting 'foo': foo
Expecting 'foo': foo
Results in PHP5:

Code: Select all

Expecting 'foo': foo
Expecting 'foo': foo
Expecting 'foo': foo
Expecting 'foo': bar
How can that possibly be a sensible change to the semantics of the language?

regards,
RR
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Re: Understanding PHP5's Object Model

Post by Christopher »

russellr wrote:Can someone please explain why that change in PHP's object model (from PHP4 to PHP5) was a good idea?

How can that possibly be a sensible change to the semantics of the language?
I think there are two reasons, the first one is practical. In PHP4 you spent a lot of time passing around objects by reference because that is how you expect them to work. Which leads to the second reason -- with objects you are not so interested in the object variable itself, but the properties it contains. That is why thinking that the "semantics" of object and scalars should be the same does not hold up. The nature of objects and the tendency toward Composition and Dependency Injection have only made the distinction clearer.
(#10850)
russellr
Forum Newbie
Posts: 5
Joined: Wed Apr 28, 2010 12:05 am

Re: Understanding PHP5's Object Model

Post by russellr »

Hi,

Thanks for your reply, which I'm still trying to digest.
In PHP4 you spent a lot of time passing around objects by reference because that is how you expect them to work
No I didn't pass objects by reference a lot in PHP4, and no I didn't expect them to work that way.

I come from a C and C++ background to PHP. When I pass an object in C++ it goes as a copy (just like any other data) unless I pass it as a reference.

There are only two reasons to pass an object as a reference in C++:
1. as a const reference for data protection (the caller knows the called function can't modify the data) and efficiency (it's the same effect as a passing a copy, but a lot cheaper)
2. as a non-const reference to allow the function modify the object

Obviously, const references aren't available in PHP, so passing a copy will suffice except in circumstances where the cost is too great.
with objects you are not so interested in the object variable itself, but the properties it contains. That is why thinking that the "semantics" of object and scalars should be the same does not hold up
I don't understand what you're saying here.

A scalar variable contains data. An object contains a collection of data.

I can't see the difference. Could you clarify?

Here's another way of looking at it: an array is a collection of data. It's not that much difference from an object. So, why doesn't PHP pass arrays as references too? At least then it would be consistently inconsistent! 8O

I really am trying to understand in what way this change to PHP makes any sense whatsoever.

thanks again,
RR
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Re: Understanding PHP5's Object Model

Post by Christopher »

russellr wrote:No I didn't pass objects by reference a lot in PHP4, and no I didn't expect them to work that way.

I come from a C and C++ background to PHP. When I pass an object in C++ it goes as a copy (just like any other data) unless I pass it as a reference.
I am not going to try to convince you out of your convictions. However, I think you missed a whole generation of languages (e.g., Java, Perl, etc.) that remove a lot of the control and tedium that C/C++ required. Like them or not, they are not going away. Whether you did or did not pass by reference seems to have had little effect on the last generation of language designers who seem to agree that objects should be passed around by handle and not copied.

Whatever your opinion, if you are going to use PHP you need to embrace the spirit of the language (i.e., scripting, share nothing, etc.) to be effective in it. These decisions were arrived at through many long and heated discussions -- not lightly.
(#10850)
User avatar
PHPHorizons
Forum Contributor
Posts: 175
Joined: Mon Sep 14, 2009 11:38 pm

Re: Understanding PHP5's Object Model

Post by PHPHorizons »

I would add to that C#, which succeeds C++ does pass objects by reference by default. This is an evolution of programming languages.

Not only is passing by reference typically the expected behavior, but there is also a performance benefit. Passing objects by value all the time is expensive. Given that the vast majority of programmers expect objects to be passed by reference and the performance boost for doing so, it's a natural evolution of PHP to move in that direction.

Cheers
russellr
Forum Newbie
Posts: 5
Joined: Wed Apr 28, 2010 12:05 am

Re: Understanding PHP5's Object Model

Post by russellr »

Hi,

Thanks for the replies.

I'm trying to understand not criticize.

I'm assuming my view must be wrong and I'm trying to make sense of something that seems nonsensical to me.
These decisions were arrived at through many long and heated discussions -- not lightly.
I guess I want to see the reasons for the decisions made. I've searched and cannot find these discussions from the designers. Do you have a URL?
Passing objects by value all the time is expensive.
That's not really a good language design point. One could quite easily implement an optimization that made passing by value as inexpensive as passing by reference (I'll supply the logic if you don't believe me).

What I've got from this thread so far is basically "for whatever reason, a large number of programmers expect objects to be passed by reference, therefore it's a good idea".

A large number of people eat too much fat, drink sugary drinks, don't exercise, etc. etc. That doesn't make those things good ideas. So, that argument doesn't wash with me.

I'm looking for sensible logical reasoning.

Maybe no one actually knows the reason. :o

Maybe the answer is that Java works the same way, XYZ language works the same way, therefore PHP5 should too.

Again, that's a pretty bad reason.

Still wondering...

regards,
RR
russellr
Forum Newbie
Posts: 5
Joined: Wed Apr 28, 2010 12:05 am

Re: Understanding PHP5's Object Model

Post by russellr »

Hi,

I think I've found the answer!

http://javadude.com/articles/passbyvalue.htm

This is about Java (which I'm not very familiar with), but I'm thinking it's 100% applicable to PHP.

So, wherever he says Java, read PHP, and I think it's exactly right.

PHP's references are really like pointers in C++, with a different syntax. I know the PHP documentation says they are not pointers, but they are.

In PHP4 objects variables were sometimes treated like pointers (references) and sometimes not.

In PHP5, it's now 100% consistent. They are pointers.

That's why this code:

Code: Select all

class Dog
{
  var $Name;
  function Dog($name)
  {
    $this->Name = $name;
  }
  function GetName()
  {
    return ($this->Name);
  }
};
function Assign($p)
{
  $p = new Dog("Max");
}
$foo = new Dog("Spot");
Assign($foo);
echo $foo->GetName();
outputs "Spot", not "Max".

but this code:

Code: Select all

function AssignName($p)
{
  $p->Name = "Max";
}
AssignName($foo);
echo $foo->GetName();
outputs "Max".

This is exactly the way pointers work in C++. References in C++ don't work this way. The first example using references in C++ would output "Max".

I'm happy I understand now. :D

Thanks for being involved in the thread....if you have any other comments, I'm happy to hear them.

regards,
RR

PS I've got the equivalent C++ code to the above if anyone's interested.
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Re: Understanding PHP5's Object Model

Post by Christopher »

russellr wrote:That's not really a good language design point. One could quite easily implement an optimization that made passing by value as inexpensive as passing by reference (I'll supply the logic if you don't believe me).

What I've got from this thread so far is basically "for whatever reason, a large number of programmers expect objects to be passed by reference, therefore it's a good idea".

A large number of people eat too much fat, drink sugary drinks, don't exercise, etc. etc. That doesn't make those things good ideas. So, that argument doesn't wash with me.
This is nonsense. Calling the deigners of Java, Perl, C# etc. a bunch of people with no good reasons is just silly. Not making copies is considered the best practice -- it supports Composition, Dependency Injection, etc. which are considered preferable.
russellr wrote:PHP's references are really like pointers in C++, with a different syntax. I know the PHP documentation says they are not pointers, but they are.

In PHP4 objects variables were sometimes treated like pointers (references) and sometimes not.

In PHP5, it's now 100% consistent. They are pointers.

This is exactly the way pointers work in C++. References in C++ don't work this way. The first example using references in C++ would output "Max".
They are not pointers. You make a big mistake thinking of PHP things in C/C++ terms. Object handles are much more like file handles -- just an ID. You cannot increment them or any of the other things you can do with pointers. As I said, you need to accept PHP on its terms, much as you would like to bend your understanding of C/C++ to make sense of things.
russellr wrote:I'm happy I understand now. :D
I hope so. ;) From a PHP programmers point of view, your original criticism seemed erroneous and your new found understanding also seems erroneous.
(#10850)
russellr
Forum Newbie
Posts: 5
Joined: Wed Apr 28, 2010 12:05 am

Re: Understanding PHP5's Object Model

Post by russellr »

Hi,
This is nonsense. Calling the deigners of Java, Perl, C# etc. a bunch of people with no good reasons is just silly.
I didn't - you've misunderstood me.
They are not pointers.
Well, if you read that article and understand what it's saying I think you'll find that they are.

I think you're making the incorrect assumption that C/C++'s implementation of pointers are the only possible way of having pointers.
Object handles are much more like file handles -- just an ID.
Well, that's exactly what a pointer is.

A pointer contains an ID (usually a memory address, but doesn't have to be) that provides the "location" of a value. That ID can be copied any number of times. Every copy provides the same location to the same value.

The fact that the PHP code I've provided is identical (except for syntax details, of course) to the C++ code, is pretty conclusive.

FWIW, here is the C++ code.

Code: Select all

#include <iostream>
#include <string>

using namespace std;

class Dog
{
public:
  string    Name;

  Dog(string name)
  {
    Name = name;
  }
  string    GetName()
  {
    return (Name);
  }
};

void Assign(Dog* p)
{
  p = new Dog("Max");
}

void AssignName(Dog* p)
{
  p->Name = "Max";
}

main()
{
    Dog*    foo;

    foo = new Dog("Spot");
    Assign(foo);
    cout << foo->GetName() << endl;
    cout << "If that said 'Spot', then PHP object references are like C++ pointers" << endl;

    AssignName(foo);
    cout << foo->GetName() << endl;
    cout << "If that said 'Max', then PHP object references are like C++ pointers" << endl;
}

The bottom line is this: PHP object variable passing works exactly like C++ pointer passing.

"If it walks like a duck and quacks like duck, it's probably a duck."
They are not pointers.
OK, that's your assertion and the assertion in the PHP documentation. Can you explain in what way PHP object variables are not pointers (except for pointer arithmetic which is irrelevant)?

The point is the PHP developers have actually got this right in the change from PHP4 to PHP5.

In PHP4, the object variables worked like pointers (call them references if you want) except when they were passed as parameters to functions. That exception was plain wrong (IMHO).

In PHP5, object variables are now consistent - that exception doesn't exist.

So, I started this thread confused about why they changed the semantics from PHP4 to PHP5, and now I understand exactly. If you're going to design your language so that object variables are pointers (whatever you want to call them), then they have to be pointers consistently - not just some of the time.

The argument that "it's more efficient" is completely spurious, and, as I said before, nothing to do with the design of the language. Efficiency comes (mainly) from implementation, not from particular semantic choices in language design.

And as a last point, if you add this PHP code to my example:

Code: Select all

function RefAssign(&$p)
{
    $p = new Dog("Gypsy");
}
RefAssign($foo);
echo "<p>".$foo->GetName();
echo "<p>"."If that said 'Gypsy', then explicit references to object variables in PHP are like C++ references";
it shows that an explicit reference to an object variable is exactly like a reference in C++:

Code: Select all

void RefAssign(Dog& p)
{
  p = *(new Dog("Gypsy"));
}

// add this to main()
    RefAssign(*foo);
    cout << foo->GetName() << endl;
    cout << "If that said 'Gypsy', then explicit references to object variables in PHP are like C++ references" << endl;

regards,
RR
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Re: Understanding PHP5's Object Model

Post by Christopher »

As I said, you are trying to think of these things in your terms rather than simply embracing PHP. You can say pointers are not addresses, they are just IDs. And you can say that it does not matter that the PHP manual says that objects are not references. But by doing so you are just doing yourself a disservice. Understanding them as they are will help you down the road using PHP.

http://www.php.net/manual/en/language.o ... rences.php

As far as efficiency, there are some issues with objects related to the class size and memory use that are particular to PHP. But that is a different subject. Again, it benefits you not building a artificial model of what PHP is doing based on other languages.
(#10850)
Post Reply