Разработка

PHP: Самые распространенные проблемы при работе с сессиями

phpsessionsС сессиями в php существует множество непонятных проблем. С появлением виртуальных окружений проблем стало больше.

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

session_start(): open(filename, O_RDWR) failed: No such file or directory

Очевидно, что ошибка возникает, когда не существует пути, по которому пишутся данные. Но при этом вы знаете, что на диске каталог, который был указан как аргумент session_save_path(), существует.

Например.

$ mkdir /tmp/sessions
$ chmod 777 /tmp/sessions
session_save_path('/tmp/sessions');
session_start();

Вы увидите на экране или в логах ошибку из заголовка (не во всех дистрибутивах).

Можно посмотреть audit.log из selinux, но если там нет ничего подозрительного и каталог действительно есть (а вы его создали выше), то причина такого поведения достаточно неожиданна.

Происходит это потому что вы работаете в centos 7 версии (или redhat\fedora) и выше. Именно в этой версии ввели параметр PrivateTmp для сервисов. Что это означает для нас?

Сделайте второй скрипт, который перечисляет содержимое директории /tmp, а так же выводит реальный путь каталога /tmp/sessions.

var_dump(glob('/tmp/*'));

Откройте скрипт в браузере. Вы увидите, что содержимое в браузере кардинально отличается от содержимого реальной папки /tmp. На скриншоте мы видем вывод из консоли и из браузера — результат совершенно разный.

2018-06-02-12:32:03_1625x863

Как это побороть? Использовать другой каталог для хранения сессий. Или перед стартом приложения проверять и создавать в случае необходимости нужную файловую структуру.

session_start(): Session data file is not created by your uid

Не самая распространенная ошибка. Чаще всего возникает в виртуальных окружениях.

Ошибка возникает в случае, когда uid владельца файла сессии не совпадает с uid текущего пользователя под которым запущен интерпретатор.

Как проверить, что это именно наш случай? Нужно создать скрипт, которыый создает файл в каталоге, в котором вы планируете размещать сессии и сверяет uid владельца файла и uid владельца процесса.

$file = __DIR__ . DIRECTORY_SEPARATOR . 'file.name';
$fd = fopen($file, 'w');
fwrite($fd, 'test data');
fclose($fd);
if (file_exists($file)) {
    $stat = stat($file);
    var_dump($stat['uid'] == posix_getuid());
}

Если мы увидим false, то да. Проблема имеет мысто быть. И вам нужно переместить сессии в другое место.

Так же подобное поведение характерно при некоторых способах монтирования nfs.

session_start(): open(filename, O_RDWR) failed: Permission denied

Каталог недоступен для записи и достаточно дать права 777. Но тут не все так очевидно и данный трюк действует не всегда. Если вы работаете в дистрибутивах, которые используют selinux, то даже при установке полных прав система можем вам не позволить писать по выбранному пути.

Это происходит потому что контекст процесса отличается от контекста папки. Вы всегда можете посмотреть в /var/log/audit/audit.log чтобы убедиться.

Как обращаться с контекстами можно подробнее посмотреть в документации и в книге.

Литература

HowTo, linux

Управление цветом в Linux

01-introЕсть такая штука под названием «уветовые профили». Казалось бы все о них слышали, но немногие умеют их использовать и понимают, зачем это вообще надо.

То, что мы воспринимаем как свет — это лишь электромагнитные колебания с длиной волны от 380-400 нм до 760-780 нм. В этом диапазоне смешались все цвета от красного к филетовому.

02-spectrum
https://ru.wikipedia.org/wiki/Свет

Когда мы видим радугу, то мы видим весь спектр цветов. А вот несовершенные электронные приборы могут отобразить лишь определенные цвета радуги. Называется это цветовым охватом — множество доступных для восприятия человеческим глазом цветов, которые способно воспроизвести устройство. У всей техники разные диаграммы цветопередачи.

Именно поэтому для каждого устройства в системе нужно задать цветовой профиль, который как раз и описывает диапазон цветового охвата.

Почему это важно? Можно пояснить на примере двух инженеров у одного из которых линейка метрическая, а у второго дюймовая. Если один другому скажет, что нужно начертить линию длиной два, то случится нечто странное: линия будет иметь длину два, но в той системе измерений, в которой работает человек.

То же самое с техникой. Если для нас цвето RGB(200, 0, 0) — это красный с каким-то уровнем насыщенности, то для принтера он может быть совершенно другим. Поэтому перед печатью все должно быть сконвертировано с учетом цветового профили устройства.

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

Когда мы просто печатаем текст на компьютере, то нас не сильно волнует, как это се конвертируется, но когда при печати фотографии мы получим цвета, которых на экране не видели, то пора что-то менять. 🙂

Читать далее

linux

Fedora: сброс политик SELinux в дефолт

getenforceSELinux штука очень мощная и полезная. Но вот незадача: иногда ее настроить бывает слишком тяжело. И можно просто довести систему до состояния, когда она не загружается (особенно если играться с политикой доступа к каталогам :)).
Для таких случаев нужно уметь сбрасывать политики в дефолтное состояние.
Сначала загружаем систему в failback-режиме (там selinux отключен).

Теперь

setenforce 0
# dnf erase selinux-policy selinux-policy-targeted
# dnf mv /etc/selinux/targeted{,.backup}
# reboot

После перезагрузки системы selinux будет отключен.

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

# dnf install selinux-policy selinux-policy-targeted

И теперь включить сам механизм. Для этого отредактируем файл /etc/selinux/config и заменим

SELINUX=disabled

на

SELINUX=enforcing

После очередной перезагрузки мы увидим, что с SELinux все хорошо.

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

Документация.