|
PHP - помогите разобраться со ссылками
|
|||
---|---|---|---|
#18+
Допустим, есть такой код: Код: php 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. 92. 93. 94. 95. 96. 97. 98. 99. 100. 101. 102.
Разве последняя строка не должна вывести значения 123? ... |
|||
:
Нравится:
Не нравится:
|
|||
05.03.2020, 20:31 |
|
PHP - помогите разобраться со ссылками
|
|||
---|---|---|---|
#18+
Не вижу на то причин. Полагаю, такое поведение станет понятным после ответа на следующий простой вопрос. На какую именно переменную (в смысле область памяти, обозначенную некоторой меткой, имеющей имя) ссылается в данном случае $val на последней итерации цикла foreach? ... |
|||
:
Нравится:
Не нравится:
|
|||
06.03.2020, 06:02 |
|
PHP - помогите разобраться со ссылками
|
|||
---|---|---|---|
#18+
Ну поскольку используется стандартный итератор массивов, и ссылается он на массив, то я ожидал, что foreach ($fld as $key=>&$val) должен быть идентичен foreach ($this->local as $key=>&$val) внутри класса. ... |
|||
:
Нравится:
Не нравится:
|
|||
06.03.2020, 11:22 |
|
PHP - помогите разобраться со ссылками
|
|||
---|---|---|---|
#18+
Итератор тут сильно из другой йоперы. На вопрос Вы ответить не попытались, видимо. Ладно, коротко, суть ссылающейся переменной есть алиас другой переменной - они обе указывают на одну и ту же область памяти. Примерно как хардлинк в файловой системе. Когда переменная $val будет явно указывать на область памяти, заданную какой-то другой переменной или элементом массива, тогда содержимое этой области можно изменить, обращаясь к этой переменной. ... |
|||
:
Нравится:
Не нравится:
|
|||
06.03.2020, 22:39 |
|
PHP - помогите разобраться со ссылками
|
|||
---|---|---|---|
#18+
Alibek B., Код: php 1. 2. 3. 4.
... |
|||
:
Нравится:
Не нравится:
|
|||
10.03.2020, 14:37 |
|
PHP - помогите разобраться со ссылками
|
|||
---|---|---|---|
#18+
vkle Когда переменная $val будет явно указывать на область памяти, заданную какой-то другой переменной или элементом массива, тогда содержимое этой области можно изменить, обращаясь к этой переменной. Поясню свою логику. Стандартный итератор позволяет в цикле изменять значения массива (если использовать foreach $array as &$item). Значит стандартный итератор массива позволяет работать не со значением переменной, а со ссылкой на нее. То есть моя цепочка рассуждений следующая: если я во внешнем коде использую &$val, то $val будет ссылаться на область памяти, которой соответствует элемент из private-массива $local, поскольку обход этого private-массива осуществляется через стандартный итератор массива. Ведь класс SubAppField по сути просто обертка над массивом массивов, а итератор IteratorAggregate обеспечивает доступ к этому массиву. Не так? ScareCrow , в этом примере ничего неожиданного, такое поведение вполне укладывается в то, что я знаю о переменных PHP. Если после первого цикла указать unset($value), то ничего в цикле изменяться не будет. И если вместо var_dump использовать debug_zval_dump, то все будет более понятно. ... |
|||
:
Нравится:
Не нравится:
|
|||
10.03.2020, 15:48 |
|
PHP - помогите разобраться со ссылками
|
|||
---|---|---|---|
#18+
Alibek B., Как я понимаю эту кухню. Значение 123 должно бы (гипотетически, по соображению, я так думаю и т.п.) нырнуть в область памяти, обозначенную, скажем $local['id']. Будь $local паблик переменной - так бы оно и было. Однако, $local в данном случае есть приватная переменная. И, стало быть, в ее отношении должен автоматически применяться волшебный метод __set(). Есть такой. И даже определен. А там, если верить доке, применима только лишь передача по значению, с явным указанием имени. Даже если итератор и прислал ссылку на область памяти в $val (ссылка - одна штука), то в сеттер она никак не лезет, так как он ожидает имя и значение (две штуки). Ну вот так как-то, сеттер ссылку теряет тут. ... |
|||
:
Нравится:
Не нравится:
|
|||
10.03.2020, 20:53 |
|
PHP - помогите разобраться со ссылками
|
|||
---|---|---|---|
#18+
Alibek B., И еще, итератор тоже ж не дураками писан. Выше я лишь предположил "если итератор и прислал ссылку", а оно не факт. Со стороны итератора видно приватную переменную и уже заранее понятно должно быть, что ссылки там не работают. В этом смысле он может даже и не прислать ссылку, а прислать значение. ... |
|||
:
Нравится:
Не нравится:
|
|||
10.03.2020, 20:59 |
|
PHP - помогите разобраться со ссылками
|
|||
---|---|---|---|
#18+
vkle И, стало быть, в ее отношении должен автоматически применяться волшебный метод __set(). ... А там, если верить доке, применима только лишь передача по значению, с явным указанием имени. Суть понял, но мне кажется, что в данном случае что-то другое. Допустим в коде есть присвоение переменной, $var=$val. В виде функции это можно было бы записать как f(&$var, $var). Но в моем случае волшебный метод set работает не с переменной (ссылкой на переменную), я в него передаю не саму переменную (которая хранит значение), а ключ массива. А уже внутри метода по этому ключу я обращаюсь к элементу массива. То есть в виде функции это будет __set($key, $var), а внутри функции будет обращение к элементу массива по ключу $arr[$key]=$val. Я скорее предполагал, что может быть это побочные эффекты trait, но в документации везде явно указывается, что trait это почти макрос и его код не переиспользуется, а повторяется. ... |
|||
:
Нравится:
Не нравится:
|
|||
11.03.2020, 08:57 |
|
PHP - помогите разобраться со ссылками
|
|||
---|---|---|---|
#18+
Alibek B. а внутри функции будет обращение к элементу массива по ключу $arr[$key]=$val. Было бы что-то вроде Код: php 1.
- тогда да, после развертывания левой части выражения $fld->$key вполне может трактоваться как имя переменной. ... |
|||
:
Нравится:
Не нравится:
|
|||
11.03.2020, 12:41 |
|
PHP - помогите разобраться со ссылками
|
|||
---|---|---|---|
#18+
vkle Да откуда ж там ключу взяться, если в Вашем варианте операции присваивания нет ни ключа, ни указания на переменную? Вероятно да. Я думал, что под капотом какая-нибудь магия происходит, следствием которой является то, что при использовании ссылки на переменную (например в foreach) фактически происходит присвоение. Но сейчас почитал про итераторы, похоже что там что-то более сложное. ... |
|||
:
Нравится:
Не нравится:
|
|||
11.03.2020, 16:04 |
|
PHP - помогите разобраться со ссылками
|
|||
---|---|---|---|
#18+
С учетом ограничений переделал класс для универсальной коллекции. Но ведь это наверняка велосипед. Не посоветуете, что добавить/улучшить? Код: php 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. 92. 93. 94. 95. 96. 97. 98. 99. 100. 101. 102. 103. 104. 105. 106. 107. 108. 109. 110. 111. 112. 113. 114. 115. 116. 117. 118. 119. 120. 121. 122. 123. 124. 125. 126. 127. 128. 129. 130. 131. 132. 133. 134. 135. 136.
... |
|||
:
Нравится:
Не нравится:
|
|||
11.03.2020, 16:37 |
|
PHP - помогите разобраться со ссылками
|
|||
---|---|---|---|
#18+
Гипотетически, такая магия возможна, если блок кода foreach будет передан в итератор. Однако, думаю, в таком случае получится абракадабра контекста. Ведь блок кода по сути выполняется во вне по отношению к объекту, а итератор внутри. И еще вот что подумалось. Ведь прямой доступ к приватной переменной объекта извне его невозможен по определению. Таким образом, никакие указатели или ссылки на область памяти, обозначенную этой переменной за пределы объекта вылезти не должны. Наверно, это более простое объяснение. ... |
|||
:
Нравится:
Не нравится:
|
|||
11.03.2020, 16:48 |
|
PHP - помогите разобраться со ссылками
|
|||
---|---|---|---|
#18+
vkle Ведь прямой доступ к приватной переменной объекта извне его невозможен по определению. Таким образом, никакие указатели или ссылки на область памяти, обозначенную этой переменной за пределы объекта вылезти не должны. Наверно, это более простое объяснение. Ну через методы это работает. Возвратить ссылку у меня не получилось, а вот через аргумент по ссылке вполне. ... |
|||
:
Нравится:
Не нравится:
|
|||
11.03.2020, 17:15 |
|
PHP - помогите разобраться со ссылками
|
|||
---|---|---|---|
#18+
Столкнулся с сообщением "Indirect modification of overloaded property". Можно ли от него избавится? Ранее можно было просто указать &, чтобы передать ссылку. Но начиная с какой-то версии (как минимум с 5.6) это запретили, & может указываться только в декларации function и foreach, использовать его в выражениях нельзя. Вот тут в принципе почти мой вариант, но предложенное решение с & сейчас уже неприменимо. ... |
|||
:
Нравится:
Не нравится:
|
|||
11.03.2020, 23:03 |
|
|
start [/forum/topic.php?fid=23&msg=39936364&tid=1459742]: |
0ms |
get settings: |
9ms |
get forum list: |
12ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
38ms |
get topic data: |
10ms |
get forum data: |
3ms |
get page messages: |
54ms |
get tp. blocked users: |
1ms |
others: | 13ms |
total: | 148ms |
0 / 0 |