Сроки сеанса PHP слишком рано [дублировать]

Python: Mutable Default Argument

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

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

Они остаются мутированными, потому что каждый раз они являются одним и тем же объектом .

Эквивалентный код:

Поскольку список связан с функцией, когда объект функции компилируется и инстанцируется, это:

def foo(mutable_default_argument=[]): # make a list the default argument
    """function that uses a list"""

почти точно эквивалентно этому:

_a_list = [] # create a list in the globals

def foo(mutable_default_argument=_a_list): # make it the default argument
    """function that uses a list"""

del _a_list # remove globals name binding

Демонстрация

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

  • , увидев, что список создан до того, как функция завершила компиляцию объекту функции,
  • , заметив, что идентификатор один и тот же каждый раз, когда список ссылается,
  • , наблюдая, что список остается, когда функция, которая его использует, называется второй раз,
  • , наблюдая порядок, в котором вывод печатается из источника (который я удобно пронумеровал для вас):

example.py

print('1. Global scope being evaluated')

def create_list():
    '''noisily create a list for usage as a kwarg'''
    l = []
    print('3. list being created and returned, id: ' + str(id(l)))
    return l

print('2. example_function about to be compiled to an object')

def example_function(default_kwarg1=create_list()):
    print('appending "a" in default default_kwarg1')
    default_kwarg1.append("a")
    print('list with id: ' + str(id(default_kwarg1)) + 
          ' - is now: ' + repr(default_kwarg1))

print('4. example_function compiled: ' + repr(example_function))


if __name__ == '__main__':
    print('5. calling example_function twice!:')
    example_function()
    example_function()

и работает это с python example.py:

1. Global scope being evaluated
2. example_function about to be compiled to an object
3. list being created and returned, id: 140502758808032
4. example_function compiled: 
5. calling example_function twice!:
appending "a" in default default_kwarg1
list with id: 140502758808032 - is now: ['a']
appending "a" in default default_kwarg1
list with id: 140502758808032 - is now: ['a', 'a']

Означает ли это нарушение принципа «Наименьшее удивление»?

Этот порядок выполнения часто путает новых пользователей Python. Если вы понимаете модель исполнения Python, это становится вполне ожидаемым.

Обычная инструкция для новых пользователей Python:

Но поэтому обычная инструкция для новых пользователей заключается в том, чтобы вместо этого создать свои аргументы по умолчанию:

def example_function_2(default_kwarg=None):
    if default_kwarg is None:
        default_kwarg = []

Это использует None singleton как объект-дозор, чтобы сообщить функции, есть ли у нас аргумент, отличный от значения по умолчанию. Если мы не получаем никакого аргумента, то мы действительно хотим использовать новый пустой список [] в качестве значения по умолчанию.

Как говорится в разделе в разделе управления потоком :

Если вы не хотите, чтобы по умолчанию были разделены между последующими вызовами, вы можете написать такую ​​функцию, как это:

def f(a, L=None):
    if L is None:
        L = []
    L.append(a)
    return L
51
задан Greg B 10 August 2011 в 13:49
поделиться

6 ответов

Проверить значение php.ini, установленное для session.gc_maxlifetime, - это время жизни ID в секундах.

Я считаю, что по умолчанию 1440 секунд (24 минуты)

http://www.php.net/manual/en/session.configuration.php

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

Как мне закончить сеанс PHP через 30 минут?

48
ответ дан Community 21 August 2018 в 21:31
поделиться
  • 1
    -1, а не правильный ответ на вопрос. распространенное заблуждение. – goat 30 April 2012 в 00:20
  • 2
    @chris, почему бы вам не предложить альтернативный ответ? – Brannon 27 June 2013 в 20:11
  • 3
    Как пишет Браннон, это совершенно неправильно и не должно быть выбранным ответом. Это значение говорит сборщику мусора о том, как себя вести, это не о том, как долго длится ваш сеанс. Сессия oculd жива навсегда, если вы не добавляете какой-то механизм. Ключ состоит в том, чтобы обрабатывать время жизни сеанса самостоятельно (т. Е. Удалять данные сеанса после периода бездействия) и устанавливать session.gc_maxlifetime на большее или равное значение. kontur предложил лучший ответ по этому вопросу, но, пожалуйста, не подтвердите этот ответ, он уклоняется от проблем безопасности. – Ninj 19 September 2013 в 13:56
  • 4
    Неверный ответ, это только устанавливает время, когда удаляются файлы недопустимого сеанса / «сборщик мусора». Установка этого параметра не продлит сеансы пользователя. – Manuel Arwed Schmidt 15 June 2014 в 19:45

