В PHP код методов объектов дублируется или совместно используется между экземплярами?

#php #arrays #object #methods

#php #массивы #объект #методы

Вопрос:

В PHP, если вы создаете массив объектов, копируются ли методы объекта (не элементы данных) для каждого экземпляра объекта в массиве или только один раз? Я бы предположил, что по соображениям памяти последнее верно; Я просто хотел подтвердить сообществу StackOverflow, что это правда.

Например, предположим, что у меня есть класс MyClass с несколькими методами, т.е.

 class MyClass {
    public $data1;
    private $data2;
    public function MyClass($d1, $d2) { 
        $this->data1=$d1;   $this->data2=$d2;
    }
    public function method1() {  }
    public function method2() {  }
}
  

Очевидно, что на самом деле method1() и method2() не являются пустыми функциями.
Теперь предположим, что я создаю массив этих объектов:

 $arr = array();
$arr[0] = amp; new MyClass(1,2);
$arr[1] = amp; new MyClass(3,4);
$arr[2] = amp; new MyClass(5,6);
  

Таким образом, PHP хранит в памяти три набора элементов данных для каждого из трех экземпляров объекта. Мой вопрос в том, хранит ли PHP также копии method1() и method2() (и конструктора) по 3 раза для каждого из 3 элементов $arr? Я пытаюсь решить, будет ли массив из ~ 200 объектов слишком требовательным к памяти из-за необходимости хранить 200 копий каждого метода в памяти.

Спасибо за ваше время.

Комментарии:

1. Конечно, метод по определению является ссылкой на процедуру? В этом случае механика процедуры будет определена только один раз (при загрузке класса, а не при создании экземпляра объекта), и все экземпляры будут просто указывать на эту процедуру. Это чистое предположение, но я не вижу другого способа для любого типа метода / функции, если только это не закрытие.

2. Хм. хороший вопрос. Интересно, что произойдет с любыми статическими переменными, определенными внутри этих методов. Будет ли это один статический переменный, общий для каждого экземпляра метода, или каждый экземпляр получит свой собственный уникальный статический переменный.

3. @DaveRandom В Javascript, когда вы определяете класс, методы внедряются в объект. Их содержимое не «разделяется» между экземплярами.

4. @Matthieu согласен, но Javascript — это совершенно другая игра с мячом, поскольку более или менее все в JS само по себе является объектом, включая метод. Но в равной степени это зависит от того, как вы определяете метод — если у String.prototype.methodName = function () {}; каждого строкового объекта есть вызываемый метод methodName , но не у всех есть своя собственная копия процедуры, они будут вызывать метод, которому принадлежит String.prototype . Пока вы не выполните mystr.methodName = function () {}; и не переопределите этот метод, mystr у него будет своя копия. Но для PHP (я полагаю) мое утверждение верно.

Ответ №1:

По определению (и это ваш код) функция существует только один раз. Вот почему вы создаете код (а не данные).

Однако затем вы можете использовать свой код для создания большого количества данных. Но это уже другая история ;).

Поэтому, если вы не будете без необходимости дублировать код между объектами, ваши функции будут существовать только один раз. Независимо от того, сколько экземпляров кода вы создаете. Дублируются только данные, связанные с кодом (члены класса).

Звучит справедливо?

КСТАТИ:

 $arr[0] = amp; new MyClass(1,2);
  

Выдает ошибку строгих стандартов. Вы не можете назначить ссылку / псевдоним с new ключевым словом. Вероятно, на этот способ написания влияет код PHP 4, но это изменилось с PHP 5, который представил хранилище объектов.

Комментарии:

1. «По определению, функция существует только один раз» > Нет, это не так, например, в Javascript, см. Мой ответ. Однако в PHP это верно.

2. Тогда вам следует прочитать мой комментарий… Я сказал «например». Просто вы говорите неправильное утверждение, функция не всегда существует один раз. Я думаю, что OP задал интересный вопрос, учитывая, что это не всегда один и тот же ответ в зависимости от языка, так что стоит быть «придирчивым» и точным. (и rage-downvote, если хотите, это очень зрелый)

3. Спасибо за предупреждение об ошибке строгих стандартов. Я довольно новичок в программировании на PHP5 и ценю совет.

4. Из OP: Похоже, консенсус заключается в том, что функции определяются только один раз, независимо от количества экземпляров каждого объекта. Это именно то, чего я ожидал. Спасибо всем за помощь. Кстати, прошло некоторое время с тех пор, как я публиковал сообщения на форумах Stackoverflow. Если есть способ пометить поток разрешенным, пожалуйста, дайте мне знать. Спасибо!

Ответ №2:

Содержимое метода будет сохранено в памяти только один раз. Каждый объект PHP (указанного класса) будет иметь ссылку на метод.

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

Это, например, отличается от Javascript, где каждый метод, определенный классом, содержится в каждом экземпляре. Однако, если вы определяете метод в его прототипе, тогда метод является общим для всех экземпляров класса (конечно, меньше в памяти). Смотрите эту ссылку: http://webdevelopersjournal.com/articles/jsintro3/js_begin3.html .

Комментарии:

1. То, что вы говорите о javascript, неверно. Это не работает так, как вы описываете это для всех интерпретаторов javascript, вы должны фактически указать правильное название языка и версию, где это имеет место.

2. @hakre Не могли бы вы быть более точными??