Как PHP5 работает с указателями на массивы?

ilyichzc

Новичок
Как PHP5 работает с указателями на массивы?

Есть многомерный массив, который является свойством класса. Стоит задача работать с его элементами (изменять количество элементов и значения их полей) внутри класса. Могу я методом get... вернуть указатель на элемент массива, так чтобы его содержимое не копировалось, а изменалось при изменении полей. До этого сталкивался с проблемами при передачи сложных массивов по указателям как аргументов функций.
Вот пример:

PHP:
$POINT = array(
  'x'=>0,
  'y'=>0,
  'z'=>0
)

class simpleClass 
{
    VAR $points= array();


   function newPoint($x, $y, $z)
   {
      GLOBAL $POINT;

      $id = count($this->points);
      $this->points[$id] = $POINT;
      $this->points[$id]['x'] = $x;
      $this->points[$id]['y'] = $y;
      $this->points[$id]['z'] = $z;

       return(&$this->points[$id]);  /// ----- Есть ли возможность вернуть указатель?
   }

   function createAndMove ($x, $y, $z)
   {
         $point = $this->newPoint(0, 0, 0);
        
         $point['x'] = $x;   /// --- изменятся ли значения в массиве $this->points[$id] ?
         $point['y'] = $y;
         $point['z'] = $z;
   }

}
 

cDLEON

Онанист РНРСlub
Интересная связка, классы+ глобалы...
PHP:
function &blablabla() {
 static $var;
 return $var;
}
$var=&blablabla();
$var='asdasdasd';
var_dump(blablabla());
 

Krishna

Продался Java
ilyichzc
Если уж ты пытаешься изображать ООП, то преврати точки из массива в объекты класса Point - оно на то однозначно напрашивается (не из-за ссылок, а исходя из общей логики ООП).
Заодно и проблема со ссылками разрешится, т.к. объекты по ссылке передаются.
 

autosoft

Новичок
Как PHP5 работает с указателями на массивы?
Вообще-то никак. Нет в PHP указателей. В PHP есть ссылки.

Например:
PHP:
$array = array(1, 2, 3, 4, 5);
echo $array[0]; // 1
$a = &$array[0];
$a = 'Текст';
echo $array[0]; // Текст
Если с функцией то тогда вот так:
PHP:
function &f(&$array, $index) {
    return $array[$index];
}
Например:
PHP:
$array = array(1, 2, 3, 4, 5);
echo $array[0]; // 1
$a = &f($array, 0);
$a = 'Текст';
echo $array[0]; // Текст
Вообщем вместо:
PHP:
function newPoint($x, $y, $z) 
   { 
      GLOBAL $POINT; 

      $id = count($this->points); 
      $this->points[$id] = $POINT; 
      $this->points[$id]['x'] = $x; 
      $this->points[$id]['y'] = $y; 
      $this->points[$id]['z'] = $z; 

       return(&$this->points[$id]);  /// ----- Есть ли возможность вернуть указатель? 
   }

$point = $this->newPoint(0, 0, 0);
Правильно будет написать:
PHP:
function &newPoint($x, $y, $z) 
   { 
      GLOBAL $POINT; 

      $id = count($this->points); 
      $this->points[$id] = $POINT; 
      $this->points[$id]['x'] = $x; 
      $this->points[$id]['y'] = $y; 
      $this->points[$id]['z'] = $z; 

       return($this->points[$id]);  /// ----- Есть ли возможность вернуть указатель? 
   }

$point = &$this->newPoint(0, 0, 0);
 

ilyichzc

Новичок
Спасибо. А то сколько рылся и книги есть, а нормально про ссылки не написано. Тоесть простейший Hello world из которого не понятно что происходит при передаче больших и сложных массивов в функции и методы.
Вообще встречал в одном мануале такое: "Сложные многомерные массивы PHP не передает по сылке, а копирует целиком" - это не дословная цитата.

-~{}~ 21.11.09 11:10:

Автор оригинала: Krishna
ilyichzc
Если уж ты пытаешься изображать ООП, то преврати точки из массива в объекты класса Point - оно на то однозначно напрашивается (не из-за ссылок, а исходя из общей логики ООП).
Заодно и проблема со ссылками разрешится, т.к. объекты по ссылке передаются.
С массивами решил работать т.к. приложению требуется в рантайме добавлять новые свойства в структуру (элементы в массив). Я почитал мануал по PHP и нашел работу со свойствами объектов в реальном времени слишком сложной. Если я ошибаюсь, то поправьте меня и покажите как можно в реальном времени добавить в класс или в объект новое свойство.
 

