Новая Объектная Модель

В PHP 5 появилась новая Объектная Модель. Работа с объектами в PHP была полностью переписана, позволяя достигнуть лучшей производительности и предоставляя новые возможности. В предыдущих версиях PHP работа с объектами производилась аналогично примитивным типам (к примеру, integer и string). Недостатком этого метода являлось то, что семантически весь объект копировался при присвоении переменной или передачи ее в качестве параметра функции. При новом подходе на объекты ссылаются по дескриптору, а не по значению (дескриптор можно представить себе как идентификатор объекта).

Многие PHP-программисты даже не в курсе хитростей механизма копирования в старой объектной модели, что означает, что большинство из PHP-приложений будут работать либо вовсе безо всяких изменений, либо с совсем небольшими изменениями.

Новая Объектная модель задокументирована в Справочнике по языку.

Обратите внимание также на директиву zend.ze1_compatibility_mode для совместимости с PHP 4.



Новая Объектная Модель
quinn at strangecode dot com
19-May-2006 08:53
Here is another possible solution for migrating code to php 5 when using $this = 'something' reassignments. In my case, I had several classes  with methods that were self-instantiating with static calls. I was able to simply use a different variable: I changed $this to $_this and it worked the same because I copied an instance of the original object by reference using an instantiation factory method:

class DB {
   function &getInstance()
   {
       static $instance = null;

       if ($instance === null) {
           $instance = new DB();
       }

       return $instance;
   }
   ...

In every method needing access to this object I assigned it to a temporary variable by reference:
  
   function doSomething ()
   {
       $_this =& DB::getInstance();

       $_this->doSomethingElse();
       $_this->param['id'] = 123;
   }

Which allows method calls or saving data back to the original object.

I originally created classes like this so I didn't need to keep track of instantiations or global objects. I could just call DB::doSomething() and the object is created dynamically or referenced from an already existing object.
riseofthethorax at yahooo dot com
28-Sep-2005 06:53
I actually understand the addressing modes in 4.3 and use them, it hasn't bothered me.. Like I have objects within objects, each with variables containing references (like pointers but without the pointer arithmetic).  I can obtain an object group from the database, obtain the method interface to a subobject, issue a manipulation through the child, then store the object group back into the database with the manipulation intact.. I'm not sure what effect the new changes will have on this, but if its drastic, I'm not sure I can support 5.0.

A nice little userlevel way of messing with PHP's addressing,
the use of aliases:

// I haven't coded in PHP for a while so sue me
class stuff {
   var $stuff;
   function stuffer() {
     $null = NULL;
     $s = &$this->stuff;
     $s = "some stuff";
     $s = &$null;
   }
}

This works.. You can make some assumptions about
what is going on behind the scenes, especially
what $s is before being assigned a reference to
another variable and after.. Its either two kinds of things,
a reference to a variable or a container of data, or
its a reference to a data location at all times, just that by default it gets an address to a string and at other times it can be assigned the address of objects. The "&" redirects where its pointing. At least this is how I think about it.
I use this side-effect all the time for making aliases in my objects..

Kiernan
hairmare-spam at purplehaze dot ch
10-Jun-2005 04:41
I have noted some discussion going on about the 'Cannot re-assign $this' error.

The most simple way to reproduce the error is:

class MyObject
{
       function test()
       {
               $this = new MyObject;
       }
}

I found the following quote (quoting zend.com) on php-dev:
  http://www.zend.com/php/ask_experts.php :

  "The fact that you could change in PHP 4, was never really meant to be
  although it worked. In PHP 5 we removed this option due to performance
  and semantic reasons. In PHP 5, you can either use a factory method
  pattern or throw an exception on error in the constructor."

This statement implies that the error lies not in PHP5 but in the script. A Bogus Bug in http://bugs.php.net/bug.php?id=27659 tells me the same thing.

There has been some discussion on how to migrate such code to php5 without having to reengineer the whole App. From my point of view the following solutions are viable:

1. Use delegation & Object composition:

$this->Object = new Whatever();

function nameOfFunction()
{
     return $this->Object->nameOfFunction();
}

This requires lots of code rewriting. Some of it could be realised with overloading. Variables would need to get overloaded or could only be accessed using a getter/setter. As a xtra you get clean OO Code!

2. Replace Original Objects Content:

foreach (get_object_vars($foo) as $key => $value)
  $this->$key = $value;

This solution only works with instance-variables. Additional classkit/runkit code would be needed to get everything else correct. This way less refactoring would be needed. This could be the right way to go if you don't need to replace any methods or the classname.

I haven't decided wich way to go. I wrote this so the next hacker with this problem finds some info where I was looking for it.
ivanildo at kowsoleea.de
23-May-2005 02:56
It seems that simpleXML functions like 'simplexml_load_file' do not work in ze1 compatibility mode due to some cloning 'features' I do not yet understand.

<Базы данныхСообщения об ошибках>
 Last updated: Tue, 15 Nov 2005