Форум программистов, компьютерный форум, киберфорум
Наши страницы

PHP для начинающих

Войти
Регистрация
Восстановить пароль
 
 
mikello
0 / 6 / 0
Регистрация: 19.11.2017
Сообщений: 173
#1

Контейнер zval - PHP

16.05.2018, 20:32. Просмотров 259. Ответов 15
Метки нет (Все метки)

Есть следующий код:

$foo = "asd";
$bar = $foo;
$zxc = &$foo;
$qwe = $foo;
В виде контейнеров zval будет так:

zxc,foo: {
type: string,
value:
str:
val: "asd"
len: 3
is_ref: 1
refcount: 2
}

bar: { // переменная выделена в отдельный zval
type: string,
value:
str:
val: "asd"
len: 3
is_ref: 0
refcount: 1
}

qwe: { // переменная выделена в отдельный zval
type: string,
value:
str:
val: "asd"
len: 3
is_ref: 0
refcount: 1
}
Вопрос - почему bar и qwe были выделены в отдельные zval?
(есть соображения по поводу bar - после $zxc = &$foo; состояние контейнера изменилось, следовательно bar был выделен в отдельный zval.)
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
16.05.2018, 20:32
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Контейнер zval (PHP):

Преход в контейнер - PHP
Верстаю сайт для курсовика), так как зданий не достаточно я решил делать с помощью фрэймов, потом, после просмотра данной работы учителя...

Из страницы взять div-контейнер и вывести его у - PHP
Собственно.. не поленился.. прочитал первые 11 страниц.. толкового ответа не нашел.. решил создать тему. Имеется страница, там куча...

При выборе radioButton вывод в контейнер Div текст - PHP
Здравствуйте, люди добрые! Пожалуйста помогите:), а то я уже к соседям стену головой пробил:wall:. Как сделать так, что бы при выборе html...

контейнер - C++
Создать контейнер, в который можно добавлять и удалять методы. Размер контейнера должен увеличиваться автоматически. Вот такое задание ,...

Контейнер - C++ Builder
Необходимо реализовать контейнер... с формой. Не знаю даже с чего начать, ну тоесть как описать класс контейнер.

Контейнер - HTML, CSS
Здравствуйте, вопрос таков. Как можно сделать так что бы контейнер который имеет position: relative; не становился минимального размера...

15
Azdeman
Фрилансер
Эксперт HTML/CSSЭксперт PHP
1734 / 1277 / 349
Регистрация: 12.01.2011
Сообщений: 5,068
16.05.2018, 21:50 #2
Потому что в первом случае 2 переменные указывают на одно и то же значение так как вы поставили (ссылку) &$foo
При $bar = $foo вы просто берете копию $foo и записываете в $bar, это 2 разные переменные и обращаются они к разному участку памяти.
1
mikello
0 / 6 / 0
Регистрация: 19.11.2017
Сообщений: 173
16.05.2018, 23:01  [ТС] #3
Azdeman,

При $bar = $foo вы просто берете копию $foo и записываете в $bar, это 2 разные переменные и обращаются они к разному участку памяти.
Как я понял, $bar и $foo ссылаются не на один и тот же контейнер zval?

Тогда почему в примере:

$foo="asd";
$bar=$foo;
переменные ссылаются на один и тот же контейнер?
0
Jewbacabra
Эксперт PHP
2965 / 2552 / 951
Регистрация: 24.04.2014
Сообщений: 7,800
16.05.2018, 23:05 #4
mikello, версия php?
0
mikello
0 / 6 / 0
Регистрация: 19.11.2017
Сообщений: 173
16.05.2018, 23:36  [ТС] #5
Jewbacabra, пример из туториала 2012 года. У себя не тестировал.

Azdeman,

При $bar = $foo вы просто берете копию $foo и записываете в $bar, это 2 разные переменные и обращаются они к разному участку памяти.
В статье написано следующее:

В случае же обычного присваивания для новой переменной создаётся отдельный контейнер, который является копией первого. На самом деле в целях оптимизации памяти копирование происходит только при изменении одной из переменных, а пока они равны обе переменные ссылаются на одну область памяти.
0
Jewbacabra
Эксперт PHP
2965 / 2552 / 951
Регистрация: 24.04.2014
Сообщений: 7,800
17.05.2018, 00:22 #6
Цитата Сообщение от mikello Посмотреть сообщение
пример из туториала 2012 года. У себя не тестировал.
В php 7 были пересмотрены многие момениы в реализации zval. Версия может оказать сильное влияние на результат
0
mikello
0 / 6 / 0
Регистрация: 19.11.2017
Сообщений: 173
17.05.2018, 01:16  [ТС] #7
Jewbacabra, протестировал на php7:

$foo = "asd";
$bar = $foo;
$zxc = &$foo;

xdebug_debug_zval('foo');
xdebug_debug_zval('bar');
Получил результат:

foo:
(refcount=2, is_ref=1)string 'asd' (length=3)

bar:
(refcount=2, is_ref=0)string 'asd' (length=3)

