П О Р Т А Л                            
С Е Т Е В Ы Х                          
П Р О Е К Т О В                        
  
Поиск по сайту:
                                                 
Главная

О проекте

Web-мастеру
     HTML & JavaScript
     SSI
     Perl
     PHP
     XML & XSLT
     Unix Shell

MySQL

Безопасность

Хостинг

Другое








Самое читаемое:

Учебник PHP - "Для Чайника".
Просмотров 4098 раз(а).

Иллюстрированный самоучитель по созданию сайтов.
Просмотров 6759 раз(а).

Учебник HTML.
Просмотров 3720 раз(а).

Руководство по PHP5.
Просмотров 5993 раз(а).

Хостинг через призму DNS.
Просмотров 4815 раз(а).

Подборка текстов стандартных документов.
Просмотров 56246 раз(а).

Учебник PHP - Самоучитель
Просмотров 3706 раз(а).

Документация на MySQL (учебник & справочное руководство)
Просмотров 8346 раз(а).

Внешние атаки...
Просмотров 4566 раз(а).

Учебник PHP.
Просмотров 3175 раз(а).

SSI в примерах.
Просмотров 176 раз(а).



 
 
| Добавить в избранное | Сделать стартовой | Помощь





Учебник РНР
Назад Глава 13. Классы и Объекты Вперёд

Ссылки внутри конструктора

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

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
*/

Назад Оглавление Вперёд
Магические функции
__sleep и __wakeup
ВверхСсылки. Разъяснения.


Если Вы не нашли что искали, то рекомендую воспользоваться поиском по сайту:
 





Copyright © 2005-2016 Project.Net.Ru