Переменные и ссылки

mani13

Новичок
StUV
меня, как человека, находящийся в свободном полёте и кодящем по настроению на чём попало по настроению, PHP всё больше смешит)
Например, в 5ой версии по умолчанию при присвоении объект передаётся по ссылке, а копируется -- все типа копируются, а объект -- нет.
Или вот ещё -- можно указать, что на входе нужна переменная, являющаяся экземпляром класса либо массивом... А остальные типа почему обделены?) Ну, с объектом можно понять -- они вообще где-то отдельно -- а вот массивы на каком основании?)
 

StUV

Rotaredom
mani13
хм...
имхо - пхп это в первую очередь средство, сильно упрощающее жизнь разработчика определенного класса задач веба...
и он не должен "уметь" делать что-то еще

как я уже где-то писал, есть люди делающие сайты полностью на С - это их право...

если вспомнить каким был пхп 3.х - то 5-ая версия просто супер
без вопросов =)))
 

StUV

Rotaredom
сейчас существует масса библиотек практически для любого ЯП, позволяющих писать под веб

хочешь - пиши длл на ObjectPascal (delphi), хочешь - хоть на фортран95
вопрос только в целесообразности

-~{}~ 24.07.06 15:15:

я своим студентам говорил - выполненные задачи принимаются на любом ЯП, кроме асм-подобных и машинных кодов

типа - "если вы сделаете решение на неизвестном мне языке - сложность задач позволяет мне разобраться в этом коде за 10-15 минут"

нормальный программист (или адекватно мыслящий студент-не_ламер, но будущий программист) всегда выберет из известных ему ЯП именно тот, который наиболее соответствует задаче

отсюда однозначно ясен "интеллектуальный уровень индивида", когда он зная паскаль и С пишет мне сортировку пузырьком на VBA с формами и кнопочками....

=)))
 

mani13

Новичок
StUV
Мы здесь не об этом.

Мы здесь рассуждаем о том, что такое ссылка)

Вообще, чисто философски получается, что в PHP с переменными такая картина:
существует куча кусков памяти, в которых хранятся значения
и
существует куча переменных, которые указывают на эти куски, притом:
1. если существует одна переменная, указывающая на данный кусок памяти, то при присвоении значение копируется
2. а вот если существует несколько переменных, указывающих на данный кусок, то ВСЕ эти переменные -- ссылки, а они при присвоении НЕ копируются

Это так, если рассматривать без объектов.

P.S.: Stuv, если пошла речь про всё остальное, то, вообщем-то, для веба если и выберу то Django(Python)/RoR(Ruby, знать бы его) ), я не такой маньяк, чтобы на компилируемых языках писать) Хотя бы в силу необходимости в случае чего перекомпилировать.

-~{}~ 24.07.06 15:23:

Картина такая, если брать, что subj топика есть нормальное поведение интерпретатора.
 

StUV

Rotaredom
mani13
хм...

PHP:
$a = 1;
$b = 2;

$c = &$b;
$a = &$b;

$d = $c;

$d = 3;

var_dump($b);

$d = &$c;

$d = 4;

var_dump($b);
-------------------------------------
usr/local/bin/php ~/1.php
int(2)
int(4)
-------------------------------------

имхо, вполне естественное поведение...
или ты о чем-то другом ?
 

VTK

Новичок
По-моему тема периодически уходит не туда. Собственно сейчас передо мной нет технической проблемы, просто мне интересны подобные ситуации. Кстати в следующем коде с $a[ 0 ] ничего не происходит:
PHP:
    function b( & $var )
    {
        $b = & $var;
    }

    $a = array( 1 );
    $c = $a;
    $c[ 0 ] = 2;
    var_dump( $a );

    b( $a[ 0 ] );
    $c = $a;
    $c[ 0 ] = 2;
    var_dump( $a );
Получается, что само по себе создание второй ссылки на переменную не превращает эту переменную в ссылку ( $a[ 0 ] ), что могло бы следовать из первого примера.