это зависит от ваших настроек php ... используйте phpinfo() и посмотрите главу сеанса. Существуют значения, такие как session.gc_maxlifetime и session.cache_expire и session.cookie_lifetime, которые влияют на продолжительность жизни сеансов

EDIT: это похоже на запись Мартина перед

2
ответ дан A J 21 August 2018 в 21:31
поделиться

Вы можете использовать что-то вроде ini_set('session.gc_maxlifetime', 28800); // 8 * 60 * 60.

0
ответ дан Eduardo Cuomo 21 August 2018 в 21:31
поделиться

Значение по умолчанию в php.ini для директивы session.gc_maxlifetime («gc» для сбора мусора) составляет 1440 секунд или 24 минуты. См. Страницу «Настройка времени выполнения сеанса» в руководстве:

http://www.php.net/manual/en/session.configuration.php

Вы можете изменить эту константу в файлах php.ini или .httpd.conf, если у вас есть к ним доступ, или в локальном файле .htaccess на вашем веб-сайте. Чтобы установить тайм-аут на один час с помощью метода .htaccess, добавьте эту строку в файл .htaccess в корневой каталог сайта:

php_value session.gc_maxlifetime "3600"

Будьте осторожны, если вы находитесь на общем хосте или если вы размещаете несколько сайтов, на которых вы не изменили значение по умолчанию. Место сеанса по умолчанию - это каталог / tmp, и процедура сбора мусора будет выполняться каждые 24 минуты для этих других сайтов (и уничтожить ваши сеансы в процессе, независимо от того, сколько времени они должны быть сохранены в ). , См. Примечание на странице руководства или на этом сайте для лучшего объяснения.

Ответ на это - перевести сеансы в другой каталог с использованием сеанса .save_path. Это также помогает предотвратить появление плохих парней из захватов ваших посетителей из каталога по умолчанию / tmp.

22
ответ дан flamingLogos 21 August 2018 в 21:31
поделиться
  • 1
    -1, а не правильный ответ на вопрос. распространенное заблуждение. собранный файл сеанса gc не заставит php генерировать новый идентификатор сеанса, а также не является надежным сроком даже в том случае, если сеансы сохраняются в их собственном каталоге. – goat 30 April 2012 в 00:23

По словам пользователя на сайте PHP.net , его попытки сохранить сеанс не удалось, поэтому ему пришлось сделать обходное решение.

<?php

$Lifetime = 3600;
$separator = (strstr(strtoupper(substr(PHP_OS, 0, 3)), "WIN")) ? "\\" : "/";

$DirectoryPath = dirname(__FILE__) . "{$separator}SessionData";
//in Wamp for Windows the result for $DirectoryPath
//would be C:\wamp\www\your_site\SessionData

is_dir($DirectoryPath) or mkdir($DirectoryPath, 0777);

if (ini_get("session.use_trans_sid") == true) {
    ini_set("url_rewriter.tags", "");
    ini_set("session.use_trans_sid", false);

}

ini_set("session.gc_maxlifetime", $Lifetime);
ini_set("session.gc_divisor", "1");
ini_set("session.gc_probability", "1");
ini_set("session.cookie_lifetime", "0");
ini_set("session.save_path", $DirectoryPath);
session_start();

?>

В папке SessionData это будут сохранены текстовые файлы для хранения информации о сеансе, каждый файл будет иметь имя, похожее на «sess_a_big_hash_here».

2
ответ дан Junior M 21 August 2018 в 21:31
поделиться

Но будьте осторожны, на большинстве настроек xampp / ampp /...- и в некоторых версиях linux это 0, что означает, что файл никогда не будет удален, пока вы не сделаете это в своем скрипте (или не заразитесь с помощью оболочки)

PHP.INI:

; Lifetime in seconds of cookie or, if 0, until browser is restarted.
; http://php.net/session.cookie-lifetime
session.cookie_lifetime = 0
0
ответ дан Sliq 21 August 2018 в 21:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: