PHP cache sem mexer com permissões de arquivo (Além disso, Como emular variáveis ??ASP aplicação em PHP)

StackOverflow https://stackoverflow.com/questions/470399

Pergunta

Eu estou tentando implementar algum tipo de cache em um script PHP que vai sair para diversos clientes / sites, que serão implantados pelos usuários bastante não-técnicos, usando uma variedade de hospedeiros web. Devido à natureza não-técnica dos usuários, eu gostaria de evitar pedindo-lhes para ajustar as permissões de arquivo. As necessidades de armazenamento em cache para ser entre sessões, portanto, usando variáveis ??de sessão está fora. Se eu estava codificação isso em ASP eu usaria variáveis ??de aplicativo, mas eles não existem em PHP (que eu saiba)

Alguém tem alguma sugestão sobre como fazer isso?

Aqui estão algumas possibilidades que eu considerados, quaisquer comentários sobre estes seriam úteis:

  • Caching através de arquivos em pastas temporárias do sistema - Eu poderia usar sys_get_temp_dir () (ou alguma casa rolou função semelhante no PHP4) para ajudar a encontrar uma pasta. A desvantagem aqui, é que provavelmente não iria funcionar em hosts usando a restrição openbase_dir
  • Alguns website Olhei para PHP enganando mencionado em fazer todas as sessões de usuários compartilham o mesmo estado de sessão forçando assim as variáveis ??de sessão para agir como variáveis ??de sessão. Claro que eu não consigo encontrar esse post agora ... Isto parece de qualquer maneira assustadora. (Eu vou atualizar esta questão com o link para este post uma vez que eu encontrá-lo de novo)
  • Use um armazenamento de dados de terceiros, como Simple Storage Service da Amazon - parece um exagero
  • Cache os dados em um controle de servidor que eu, e ter o download do cliente novos dados de lá em cada hit.

Mais uma vez, qualquer comentário sobre estas ideias ou quaisquer novos seria apreciada.

UPDATE: Eu tentei usar session_id () para usar um estado de sessão compartilhada, mas ele não funciona. Cada sessão é manter seu próprio "GlobalCache", todas as idéias porquê:?

// 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();

UPDATE: alguns sugeriram o uso de memcached, que é na verdade uma grande solução para alguns, mas desde que eu não tenho controle sobre o ambiente de servidor final não é uma opção. A idéia é ter um script que as pessoas podem apenas FTP-se para uma conta de hospedagem compartilhada que só funciona fora da caixa.

UPDATE: alguém sugeriu a criação de minha própria pasta de cache com o roteiro, mas eu não teria necessidade de criar tal pasta dentro de uma pasta que já tinha permissões de gravação?

UPDATE, encontrado Solução: eu acabei descobrindo os problemas no meu script de sessão global e colocaram a minha própria resposta para esse efeito. Obrigado pela ajuda a todos.

Foi útil?

Solução

Ok, eu descobri como fazer isso emulando variáveis ??de aplicativo estilo ASP usando um estado de sessão shared / global. Duas mudanças-chave de meu código não-trabalhando na atualização relevante:

  1. Para o estado da sessão switch, que deve terminar a sessão atual, mude para o novo, em seguida, iniciá-lo. Eu encapsulado este processo em switch_session ()

  2. Uma vez que estão migrando ids de sessão em torno de nós temos para o buffer de saída usando ob_start da página () / ob_end_flush () para que o cookie de sessão não é enviado muito em breve.

O código inteiro de trabalho segue (limpado também!). Isso pode ser facilmente testado por carregar a página em um IE e uma janela do Firefox, e recarregando cada várias vezes para assistir os contadores de subir:

<?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();
?>

Outras dicas

Você pode usar sessões com uma chave de sessão fixo.

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

session_id ([id]) é usado para obter ou definir o id sessão para a sessão atual. Se id for especificado, ele irá substituir o id da sessão atual. session_id () precisa ser chamado antes de session_start () para esse fim.

Use o seu próprio dir cache no dir do seu aplicativo. Com isso você não tem que lutar com vários servidor e / ou configuração do PHP e obter a melhor portabilidade.

Eu voto para "Cache os dados em um controle de servidor que eu, e ter o download do cliente novos dados de lá em cada hit."

Todos os outros caminhos levam a certa loucura.

Confira memcached para PHP ele funciona muito bem.

http://www.php.net/memcache

Eu usei a função atualizada pelo autor como uma maneira de armazenar em cache um resultado de consulta de banco de dados simples, já que eu estava esperando carga elevada. Eu também armazenou um timestamp para que eu pudesse definir quantas vezes a página iria renovar o resultado do banco de dados ao invés de apenas tomar o valor em cache.

Eu posso dizer-lhe que esta função de cache tinha muito muito muito pior desempenho do que ir direto para o banco de dados em cada solicitação. Eu realmente matou o servidor. Uma vez que eu mudei de volta para simplesmente consultando o banco de dados do servidor tem até a velocidade máxima eo muito grande de carga não foi notado.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top