[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Почеу это работает?
shifteee
Вопрос в следующем:
есть файл index.php

session_start();
$a = 2;
$b = &$a;
$_SESSION["var_b"] = $b;

echo $a; //// вывод 2
echo $b //// вывод 2


и файл notindex.php, переход к которому осуществляется по обычной ссылке
<a href="">
, с содержанием:

session_start();
$c = $_SESSION["var_b"]
echo $c; //// вывод 2


Вопрос: почему это работает? Почему я в обоих вариантах, передавая адрес переменной, я получаю значение. И почему при переходе на страницу notindex.php ссылка на переменную $a все равно выдает ее значение?



Спустя 1 минута, 19 секунд shifteee написал(а):
Ах да... дело происходит на локалхосте, если это имеет значение с установленным апачем 2.19 и пхп 5.3.6... ну и Иксдебагер стоит



Спустя 16 минут, 24 секунды (16.08.2011 - 20:25) Invis1ble написал(а):
Цитата
Почему я в обоих вариантах, передавая адрес переменной, я получаю значение

ну так потому что ссылка
Цитата
И почему при переходе на страницу notindex.php ссылка на переменную $a все равно выдает ее значение?

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

Спустя 3 минуты, 32 секунды (16.08.2011 - 20:29) shifteee написал(а):
$b = &$a;
$_SESSION["var_b"] = $b;


если я правильно помню программирование, без операций разыменования в переменнойй $b не должно быть значения переменной $а, а только адрес, в котором содержится значение переменной $a

Спустя 7 минут, 19 секунд (16.08.2011 - 20:36) kovaldm написал(а):
Переменнная $b ссылается на переменную $a только и всего. А какой адрес вы хотели в ней увидеть?

Спустя 11 минут, 10 секунд (16.08.2011 - 20:47) shifteee написал(а):
Цитата
Понятие указателя тесно связано с понятием адреса объекта. В C есть специальная операция, позволяющая получить адрес любой переменной:

&p – получение адреса, где p – идентификатор переменной. Результатом операции является адрес переменной p.


Я думаю что в php, написанном на с++, эти операции работают одинакового. Поправьте меня если я неправ

Спустя 2 минуты, 17 секунд (16.08.2011 - 20:49) kovaldm написал(а):
РНР написан на С.
Цитата
Ссылки в PHP - это средство доступа к содержимому одной переменной под разными именами. Они не похожи на указатели C и не являются псевдонимами таблицы символов. В PHP имя переменной и её содержимое - это разные вещи, поэтому одно содержимое может иметь разные имена. Ближайшая аналогия - имена файлов Unix и файлы - имена переменных являются элементами каталогов, а содержимое переменных это сами файлы. Ссылки в PHP - аналог жёстких ссылок (hardlinks) в файловых системах Unix.

Спустя 1 минута, 40 секунд (16.08.2011 - 20:51) blazze написал(а):
$b = &$a;


эта конструкция означает что там теоретически и есть адрес и в этом легко убедится изменив значение переменной $а и вывести значение переменной б в стандартный поток вывода.
По поводу второго вопроса почему есть значение с. потому что массив сесий хранится на сервере (в файлах или бд). и пока есть сессия все переменные сесии хранятся там.

Спустя 15 минут (16.08.2011 - 21:06) Guest написал(а):
потому что массив сесий хранится на сервере (в файлах или бд). и пока есть сессия все переменные сесии хранятся там. 


Это понятно. Я всеже и новичек, но не на столько. Смыс этого маленькогоо эксперимента в том, чтобы понять где границы одного скрипта пхп и начало другого. В какой момент все созданные переменные со станицы, скажем, index.php перестанут существовать в памяти сервера. И есть ли возможность хранить в переменных сессий ссылки на созданные объекты и обращаться к функциям классов в любом месте кода любого файла проекта, просто поместив ссылку на этот класс.

типо такого
$a = new Db();
$_SESSION["db_link"] = &$a;



и где-нибудь в жопе моего проекта :

$result = $_SESSION["db_link"] -> fetch_asasoc();

Спустя 5 минут, 48 секунд (16.08.2011 - 21:12) blazze написал(а):
глобальные переменные в ооп - зло wink.gif

после вывода странички все объекты, переменные и т.д. уничтожаются сохраняется только то, что засовывается в массив $_SESSION. пхп это не джава и не с++.

Спустя 16 секунд (16.08.2011 - 21:12) Invis1ble написал(а):
Guest
Цитата
$a = new Db();
$_SESSION["db_link"] = &$a;

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

Спустя 2 минуты, 18 секунд (16.08.2011 - 21:14) shifteee написал(а):
Цитата (Invis1ble @ 16.08.2011 - 18:12)
Guest
Цитата
$a = new Db();
$_SESSION["db_link"] = &$a;

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

на локалхосте работает))) иначе я бы не поднял вопрос)))