Почему у foo refcount 2, а не 3 (если у bar refcount 2)? (в примере из 1ого поста у bar refcount 1)
0
Jewbacabra
Эксперт PHP
2965 / 2552 / 951
Регистрация: 24.04.2014
Сообщений: 7,800
17.05.2018, 01:31 #8
У меня так получается
Код
foo: (refcount=2, is_ref=1)='test'
bar: (refcount=0, is_ref=0)='test'
zxc: (refcount=2, is_ref=1)='test'
на 7.2 и 7.1
0
mikello
0 / 6 / 0
Регистрация: 19.11.2017
Сообщений: 173
17.05.2018, 01:41  [ТС] #9
Jewbacabra, при refcount=0 ( как у вас в коде) сборщик мусора освобождает память, занимаемую данным контейнером, так как нет переменных, которые на него ссылаются.

Как тогда понять принцип работы с контейнерами, если разные версии php выдают разный результат? Должна же быть какая-то логика во всем этом.

И как могут разные переменные($bar=$foo) ссылаться на один и тот же контейнер, если Azdeman пишет:

При $bar = $foo вы просто берете копию $foo и записываете в $bar, это 2 разные переменные и обращаются они к разному участку памяти.
Контейнер - это и есть участок памяти.
0
Jewbacabra
Эксперт PHP
2965 / 2552 / 951
Регистрация: 24.04.2014
Сообщений: 7,800
17.05.2018, 01:57 #10
Цитата Сообщение от mikello Посмотреть сообщение
как тогда понять принцип работы с контейнерами, если разные версии php выдают разный результат?
Результат выполнения данного кода во всех версиях будет одинаков. Внутри может быть реальзовано по-разному.
Цитата Сообщение от mikello Посмотреть сообщение
Должна же быть какая-то логика во всем этом.
Исходный код php открыт, реализацию впринципе можно посмотреть
Цитата Сообщение от mikello Посмотреть сообщение
И как могут разные переменные($bar=$foo) ссылаться на один и тот же контейнер
Логически с точки зрения программиста php это разные переменные, убедиться в этом можно изменив значение одной из переменных. Но постоянное копирование переменных может быть затратным по ресурсам (особенно передача больших массивов в функцию). Поэтому использеутся так называемый copy-on-write, когда физически копирование откладывается до изменения одной из переменных. В php 5 реализация этого механизма была проще, но менее эффективна. В 7 ее пересмотрели в сторону большей эффективности, что несколько усложнило логику, например copy-on-write не будет применен для целых чисел, так как смысла в этом нет. Но с точки зрения программиста который пишет код на php результат будет одинаковым
1
mikello
0 / 6 / 0
Регистрация: 19.11.2017
Сообщений: 173
17.05.2018, 17:00  [ТС] #11
Разобрался =) Всем спасибо =)

Добавлено через 6 часов 48 минут
Jewbacabra,

Логически с точки зрения программиста php это разные переменные, убедиться в этом можно изменив значение одной из переменных.
Согласен с этим. Но как быть с тем, что обе переменные ссылаются на один и тот же контейнер? (это видно из результатов работы кода на PHP 7 и ранних версий)

Если рассмотреть следующий код:

$a=1;
$b=$a;
Здесь $a и $b ссылаются на один и тот же контейнер. При этом это разные переменные.

Разобрался, как php работает с контейнерами, но не очень понимаю, как разные переменные ссылаются на один и тот же контейнер, если эти переменные ($a и $b) в памяти находятся на разных участках?
0
Jewbacabra
Эксперт PHP
2965 / 2552 / 951
Регистрация: 24.04.2014
Сообщений: 7,800
17.05.2018, 17:39 #12
mikello, а теперь попробуй поменять значение одной из двух переменных и посмотреть что получится
0
mikello
0 / 6 / 0
Регистрация: 19.11.2017
Сообщений: 173
17.05.2018, 17:43  [ТС] #13
Jewbacabra, поменял. Получил 2 контейнера.
0
Jewbacabra
Эксперт PHP
2965 / 2552 / 951
Регистрация: 24.04.2014
Сообщений: 7,800
17.05.2018, 17:51 #14
mikello, это и есть copy-on-write. Создание нового "контейнера" откладывается до тех пор, пока в этом не появится необходимость
0
mikello
0 / 6 / 0
Регистрация: 19.11.2017
Сообщений: 173
17.05.2018, 18:21  [ТС] #15
Jewbacabra, мне это понятно отлично =)

А непонятно другое - как именно переменные представлены в памяти: переменную представляет контейнер. В примере выше 2 переменные на этапе их инициализации (до их изменений) представлены одним контейнером. Означает ли это, что эти переменные находятся в разных участках памяти, но ссылаются на один и тот же контейнер?
0
17.05.2018, 18:21
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
17.05.2018, 18:21
Привет! Вот еще темы с ответами:

Контейнер - C (СИ)
Привет. Я Си знаю не очень хорошо. Хочу, чтобы помогли разобраться с заданием, понять его. Дана библиотека #ifndef LINEAR_SEQUENCE_H ...

Из БД в контейнер - C++ Builder
Приветствую!! Пишу программу парсер, выгружаю данные из БД. Подскажите, пожалуйста, наилучший способ чтоб я мог выгружая данные занести их...

Контейнер таблиц - FoxPro
Задание дали, но вообще ничего не объяснили. Подскажите, пожалуйста, что это вообще такое и как его создать (с помощью Project Manager).

контейнер map - C++
Помогите, пожалуйста дописать программу. Определите карту, в которой ключом является фамилия семьи, а значением вектор, который содержит...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru