Главная Свежие Последние Лучшие Контактная информация  
 
 


Справочник языка » Ссылки внутри конструктора
Создание ссылок внутри конструктора может привести к неожиданным результатам. В этом разделе сделана попытка помочь избежать проблем.

class Foo
{
function Foo($name)
{
// создать ссылку внутри глобального массива $globalref
global $globalref;
$globalref[] = &$this;
// установить имя передаваемого значения
$this->setName($name);
// и выдать его
$this->echoName();
}

function echoName()
{
echo "<br>",$this->name;
}

function setName($name)
{
$this->name = $name;
}
}


Давайте проверим, есть ли различия между $bar1, которая создана с использованием copy = operator и $bar2, которая создана с использованием reference =& operator...

$bar1 = new Foo('set in constructor');
$bar1->echoName();
$globalref[0]->echoName();

/* вывод:
set in constructor
set in constructor
set in constructor */

$bar2 =& new Foo('set in constructor');
$bar2->echoName();
$globalref[1]->echoName();

/* вывод:
set in constructor
set in constructor
set in constructor */


Очевидной разницы нет, но фактически - очень значительная: $bar1 и $globalref[0] это _НЕ_ ссылки, это НЕ одна и та же переменная. Это из-за того, что "new" не возвращает ссылку по умолчанию, а возвращает копию.

Примечание: здесь нет потери производительности (поскольку PHP 4 и более поздние используют подсчёт ссылок) при возвращении копий вместо ссылок. Наоборот, часто намного лучше работать с копиями вместо ссылок, так как создание ссылок занимает некоторое время, а создание копий практически не требует времени (если только они не большие массивы и не изменяются последовательно одна за другой, тогда нужно использовать ссылки для изменения их всех).

Чтобы проверить то, что написано выше, давайте рассмотрим следующий код:

// теперь мы будем изменять имя. что можно ожидать?
// можно ожидать, что $bar1 и $globalref[0] изменят свои имена...
$bar1->setName('set from outside');

// как сказано ранее, это не тот случай.
$bar1->echoName();
$globalref[0]->echoName();

/* вывод:
set from outside
set in constructor */

// давайте посмотрим, что разного есть в $bar2 и в $globalref[1]
$bar2->setName('set from outside');

// к счастью, они не только равны, но это одна и та же переменная
// таким образом, $bar2->name и $globalref[1]->name это также одно и то же
$bar2->echoName();
$globalref[1]->echoName();

/* вывод:
set from outside
set from outside */


Последний пример. Попытайтесь в нём разобраться.

class A
{
function A($i)
{
$this->value = $i;
// попытайтесь понять, почему ссылка нам здесь не нужна
$this->b = new B($this);
}

function createRef()
{
$this->c = new B($this);
}

function echoValue()
{
echo "<br>","class ",get_class($this),': ',$this->value;
}
}


class B
{
function B(&$a)
{
$this->a = &$a;
}

function echoValue()
{
echo "<br>","class ",get_class($this),': ',$this->a->value;
}
}

// попытайтесь понять, почему использование простой копии здесь даст
// нежелательный результат в строке *-marked
$a =& new A(10);
$a->createRef();

$a->echoValue();
$a->b->echoValue();
$a->c->echoValue();

$a->value = 11;

$a->echoValue();
$a->b->echoValue(); // *
$a->c->echoValue();

/*
output:
class A: 10
class B: 10
class B: 10
class A: 11
class B: 11
class B: 11
*/

Добавить в закладки:

 

теги: конструктор
 

  Еще статьи
com_invoke 188
Функции Aspell 188
bzclose 59
Константы: Предопределённые константы sockets 180
Математические: bcscale 72
 


  Категории
Начнем 13
Справочник языка 89
Возможности 12
Функции 142
Расширение PHP 4.0 0
FAQ 0
 

  Теги
 

  Лучшее на сайте
Безопасность: Скрытие PHP 472
Что такое PHP? 446
Безопасность: Данные, отправляемые пользователем 373
foreach 354
Безопасность: Безопасность баз данных 334
Файл конфигурации 333
Операции: Строковые операции 311
Безопасность: CGI-двоичный 305
Безопасность: Безопасность файловой системы 298
Безопасность: Обзор 291
 

  Друзья сайта
область профнастил
автобетононасосы программа
Ноутбуки, ноутбуки Toshiba продажа
 

  Интересное
 

 
Использование материалов только при активной гиперссылке "http://iamcoder.net"
Copyright 2008 http://iamcoder.net Серия сайтов: "Стань умным!".