Кэширование PHP без вмешательства в права доступа к файлам (также, Как эмулировать переменные ASP-приложения в PHP) - PullRequest
1 голос
/ 22 января 2009

Я пытаюсь реализовать какое-то кэширование в PHP-скрипте, который будет использоваться многими клиентами / сайтами, которые будут развернуты довольно нетехническими пользователями с использованием различных веб-хостов. Из-за нетехнического характера пользователей я бы не стал просить их настроить права доступа к файлам. Кэширование должно происходить между сеансами, поэтому использование переменных сеанса запрещено. Если бы я кодировал это в ASP, я бы использовал переменные приложения, но они не существуют в PHP (насколько мне известно)

Кто-нибудь есть какие-либо предложения о том, как это сделать?

Вот некоторые возможности, которые я рассмотрел, любые комментарии по ним будут полезны:

  • Кэширование с помощью файлов в системных временных папках - я мог бы использовать sys_get_temp_dir () (или некоторую аналогичную функцию на PHP4), чтобы помочь найти такую ​​папку. Недостатком здесь является то, что он, вероятно, не будет работать на хостах, использующих ограничение openbase_dir
  • На каком-то веб-сайте, на котором я смотрел, упоминалось, что PHP заставляет все пользовательские сеансы использовать одно и то же состояние сеанса, заставляя переменные сеанса действовать как переменные сеанса. Конечно, я не могу найти этот пост сейчас ... Это кажется страшным в любом случае. (Я обновлю этот вопрос ссылкой на этот пост, как только найду его снова)
  • Использовать стороннее хранилище данных, такое как Amazon Simple Storage Service - похоже, излишнее
  • Кэшировать данные на сервере, которым я управляю, и заставлять клиента загружать оттуда новые данные при каждом обращении.

Еще раз, любые комментарии к этим идеям или любые новые будут оценены.

ОБНОВЛЕНИЕ: Я пытался использовать 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 к учетной записи общего хостинга, которая просто работает из коробки.

ОБНОВЛЕНИЕ: кто-то предложил создать мою собственную папку кэша с помощью скрипта, но разве мне не нужно было создавать такую ​​папку внутри папки, у которой уже были разрешения на запись?

ОБНОВЛЕНИЕ, НАЙДЕНО РЕШЕНИЕ: В итоге я выяснил проблемы в моем глобальном сценарии сеанса и опубликовал свой собственный ответ на этот счет. Спасибо всем за помощь.

Ответы [ 6 ]

2 голосов
/ 23 января 2009

Хорошо, я понял, как это сделать, эмулируя переменные приложения в стиле ASP, используя общее / глобальное состояние сеанса. Два ключевых изменения из моего нерабочего кода в соответствующем обновлении:

  1. Чтобы переключить состояние сеанса, мы должны завершить текущий сеанс, переключиться на новый, а затем запустить его. Я инкапсулировал этот процесс в switch_session ()

  2. Поскольку мы переключаем идентификаторы сеансов, мы должны буферизовать вывод страницы с помощью 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();
?>

1 голос
/ 22 января 2009

Используйте свой собственный каталог кеша в каталоге вашего приложения. При этом вам не нужно бороться с различными настройками сервера и / или PHP и получать наилучшую переносимость.

1 голос
/ 22 января 2009

Вы можете использовать сеансы с фиксированным ключом сеанса.

http://de.php.net/manual/en/function.session-id.php:

session_id ([id]) используется для получения или установки сеанса id для текущего сеанса. Если указан идентификатор, он заменит текущий идентификатор сессии. Для этого необходимо вызвать session_id () перед session_start ().

0 голосов
/ 22 января 2010

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

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

0 голосов
/ 22 января 2009

Проверьте memcached для php - он работает очень хорошо.

http://www.php.net/memcache

0 голосов
/ 22 января 2009

Я голосую за «Кэширование данных на сервере, которым я управляю, и чтобы клиент загружал оттуда новые данные при каждом обращении».

Все остальные пути ведут к определенному безумию.

...