Объясните тупому про sessions

12
Kaavain
На сайте с 28.07.2015
Offline
133
322

В гугле не забанен, Стековерфлоу читал, но похожу слишком туп. Объясните убогому.

index.php содержит session_start(); (и не только он, но первый - там). Перед этим include config.php; где устанавливается разное, в частности ini_set('session.save_path', $path); 

Каждое перелистывание - это обращение к index.php с GET-параметрами. То есть каждый хит любого юзера -  include config.php;  ini_set('session.save_path', $path);  session_start();

Правильно ли я понимаю, что у реального юзера сажается кука, и при  session_start(); выбирается существующий файл сессии вместо создания нового? А у роботов просто куки запрещены, поэтому у робота - каждый хит = новый файл сессии?

Что хочу, хочу чтобы у реального юзера не запускался процесс  ini_set('session.save_path', $path); , но если перед  session_start();  в  index.php или, что равно, в  config.php, делать if ($_SESSION['test']) типа сессия есть, то результат - фиг. То есть файл сессии с $_SESSION['test'] он есть, но до  session_start(); не открыт что ли.... 

Как быть?

Могу порекомендовать только хостинг: https://traf.at/vps - за 3 года все на 4++ и цены не подняли. Ну и банк для белых ИП: https://traf.at/bankm
Aisamiery
На сайте с 12.04.2015
Offline
293
#1

Хотелось бы понять ваш опус, но честно непонятно совсем.

session_start() -  создаёт сессию, либо возобновляет существующую, основываясь на идентификаторе сессии, переданном через GET- или POST-запрос, либо переданный через cookie (из документации)

до вызова session_start массив $_SESSION пуст. Вы можете стартовать сессию только по условию, условием будет ваше определение реального юзера (только не в массиве $_SESSION)

Разработка проектов на Symfony, Laravel, 1C-Bitrix, UMI.CMS, OctoberCMS
Kaavain
На сайте с 28.07.2015
Offline
133
#2
Aisamiery #:

Хотелось бы понять ваш опус, но честно непонятно совсем.

session_start() -  создаёт сессию, либо возобновляет существующую, основываясь на идентификаторе сессии, переданном через GET- или POST-запрос, либо переданный через cookie (из документации)

до вызова session_start массив $_SESSION пуст. Вы можете стартовать сессию только по условию, условием будет ваше определение реального юзера (только не в массиве $_SESSION)

Массив в памяти. Но файл сессии-то есть. Я тоже понять не могу, согласен :-) , поэтому и прошу объяснить. 

W1
На сайте с 22.01.2021
Offline
285
#3
Kaavain :
хочу чтобы у реального юзера не запускался процесс  ini_set('session.save_path', $path);

Не нужны сессии? Странное желание.

Мой форум - https://webinfo.guru –Там я всегда на связи
E
На сайте с 29.09.2020
Offline
26
#4
Kaavain :

Каждое перелистывание - это обращение к index.php с GET-параметрами. То есть каждый хит любого юзера -  include config.php;  ini_set('session.save_path', $path);  session_start();

Правильно ли я понимаю, что у реального юзера сажается кука, и при  session_start(); выбирается существующий файл сессии вместо создания нового? А у роботов просто куки запрещены, поэтому у робота - каждый хит = новый файл сессии?

Да, сажается кука с именем PHPSESSID по умолчанию. Но у роботов ПС куки не запрещены, они ходят реальными браузерами.

Кроме  session_start(), в целях защиты ID сессии от перехвата, может вызываться  session_regenerate_id , которая гененерирует новый ID сессии (создает новый файл сессии).  При этом ID старой сессии (файл сессии на диске сервера) может не уничтожаться немедленно, а храниться некоторое время (там по ссылке есть пример реализации и объяснение почему так делается). При некорректной реализации, ПС может нагенерить тонну сессий.

Kaavain :

Что хочу, хочу чтобы у реального юзера не запускался процесс  ini_set('session.save_path', $path); , но если перед  session_start();  в  index.php или, что равно, в  config.php, делать if ($_SESSION['test']) типа сессия есть, то результат - фиг. То есть файл сессии с $_SESSION['test'] он есть, но до  session_start(); не открыт что ли.... 

Как быть?

Пока не запустите  session_start(); , массив $_SESSION[] не будет заполнен. Его заполняет именно  session_start();  (читает файл сессии на сервере и иниализирует из него этот массив)

Вы просто используете сессии не по назначению. Сессия должна стартоваться только для авторизованных(залогиненных) посетителей - для этого при авторизации посетителю садится кука (например, Login_Name=Вася), и если браузер присылает эту куку - значит посетитель уже ранее логинился на сайт, и ему стартуется сессия. Если прислан корректный PHPSESSID , то из сессии (файла на сервере с именем из  PHPSESSID) поднимаются данные идентификации посетителя, что он навыбирал себе в корзину, и тп.

Вы же храните в сессии данные (выбранные товары в корзине) для любых неавторизованных посетителей, а это надо делать в куках или localStorage. Тогда не придётся стартовать сессию ботам и всяким случайным посетителям.

С минимальными переделками сайта - можно садить посетителю специальную куку типа basket=1, если он выбрал что-либо в корзину. Тогда на сервере проверяете isset($_COOKIE['basket']), и если она установлена - вызываете session_start(). У ботов ПС этой куки не будет, ибо они ничего в корзину не выбирают.

Window: localStorage property - Web APIs | MDN
Window: localStorage property - Web APIs | MDN
  • 2023.04.08
  • developer.mozilla.org