autosoft

Новичок
PHP:
class example {

    public $property_1 = 1;

    public function self_var_dump() {

        var_dump($this);
    }
}

$example = new example();

$example->self_var_dump();

$example->property_2 = 2; // Инициализация необъявленного свойства
$example->self_var_dump();
Но судя из задачи использование массивов предпочтительнее.
 

ilyichzc

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

А по поводу использования массивов хотелось бы узнать мнение опытных программистов:

Чем это плохо?
Дурной тон или как то сказывается на производительности?

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

autosoft

Новичок
Непосредственно в класс добавить новое свойство нельзя.

Для этого класс нужно переопределить:

http://ua2.php.net/manual/en/keyword.extends.php
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
ilyichzc
есть суп из кастрюли ртом тоже "предпочтительней" - мыть посуду не надо.
но почему-то так не делают

вот и глобалы с классами не мешают

объяснять почему влом: мама в детстве должна учить есть ложкой, и ООП учат не на форумах
 

ilyichzc

Новичок
Так не делают, потому что весь суп прокиснет :)
Да и вообще, когда стоит задача перебирать свойства класса и добавлять новые на лету то все сводится к приведению объкта к массиву.
А зачем тогда городить огород?
Что же касается супа и кастрюли тут конечно есть истина, но я программист, а не гувернантка и решаю практические задачи.
 

Krishna

Продался Java
Раз ты программист, то должен знать, что если хочешь получить совет по архитектуре в незнакомом языке, то надо описывать изначальную задачу, а не просить додумать свое наполовину придуманное и скорее всего неправильное архитектурное решение.
 

ilyichzc

Новичок
Автор оригинала: Krishna
Раз ты программист, то должен знать, что если хочешь получить совет по архитектуре в незнакомом языке, то надо описывать изначальную задачу, а не просить додумать свое наполовину придуманное и скорее всего неправильное архитектурное решение.
Посмотрите на тему. Там нет ни буквы об архитектуре.
 

ilyichzc

Новичок
Извиняюсь, если кого то нервирует продолжение темы с массивами и ссылками, но у меня есть еще один вопрос:

Если я сформирую внутри метода массив ссылок и верну его для последующей обработки то смогу я обращаться к данным по ссылкам-элементам этого массива.

Например:

PHP:
function getPoints($where)
{
   $result = array();

    foreach($this->points as $key=>$point)
   {
        $found = true;
       
         foreach($where as $prop=>$val)
             if ($point[$prop] != $val)
             {
                   $found = false;
                   break;
             }

        if ($found) $result[] = &$this->points[$key];
   }
    
    return($result);
}

   $points = $obj->getPoints(array('x'=>10, 'y'=>20));

    foreach ($points as $point)
   {
       $point['x'] -= 10;  // ----- Изменится ли значение в $this->points[$id] ?
    }
Заранее благодарен.
 

autosoft

Новичок
А задачка-то всё усложняется :)

Если я сформирую внутри метода массив ссылок и верну его для последующей обработки то смогу я обращаться к данным по ссылкам-элементам этого массива.
Сможеш, если исправиш код определения своей функции на следующий:

function & getPoints($where)
{
$result = array();

foreach($this->points as $key=>& $point)
{
$found = true;

foreach($where as $prop=>& $val)
if ($point[$prop] != $val)
{
$found = false;
break;
}

if ($found) $result[] = &$this->points[$key];
}

return($result);
}

$points = & $obj->getPoints(array('x'=>10, 'y'=>20));

foreach ($points as & $point)
{
$point['x'] -= 10; // ----- Изменится ли значение в $this->points[$id] ?
}

Да, и очень прошу.

Читай до полного понимания это:
http://ua2.php.net/manual/en/functions.returning-values.php (Example #3 Returning a reference from a function),
вот это:
http://ua2.php.net/manual/en/language.references.php,
и вот это:
http://ua2.php.net/manual/en/control-structures.foreach.php (ищи "As of PHP 5, you can easily modify array's elements by preceding $value with &. This will assign reference instead of copying the value.").
 
Сверху