что значит завершение работы скрипта? вывод содержимого index.php в окно браузера?

Спустя 2 минуты, 11 секунд (16.08.2011 - 21:17) kirik написал(а):
Цитата (Guest @ 16.08.2011 - 14:06)
где границы одного скрипта пхп и начало другого

В случае работы php как модуля к apache или через fpm, при каждом запросе скрипт будет отрабатываться снова и снова, начиная с нуля. А после завершения своей работы вся занятая им память освободится.

Цитата (Guest @ 16.08.2011 - 14:06)
И есть ли возможность хранить в переменных сессий ссылки на созданные объекты и обращаться к функциям классов в любом месте кода любого файла проекта, просто поместив ссылку на этот класс.

Такая возможность есть. Для таких целей обычно используют Memcached, и инициированные объекты загоняют в него. Но ИМХО это костыль.
А в переменных сессий лучше вообще ничего не хранить, если есть такая возможность. Тоесть использовать их в крайних случаях, когда нужно авторизовать пользователя (записать в сессию его id). Это я про большие проекты говорю.

Цитата (shifteee @ 16.08.2011 - 14:14)
что значит завершение работы скрипта? вывод содержимого index.php в окно браузера?

Это значит что интерпритатор достиг конца файла, либо выполнение скрипта прервали (exit, die, неотловленное исключение, либо фатальная ошибка)

Спустя 1 минута, 6 секунд (16.08.2011 - 21:18) Invis1ble написал(а):
Удивительно, но только что протестировал - действительно работает.
Цитата
что значит завершение работы скрипта?

вывод содержимого в браузер происходит уже после отработки скрипта (кроме отдельных случаев, например при использовани flush())



Спустя 1 минута, 21 секунда Invis1ble написал(а):
kirik
Цитата
А после завершения своей работы вся занятая им память освободится.

Хочу повторить вопрос ТС: Почему работает? biggrin.gif

Спустя 2 минуты, 31 секунда (16.08.2011 - 21:20) Guest написал(а):
Цитата (Invis1ble @ 16.08.2011 - 18:18)
Удивительно, но только что протестировал - действительно работает.

Чудеса, правда?))

Остается понять почему работает)))

Спустя 3 минуты, 5 секунд (16.08.2011 - 21:23) kirik написал(а):
Цитата (Invis1ble @ 16.08.2011 - 14:19)
Хочу повторить вопрос ТС: Почему работает?

Так сессии же хранятся вне зависимости от того, завершился скрипт или нет.
А в самом начале происходит что: перед тем как скрипт завершается, php записывает массив $_SESSION в соттвтетствующий сессионный файл. Так как на момент этой записи память остаётся не тронутой, то и доступ к $a (через ссылку $_SESSION["db_link"]) у нас всё ещё есть.

Спустя 3 минуты, 8 секунд (16.08.2011 - 21:26) Guest написал(а):
так переменной $a не существует. Там должна быть ссылка на нее. Не более. Передавая переменную по ссылке не должно происходить копирование всего объекта.

Спустя 1 минута, 8 секунд (16.08.2011 - 21:28) blazze написал(а):
ну если ссылка на ресурс не удаляется, то соответственно, почему оно не должно работать? для таких извратов так же есть персист коннект biggrin.gif тут проблема, что чем больше юзеров тем больше будет нагрузка на сервер - держать много открытых соединений.

