Я пытаюсь реализовать какое-то кеширование в сценарии PHP, который будет распространяться на множество разных клиентов / сайтов, которые будут развертываться довольно нетехническими пользователями с использованием различных веб-хостов. Из-за нетехнического характера пользователей я бы не хотел просить их настраивать права доступа к файлам. Кеширование должно осуществляться между сеансами, поэтому использование переменных сеанса не допускается. Если бы я кодировал это в ASP, я бы использовал переменные приложения, но они не существуют в PHP (насколько мне известно)
Есть ли у кого-нибудь предложения о том, как это сделать?
Вот некоторые возможности, которые я рассмотрел, любые комментарии по ним были бы полезны:
Еще раз, любые комментарии к этим идеям или любые новые были бы признательны.
ОБНОВИТЬ: Я пробовал использовать session_id () для использования общего состояния сеанса, но это не сработало. Каждая сессия поддерживает свой собственный "GlobalCache", есть идеи, почему ?:
// This code doesn't work, but the similar code in my answer does!
function test() {
if (!$_SESSION['session_count']) $_SESSION['session_count'] = 0;
$_SESSION['session_count']++;
$count = get_cache( 'count' );
print "pre application count: $count<br>";
if ( !$count )
$count = 0;
$count++;
print "session_id: " . session_id() . "<br>";
print "post application count: $count<br>";
print "session_count: " . $_SESSION['session_count'] . "<br>";
set_cache('count', $count);
}
function set_cache( $name, $value ) {
$old_session = session_id();
print "old_session (set): $old_session<br>";
session_id("GlobalCache");
print "new_session (set): " . session_id() . "<br>";
$_SESSION[$name] = $value;
session_id( $old_session );
}
function get_cache( $name ) {
$old_session = session_id();
print "old_session (get): $old_session<br>";
session_id("GlobalCache");
print "new_session (get): " . session_id() . "<br>";
$value = $_SESSION[$name];
session_id( $old_session );
return $value;
}
session_start();
test();
ОБНОВИТЬ: некоторые предлагали использовать memcached, что на самом деле является отличным решением для некоторых, но, поскольку у меня нет контроля над средой конечного сервера, это не вариант. Идея состоит в том, чтобы иметь сценарий, который люди могут просто использовать FTP до учетной записи общего хостинга, которая просто работает из коробки.
ОБНОВИТЬ: кто-то предложил создать мою собственную папку кеша с помощью скрипта, но разве мне не нужно создавать такую папку внутри папки, у которой уже есть права на запись?
ОБНОВЛЕНИЕ, РЕШЕНИЕ НАЙДЕНО: В итоге я выяснил проблемы в моем сценарии глобального сеанса и опубликовал свой собственный ответ на этот счет. Спасибо всем за помощь.






Я голосую за "Кэшировать данные на сервере, который я контролирую, и предлагать клиенту загружать оттуда новые данные при каждом обращении".
Все остальные пути ведут к определенному безумию.
Вы можете использовать сеансы с фиксированным ключом сеанса.
http://de.php.net/manual/en/function.session-id.php:
session_id([id]) is used to get or set the session
idfor the current session. If id is specified, it will replace the current session id. session_id() needs to be called before session_start() for that purpose.
Используйте свой собственный каталог кеша в каталоге вашего приложения. Таким образом, вам не придется бороться с различными настройками сервера и / или PHP, и вы получите лучшую переносимость.
… И защитите его от запросов из Интернета.
Проверьте memcached для php - он действительно хорошо работает.
memcache - это круто, но здесь это не вариант, поскольку я не контролирую сервер, на котором будут развернуты копии моего скрипта.
Хорошо, я понял, как это сделать, эмулируя переменные приложения в стиле ASP с использованием общего / глобального состояния сеанса. Два ключевых изменения из моего неработающего кода в соответствующем обновлении:
Чтобы переключить состояние сеанса, мы должны завершить текущий сеанс, переключиться на новый, а затем запустить его. Я инкапсулировал этот процесс в switch_session ()
Поскольку мы переключаем идентификаторы сеансов, мы должны буферизовать вывод страницы с помощью ob_start () / ob_end_flush (), чтобы cookie сеанса не отправлялся слишком рано.
Далее следует полный рабочий код (тоже очищенный!). Это можно легко проверить, загрузив страницу в окнах IE и Firefox и перезагрузив каждую по несколько раз, чтобы увидеть рост счетчиков:
<?php
function test() {
// Do a regular session count
print "session_id: " . session_id() . "<br>";
if (!$_SESSION['session_count']) $_SESSION['session_count'] = 0;
$_SESSION['session_count']++;
print "session count: " . $_SESSION['session_count'] . "<br>";
// Do an application count
$count = get_cache( 'count' );
if ( !$count ) $count = 0;
$count++;
print "application count: $count<br>";
set_cache('count', $count);
}
function set_cache( $name, $value ) {
$old_session = switch_session("GlobalCache");
$_SESSION[$name] = $value;
switch_session( $old_session );
}
function get_cache( $name ) {
$old_session = switch_session("GlobalCache");
$value = $_SESSION[$name];
switch_session( $old_session );
return $value;
}
function switch_session( $session_id ) {
// switch the session and return the original
$old_id = session_id();
session_write_close();
session_id($session_id);
session_start();
return $old_id;
}
ob_start();
session_start();
test();
ob_end_flush();
?>
Я использовал обновленную функцию автора как способ кэшировать простой результат запроса к базе данных, так как ожидал высокой нагрузки. Я также сохранил метку времени, чтобы я мог определить, как часто страница будет обновлять результат базы данных, а не просто принимать кешированное значение.
Я могу сказать вам, что эта функция кеширования имела намного худшую производительность, чем прямая работа с базой данных при каждом запросе. Я действительно убил сервер. Как только я вернулся к простому обращению к базе данных, сервер набрал полную скорость, и довольно большая нагрузка даже не была замечена.
И убедитесь, что подкаталог кеша создается PHP во время первого запуска, поэтому он является владельцем каталога и может писать в него позже.