Передача объектов по ссылкам и значениям в PHP

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

Общеизвестно, что с 5ой версии PHP все объекты передаются по ссылке. Но что же стоит за этой фразой?
Пример первый:

< ?php
session_start();
class My {
        public $i = 0;
}
 
if (isset($_SESSION['my_int'])) {
        $my_int = $_SESSION['my_int'];
} else {
        $my_int = 0;
        $_SESSION['my_int'] = $my_int;
}
if (isset($_SESSION['my_obj'])) {
        $my_obj = $_SESSION['my_obj'];
} else {
        $my_obj = new My();
        $_SESSION['my_obj'] = $my_obj;
}
echo('my_int=' . $my_int++);
echo(' my_obj.i=' . $my_obj->i++);
?>

Обновив страницу несколько раз, получаем:

my_int=0 my_obj.i=0
my_int=0 my_obj.i=1
my_int=0 my_obj.i=2

Т.е. объект сохраняется в сессии, даже при том что мы этого явно не делали. Тут все просто, $my_obj = $_SESSION[‘my_obj’]; создает в $my_obj копию идентификатора и обращение к $my_obj->i фактически равносильно $_SESSION[‘my_obj’]->i
Добиться того же эффекта с переменной можно явно присвоив значение по ссылке:

$my_int = &$_SESSION['my_int'];

Теперь при обновление страницы увеличиваться будут оба счетчика.

Возьмем менее тривиальный пример, чтобы показать, менее очевидные веши:

<?php
class A {
    public $foo = 'empty';
}
class B {
    public $foo = 'empty';
    public $bar = 'hello';
}
 
function normalAssignment($obj) {
    $obj->foo = 'changed';
    $obj = new B;
}
 
function referenceAssignment(&$obj) {
    $obj->foo = 'changed';
    $obj = new B;
}
 
$a = new A;
normalAssignment($a);
echo get_class($a), "\n";
echo "foo = {$a->foo}\n";
 
referenceAssignment($a);
echo get_class($a), "\n";
echo "foo = {$a->foo}\n";
echo "bar = {$a->bar}\n";
/*
prints:
A
foo = changed
B
foo = empty
bar = hello
*/
?>

Вывод менее очевиден, не так ли?
Под передачей по ссылке подразумевается передача копии указателя, следовательно при обращение через “->”, мы получаем доступ к внутренностям переданного объекта, тогда как “=” оперирует уже с локальной копией объекта.
Символ “&” автоматически устанавливает присваиваемой переменной идентификатор того же участка память, что и у оригинального объекта. Здесь более подходит термин “alias”. Этот алиас будет постоянным, до тех пор, пока его явно не удалить (unset($var_name)).
Вывод: в функции передаются указатели на объекты, не сами объекты. Эти указатели – копии оригиналов, до тех пор пока в параметрах функции не используется “&” – в этом случае передается оригинал.

7 Responses to “Передача объектов по ссылкам и значениям в PHP”

  1. 777 слот says:

    На выходных Я Заработал в этом лучшем казино

    Feel free to visit my homepage; 777 слот

  2. Вчера Я выиграл бабки в этом знаменитом казино

    Here is my web page – захватывающий игровой процесс – igrovieavtomati-besplatno.info,

  3. Несколько дней назад Я разбогател
    в этом современном клубе

    My website – online в режиме демо

  4. На прошлых выходных Я разбогател в
    этом знаменитом казино

    Also visit my web site – Казино Вулкан

  5. Hello, I think your site might be having browser compatibility issues.

    When I look at your blog site in Ie, it looks fine but when opening in Internet Explorer,
    it has some overlapping. I just wanted to give
    you a quick heads up! Other then that, great blog!

  6. Месяц назад Я выиграл деньги в этом
    крутом клубе

    Here is my web site – online в режиме демо

  7. На праздниках Я сорвал джекпот в этом выгодном казино

    Here is my web page: в интернете

Leave a Reply