Спустя 43 секунды (16.08.2011 - 21:28) Invis1ble написал(а):
вот и меня это смущает... вроде как ссылка, а получается по сути, что нет

Спустя 3 минуты, 11 секунд (16.08.2011 - 21:31) Guest написал(а):
Цитата (blazze @ 16.08.2011 - 18:28)
ну если ссылка на ресурс не удаляется, то соответственно, почему оно не должно работать? для таких извратов так же есть персист коннект biggrin.gif тут проблема, что чем больше юзеров тем больше будет нагрузка на сервер - держать много открытых соединений.

Ну ссылка может не удляется, но осттальная память, зарезервированная под объект удаляться должна!

И дело не в mySQL_pconnect. Я класс ДБ привел для примера.

Спустя 15 секунд (16.08.2011 - 21:32) blazze написал(а):
Invis1ble

извини, но помоему кто-то из нас не совсем понимает тему ссылок laugh.gif

я например не могу никак понять почему оно не должно работать laugh.gif

Спустя 2 минуты, 58 секунд (16.08.2011 - 21:35) kirik написал(а):
Цитата (Invis1ble @ 16.08.2011 - 14:28)
вроде как ссылка, а получается по сути, что нет

Почему нет то? smile.gif Ссылочные переменные просто разделяют одну область памяти между собой.
Если у нас комната с двумя дверьми (допустим дверь А и дверь Б), то если ты принесёшь.. стол через дверь А, то это стол будет доступен даже если ты зайдёшь через дверь Б. И вынести этот стол можно из любой двери.

Спустя 1 минута, 44 секунды (16.08.2011 - 21:36) Invis1ble написал(а):
blazze
В моем понимании - ссылка это некий объект, который указывает на некую область памяти. Если по завершении работы скрипта память очищается, то по идее и ссылка должна становиться "битой", но так почему-то не происходит....

Спустя 1 минута, 6 секунд (16.08.2011 - 21:37) ZSH написал(а):
Цитата
я например не могу никак понять почему оно не должно работать

я тоже
echo $b //выводит 2

то почему не может быть
$_SESSION['qqq'] = $b // тоже 2

и потом содержимое сессии пишется в файл, а на следующей странице считывается.

Спустя 54 секунды (16.08.2011 - 21:38) Invis1ble написал(а):
kirik
ну так да, а если комната (память) очищается, и стол (данные) при этом уничтожаются, то что я смогу вынести через дверь B (ссылку)?

Спустя 2 минуты, 18 секунд (16.08.2011 - 21:41) kirik написал(а):
Цитата (Invis1ble @ 16.08.2011 - 14:36)
Если по завершении работы скрипта память очищается, то по идее и ссылка должна становиться "битой", но так почему-то не происходит....

Битой она не становится, потому что тоже удаляется. Но не это хотел сказать.. Ведь запись в сессионный файл данных происходит _до_ того как скрипт завершится и php освободит занятую память.
Даже если ты вызываеш exit - php после этого вызова проделывает ещё кучу дел, в т.ч. и сериализацию массива SESSION в файл.

UPD
Цитата (Invis1ble @ 16.08.2011 - 14:38)
ну так да, а если комната (память) очищается, и стол (данные) при этом уничтожаются, то что я смогу вынести через дверь B (ссылку)?

Ничего smile.gif Комнаты (области памяти) после освобождения больше не существует. А с ней и дверей

Спустя 6 секунд (16.08.2011 - 21:41) blazze написал(а):
перейдем ближе к телу так сказать:

пременная $a имеет например адресс [00001h] где записано значение 2
в переменную б мы записали адрес [00001h]
потом записали этот же адрес в сессию..
Теперь вопрос на каком этапе и почему вдруг по вашей логике должна очистится ячейка памяти [00001h]

Спустя 27 секунд (16.08.2011 - 21:41) Invis1ble написал(а):
ZSH
речь в данном случае о другом:
index.php
<?php
session_start();
$a = 10;
$_SESSION['a'] = &$a;
header('Location: test.php');

test.php
<?php
session_start();
var_dump($_SESSION['a']); // int 10

Спустя 59 секунд (16.08.2011 - 21:42) ZSH написал(а):
Цитата
ну так да, а если комната (память) очищается, и стол (данные) при этом уничтожаются, то что я смогу вынести через дверь B (ссылку)?


а через дверь Б стол записался в файл сессий

Спустя 1 минута, 26 секунд (16.08.2011 - 21:44) Invis1ble написал(а):
blazze
Цитата
Теперь вопрос на каком этапе и почему вдруг по вашей логике должна очистится ячейка памяти

на этапе завершения работы скрипта index.php (см. код в предыдущем посте)

Спустя 2 минуты, 20 секунд (16.08.2011 - 21:46) kirik написал(а):
Цитата (blazze @ 16.08.2011 - 14:41)
на каком этапе и почему вдруг по вашей логике должна очистится ячейка памяти [00001h]

Потому что php smile.gif Сборщик мусора освободит эту ячейку, как только на неё не будет ни одной ссылки.

Спустя 5 секунд (16.08.2011 - 21:46) kovaldm написал(а):
По сути $a это тоже ссылка, так же как и $b, и обе они ссылаются на один и тот же "участок" памяти.

Спустя 2 минуты, 11 секунд (16.08.2011 - 21:48) Invis1ble написал(а):
Цитата
Потому что php Сборщик мусора освободит эту ячейку, как только на неё не будет ни одной ссылки.

Ага! Бинго! Теперь все встает на свои места. Я действительно забыл, что сборщик очищает память только при отсутствии каких-либо ссылок на нее.

kirik
Как всегда, почет и уважуха. Лови + smile.gif

Спустя 7 минут, 37 секунд (16.08.2011 - 21:56) Guest написал(а):
Хм... надо попробовать на нормальном хосте. Зчастую локалхост - совсем не показатель. Если все получится, то это забавный инструмент выходит.

Спустя 8 секунд (16.08.2011 - 21:56) blazze написал(а):
а у нас есть ссылка потому ничего не очищается, а даже если и очищается то перед очисткой сеарелизуется и ссылка остаетсяс жива.

Спустя 49 секунд (16.08.2011 - 21:57) Guest написал(а):
Цитата (Invis1ble @ 16.08.2011 - 18:48)
Цитата
Потому что php Сборщик мусора освободит эту ячейку, как только на неё не будет ни одной ссылки.

Ага! Бинго! Теперь все встает на свои места. Я действительно забыл, что сборщик очищает память только при отсутствии каких-либо ссылок на нее.

kirik
Как всегда, почет и уважуха. Лови + smile.gif

ТОлько неизвестно как связан с ними файл сессии, хранящийся какое-то время где-то там совершенно не в ОЗУ сервера)))

Спустя 8 минут, 56 секунд (16.08.2011 - 22:06) blazze написал(а):
http://hosting.viart.com/~blazze/test/test.php

вот собственно наш тест на реальном хостинге все работает так как и должно

Спустя 56 секунд (16.08.2011 - 22:07) ZSH написал(а):
$a = 100;
$_SESSION['a'] = &$a;
echo $_SESSION['a'] ; //выводит 100, не ссылку а содержимое по ссылке


естественно в файл сессий пишется не ссылка а содержимое по ссылке

Спустя 3 минуты, 58 секунд (16.08.2011 - 22:11) blazze написал(а):
Цитата (ZSH @ 16.08.2011 - 19:07)
$a = 100;
$_SESSION['a'] = &$a;
echo $_SESSION['a'] ; //выводит 100, не ссылку а содержимое по ссылке


естественно в файл сессий пишется не ссылка а содержимое по ссылке

не совсем так, при обращении к переменной там находится ссылка а при выводе уже значение. может не совсем понятно изъясняюсь , но по другому не выходит smile.gif

Спустя 4 минуты, 33 секунды (16.08.2011 - 22:15) Invis1ble написал(а):
ZSH
Цитата
естественно в файл сессий пишется не ссылка а содержимое по ссылке

session_start();
$a = 10;
$_SESSION['a'] = &$a;
var_dump($_SESSION['a']); // int 10
$a = 20;
var_dump($_SESSION['a']); // int 20