The read-only property of the interface allows you to access a object for the 's origin; the stored data is saved across browser sessions. is similar to , except that while data has no expiration time, data gets cleared when the page session ends — that is, when the page is closed. ( data for a document loaded in a "private browsing" or...
Kaavain
На сайте с 28.07.2015
Offline
133
#5
egranty #:
Вы просто используете сессии не по назначению

Да, я это понимаю. Но переделывать это очень сложно. Вот и леплю костыли.

egranty #:
Пока не запустите  session_start(); , массив $_SESSION[] не будет заполнен.

Это я тоже понимаю. Вопрос в том - можно ли ДО  session_start(); понять что сессия данного посетителя существует? Я бы делал эту проверку, и тогда бы обходил 

$path = $_SERVER['DOCUMENT_ROOT'].'/sessions/'.$_SERVER['HTTP_HOST'];
if (!is_dir($path)) {
        $path = $_SERVER['DOCUMENT_ROOT'].'/sessions/bots';
}
if (isset($_SERVER['HTTP_USER_AGENT'])) {
        if (!is_bool(stripos($_SERVER['HTTP_USER_AGENT'], 'bot')) ||
            !is_bool(stripos($_SERVER['HTTP_USER_AGENT'], 'spider')) ||
            !is_bool(stripos($_SERVER['HTTP_USER_AGENT'], 'Slurp')) ||
            !is_bool(stripos($_SERVER['HTTP_USER_AGENT'], 'crawler')) ||
            !is_bool(stripos($_SERVER['HTTP_USER_AGENT'], 'Uptime')) ||
            !is_bool(stripos($_SERVER['HTTP_USER_AGENT'], 'facebook'))) {
                $path = $_SERVER['DOCUMENT_ROOT'].'/sessions/bots';
        }
}
ini_set('session.save_path', $path);

при каждом хите...

Kaavain
На сайте с 28.07.2015
Offline
133
#6
webinfo #:
Не нужны сессии? Странное желание.

Не очень точно выразился:

webinfo #:
хочу чтобы у реального юзера не запускался процесс  ini_set('session.save_path', $path);

хочу чтобы у реального юзера не запускался процесс  ini_set('session.save_path', $path); ЕСЛИ ЭТО НЕ ПЕРВЫЙ ХИТ.

Kaavain
На сайте с 28.07.2015
Offline
133
#7

Так, сам острю - сам смеюсь. У меня всегда так - пока тут (или не тут, но тут позориться не так страшно) пишу, приходит в голову такая редкость, как умная мысль...

1. При каждом хите идет обращение к index.php и это всегда как в первый раз, тут ниче не попишешь, Апач или Нгинкс (уж не знаю кто) не может знать прошлого... 

2. Соответственно при каждом хите session.save_path дефолтный, а именно /var/www/user/data/tmp если панель ISPmanager (всеми силами стараюсь слезть с этой иглы) или FastPanel (отличная штука). И без ini_set('session.save_path', $path); ничего не поделать.

3. Чтобы избежать при каждом хите if (юзерагент?){$path} + ini_set('session.save_path', $path);  что я и хочу - юзать (неправильно мною используемые) сессии нельзя, так как массив $_SESSION[] пуст до session_start();  , а чтение из файла получается сложно и медленно.

4. Рабочий вариант должен быть такой: писать в куки скажем либо безликое $sesspath = 1(2,3,4,...) получаемое при первом хите и при всех хитах читать его и if(!$sesspath) { if (юзерагент?){$path} + ini_set('session.save_path', $path); } либо писать туда сразу весь  $path но мне кажется это не принято, так как в юзера в куках будет уже не безликая информация, а конкретика.

5. П.4 не должен сбоить, ибо если умерла кука у юзера, то и корзина обнулилась и вообще шефвсепропало.

6. Бонусная игра: а может вообще еще и  session_start();  заменить на if(! $_SESSION[]){ session_start(); } раз пошла такая пьянь??? UPD: не имеет смысла, так как повторный вызов ничего не делает, а варнинги у меня отключены.

Скажите мне, я мегахакер или опять что не понял?

V1
На сайте с 14.03.2007
Online
146
#8
Kaavain #:
заменить на if(! $_SESSION[]){ session_start(); }
Kaavain #:
так как массив $_SESSION[] пуст до session_start();

)

Интересно что за магазин, где пользователи возвращаются к корзине через некоторое время.

Мне когда-то также не хотелось переделывать свои несколько сайтов с php 5 на следующую версию, так как нужно было изменить и доступ к базе данных и некоторые модули не работали. Но просто сел и переделал по правильному. Может и Вам переделать на нормальную логику, как писали выше?

W1
На сайте с 22.01.2021
Offline
285
#9
Kaavain #:
Скажите мне, я мегахакер или опять что не понял?

Просто решил заняться какой-то фигнёй, от нефигделать.

Kaavain
На сайте с 28.07.2015
Offline
133
#10
vitaliy11 #:

)

Интересно что за магазин, где пользователи возвращаются к корзине через некоторое время.

Мне когда-то также не хотелось переделывать свои несколько сайтов с php 5 на следующую версию, так как нужно было изменить и доступ к базе данных и некоторые модули не работали. Но просто сел и переделал по правильному. Может и Вам переделать на нормальную логику, как писали выше?

У меня время жизни корзины - год. Возврат к корзине через месяц - не редкость. Иногда возвращаются даже больше, чем через год. Правда такие случаи исчезающие редки. 

12

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий