Есть файл конфига, который возвращает массив значений. Содержимое:
<?php return (array ());
В классе работы с конфигами, подключаю этот файл и получаю его значение так:
$arr = include($full_path);
Потом стоит проверка if(!is_array($arr))...
и в случае если это не массив - выбрасывается исключение.
Возникла странная проблема. На корректное содержимое конфига, однажды я получил исключение. Я проверил файл конфига, он в порядке.
Ошибка возникает тогда, когда выполняется сохранение конфига. Если очень быстро обновить страницу, в одной из итераций получится выбить ошибку. Без сохранения ошибка кажется не возникает.
Сохраняю конфиг функцией file_put_contents
. Конечно я сразу же подумал что проблема в LOCK_EX
, но это не так! Я убирал этот параметр, ошибка хоть и появлялась реже, она осталась и несколько раз мне удалось её отловить.
Если ДО строчки с проверкой if(!is_array($arr))...
вставить var_dump(file_get_contents($full_path))
, ошибку отловливать не получается (у меня не получилось во всяком случае, думаю файл ждет загрузки, а инклуд нет - это основная догадка). Сама же переменная $arr
содержит 1, если её вызвать до выброса исключения, что говорит о том что файл "успешно" подключен.
Обратите внимание на то, что ошибка возникает после быстрого обновления страницы и не сразу. Я пробовал до инклуда вставлять условие с is_readable, оно вообще ни разу не выдало false.
Учтите, сохранение проходит без проблем. Учтите, ошибка проявляется не каждый раз, и не имеет четкого триггера для вызова, поймать её можно обновляя страницу много раз и быстро (ну или зажав f5), при этом время зажатия не определено.
Если кто-то знает в чем причина такого поведения, помогите найти решение.
Моя задача, избавиться от ошибки. Если это невозможно, то хотя бы найти способ выбрасывать конкретную ошибку вроде "файл сейчас недоступен для подключения"
Код класса и конфига
В php используется рекомендательная блокировка. Защита файла от конкурентного доступа работает только если все писатели и читатели ипользуют в доступе LOCK_(EX|SH). Те, кто не использует флаги LOCK_(EX|SH), будут бесконтрольно писать и читать в любой момент.
В php с этим плохо. file(), include, require
и так далее - не используют блокировку, даже file_put_contents(LOCK_EX)
есть, а file_get_contents (LOCK_SH)
не существует.
Если не нужно редактировать файл, а полностью перезаписывать, и старое содержимое файла не влияет на новое, то можно писать во временный файл и потом делать rename
этого файла в нужное имя.
При записи во временный файл с рэндомным именем нет конкурентного доступа, а rename
атомарен.
При таком подходе никто не должен писать в конечный файл напрямую.
Файл 1.
<?php
function getConfig($full_path) {
return (array());
}
Файл 2.
<?php
include('файл1.php');
$arr = getConfig($full_path);
if(!is_array($arr))...
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Делаю выборку по городу, у города есть районы, у них комплексы, а у комплексов квартирыВ конечном итоге мне нужно получить квартиры для определенного...
Кладу в папку с сайтом все нужный файлы и indexphp в итоге рисует мне страничку, но без стилей
http://phpnet/manual/en/function
Добрый день, хотим запустить скрипт, который рандомом на протяжении всего дня будет запускать различные функции