:)

Спустя 1 минута, 38 секунд (16.08.2011 - 22:17) kovaldm написал(а):
Invis1ble
Издеваешься?

Спустя 1 минута, 25 секунд (16.08.2011 - 22:18) blazze написал(а):
все правильно Invis1ble именно это я имел ввиду когда писал "при обращении к переменной там находится ссылка а при выводе уже значение"

Спустя 2 минуты, 55 секунд (16.08.2011 - 22:21) Invis1ble написал(а):
kovaldm
Цитата
Издеваешься?

Нет. С чего ты взял? И над кем?

Спустя 1 минута, 33 секунды (16.08.2011 - 22:23) ZSH написал(а):
Цитата
не совсем так, при обращении к переменной там находится ссылка а при выводе уже значение. может не совсем понятно изъясняюсь , но по другому не выходит


ну и я о том же, только как выразится не знаю sad.gif

Цитата
"при обращении к переменной там находится ссылка а при выводе уже значение"

Вот оно!!!

Спустя 1 минута, 36 секунд (16.08.2011 - 22:24) shifteee написал(а):
Т.е. по сути получается давольно оптимальный код. Или такое использование этой фичи неправильно по идеологическим соображениям?

Спустя 2 минуты, 53 секунды (16.08.2011 - 22:27) kovaldm написал(а):
Цитата (Invis1ble @ 16.08.2011 - 22:15)
ZSH
Цитата
естественно в файл сессий пишется не ссылка а содержимое по ссылке

session_start();
$a = 10;
$_SESSION['a'] = &$a;
var_dump($_SESSION['a']); // int 10
$a = 20;
var_dump($_SESSION['a']); // int 20

:)

При новом запуске скрипта в сессии окажется int(20), а не ссылка, то есть значение.

Спустя 5 минут, 36 секунд (16.08.2011 - 22:33) ZSH написал(а):
Цитата
естественно в файл сессий пишется не ссылка а содержимое по ссылке

все верно пишется в файл по окончанию работы скрипта а не в процесе изменения содержимого по ссылке
Цитата (blazze)
"при обращении к переменной там находится ссылка а при выводе уже значение"

запись в файл это уже вывод

Спустя 3 минуты, 55 секунд (16.08.2011 - 22:37) kirik написал(а):
Цитата (shifteee @ 16.08.2011 - 15:24)
Или такое использование этой фичи неправильно по идеологическим соображениям?

Как уже выше писал, лучше для хранения объектов использовать memcached, ибо стандартные сессии используют файлы, а это в свою очередь повышает количество I/O операций.

Ещё момент почти по теме:
$a = 1;
$b = $a;

- до тех пор пока мы не изменили значение a или b, эти две переменные тоже неявно ссылаются на одну область в памяти. Только когда мы изменяем значение одной из переменных, выделяется область под хранение значения новой переменной.

Спустя 3 минуты, 34 секунды (16.08.2011 - 22:40) Guest написал(а):
блин... си погубил мой мозг и я не могу правильно воспринимать пхп. Все как-то через жопу

Спустя 3 минуты, 37 секунд (16.08.2011 - 22:44) kirik написал(а):
Guest
Не нравится когда всё сделано за вас? smile.gif

Спустя 4 минуты, 23 секунды (16.08.2011 - 22:48) blazze написал(а):
Цитата (kirik @ 16.08.2011 - 19:37)
ибо стандартные сессии используют файлы, а это в свою очередь повышает количество I/O операций.




согласно рекомендациям зенд или пхп.нет сессии должны храниться в бд

Спустя 40 минут, 15 секунд (16.08.2011 - 23:29) kirik написал(а):
Цитата (blazze @ 16.08.2011 - 15:48)
согласно рекомендациям зенд или пхп.нет сессии должны храниться в бд

Это лишь рекомендации. Тем более хранение сессий в БД повлечет за собой увеличение нагрузки на последнюю, поэтому я считаю это сомнительным мероприятием. Хотя как альтернатива файлам в случае малой посещаемости - вполне даже удобно и красиво.
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.