Ситуация эта из жизни, просто она показана в максимальном упрощении. На самом деле есть класс для работы с шаблоном и он, анализируя HTML, строит дерево с рекурсивными ссылками, которое представляет структуру вложенных тегов типа <TMPL_LOOP …>. И это самое дерево становится ссылкой, то есть, если я скопирую объект этого класса, то дерево разбора у них окажется одно и тоже (что в принципе логично. если бы язык позволял копировать рекурсивные деревья, то проблем бы стало еще больше ). Вот (опять же упрощеный) пример:
PHP:
    class A {
        var $array1 = array();
        var $array2 = array();

        function f( & $array, $n )
        {
            $array[ 'child1' ] = array( 'item' => '1' );
            if ( $n ) {
                $item = $this->f( $array[ 'children' ], $n - 1 );
                $item[ 'parent' ] = & $array;
                $array[ 'child1' ] = $item;
            }
            return array( 'item' => '2' );
        }

        function b()
        {
            $this->f( $this->array1, 0 );
            $this->f( $this->array2, 1 );
        }
    }

    $a = new A();
    $a->b();
    var_dump( $a->array1[ 'child1' ][ 'item' ] );
    var_dump( $a->array2[ 'child1' ][ 'item' ] );
    $b = $a;
    $b->array1 = null;
    $b->array2 = null;
    var_dump( $a->array1[ 'child1' ][ 'item' ] );
    var_dump( $a->array2[ 'child1' ][ 'item' ] );
Какой думаете будет результат?
Код:
string(1) "1"
string(1) "2"
string(1) "1"
NULL
-~{}~ 24.07.06 15:53:

Гравицапа, спасибо за ссылку (правда пока полностью не заробрался).
 

StUV

Rotaredom
VTK
хм...

php ~/1.php

string(1) "1"
string(1) "2"
NULL
NULL

код копипастил...

-~{}~ 24.07.06 16:06:

VTK
объясни без примеров - чего ты хочеь добиться?

если нужны два идентичных связанных дерева - инициализируй узлы ссылками, если различные - инициализируй значениями...

что в этом сложного и непонятного ?

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

mani13

Новичок
StUV
Я все пою про код в первом посте.
PHP:
$a = array(1);
$c = $a;
$c[0] = 2;
var_dump($a, $c);

$b = &$a[0];
$c = $a;
$c[0] = 2;
var_dump($a, $c);
Итого на практике:
Код:
array(1) {
  [0]=>
  int(1)
}
array(1) {
  [0]=>
  int(2)
}
array(1) {
  [0]=>
  &int(2)
}
array(1) {
  [0]=>
  &int(2)
}
То есть в массиве $a, а, после присвоения, и в $c появляется ссылка.
Тогда как ожидается, что $b будет вести на $a[0], а $a[0] будет представлять собой неСсылку.
То есть после копирования и последующего присвоения будет $a = array(1), а $c = array(2).
Откуда она там?
* интерес уже чисто спортивный...
Версия PHP: PHP 5.1.4-pl4-gentoo

-~{}~ 24.07.06 17:00:

Всё, после медитирования я понял почему это происходит и почему это не бага)
 

VTK

Новичок
StUV
Добиться я ничего не хочу. Просто поведение мне кажется явно не ожидаемое, а поэтому хотел узнать сталкивался ли кто-нибудь с подобным или может кому просто интересно будет.
Постараюсь как можно раньше проверить все это в пятой версии, но пока нет возможности.

-~{}~ 24.07.06 17:06:

mani13
Можешь поделиться откровением?
 

mani13

Новичок
mani13
Можешь поделиться откровением?
Легко.
Что есть
PHP:
$a = array(1);
$b = &$a[0];
$c = $a;
$c[0] = 2;
и чем оно отличается от
PHP:
$a = 1;
$b = &$a;
$c = $a;
$c = 2;
?

Разъясняю что и как происходит.
PHP:
$b = &$a;
После этого мы получаем, $a и $b указывают на один и тот же кусок памяти($a и $b являются "ссылками" друг на друга).
НО:
PHP:
$c = $a;
В своей сути есть КОПИРОВАНИЕ.
То есть в $c копируется значение $a.

В первом же случае после
PHP:
$b = &$a[0];
ОБА элемента являются ссылками.
Далее, копирование:
PHP:
$c = $a;
Копирование массивов является довольно специфичным, по этому поводу даже есть замечание в мануале:
Замечание: При копировании массива ссылок, они не разыменовываются. Это также касается массивов, передаваемых функциям по значению.
Что сие значит?
А значит то, что если в массиве была ссылка, то после копирования этот элемент остаётся ссылкой.
Итого имеем, что $a[0] является ссылкой, следовательно, после копирования $c[0] тоже ссылка.
 
Сверху