Pergunta

Já tropeçou em um tutorial que você sente é de grande valor, mas não completamente explicadas adequadamente? Esse é o meu dilema. Eu sei Este tutorial tem algum valor, mas eu simplesmente não pode obtê-lo.

  1. Onde você chamar cada função?
  2. Qual função deve ser chamado primeiro e qual em seguida, e que terceiro?
  3. Será que todas as funções de ser chamado em todos os arquivos em um aplicativo?
  4. Alguém sabe de uma maneira melhor cura os "botão voltar Blues"?

Eu estou querendo saber se isso vai agitar uma boa conversa que inclui o autor do artigo. A parte que eu estou particularmente interessado em se controlar o botão de volta, a fim de evitar que formam entradas duplicadas em um banco de dados quando o botão Voltar é pressionado. Basicamente, você quer controlar o botão de volta através dos seguintes três funções durante a execução dos scripts na sua aplicação. Em que ordem exatamente para chamar as funções (ver perguntas acima) não está claro a partir do tutorial.

Movimento Todos os forwards é realizada por usando minha função scriptNext. Isto é chamado de dentro do script atual em Para ativar o novo script.

function scriptNext($script_id)
// proceed forwards to a new script
{
   if (empty($script_id)) {
      trigger_error("script id is not defined", E_USER_ERROR);
   } // if

   // get list of screens used in this session
   $page_stack = $_SESSION['page_stack'];
   if (in_array($script_id, $page_stack)) {
      // remove this item and any following items from the stack array
      do {
         $last = array_pop($page_stack);
      } while ($last != $script_id);
   } // if

   // add next script to end of array and update session data
   $page_stack[] = $script_id;
   $_SESSION['page_stack'] = $page_stack;

   // now pass control to the designated script
   $location = 'http://' .$_SERVER['HTTP_HOST'] .$script_id;
   header('Location: ' .$location); 
   exit;

} // scriptNext

Quando qualquer script terminou o seu processamento termina chamando a minha função scriptPrevious. Isso vai soltar o script atual a partir do final da matriz pilha e reactivar o script anterior na matriz.

function scriptPrevious()
// go back to the previous script (as defined in PAGE_STACK)
{
   // get id of current script
   $script_id = $_SERVER['PHP_SELF'];

   // get list of screens used in this session
   $page_stack = $_SESSION['page_stack'];
   if (in_array($script_id, $page_stack)) {
      // remove this item and any following items from the stack array
      do {
         $last = array_pop($page_stack);
      } while ($last != $script_id);
      // update session data
      $_SESSION['page_stack'] = $page_stack;
   } // if

   if (count($page_stack) > 0) {
      $previous = array_pop($page_stack);
      // reactivate previous script
      $location = 'http://' .$_SERVER['HTTP_HOST'] .$previous;
   } else {
      // no previous scripts, so terminate session
      session_unset();
      session_destroy();
      // revert to default start page
      $location = 'http://' .$_SERVER['HTTP_HOST'] .'/index.php';
   } // if

   header('Location: ' .$location); 
   exit;

} // scriptPrevious

Sempre que um script é ativado, o que pode ser, quer através da scriptNext ou scriptPrevious funções, ou por causa do botão BACK no navegador, ele irá chamar o seguinte função para verificar se ele é o script atual de acordo com o conteúdo da pilha do programa e tomar medidas adequadas, se não é.

function initSession()
// initialise session data
{
   // get program stack
   if (isset($_SESSION['page_stack'])) {
      // use existing stack
      $page_stack = $_SESSION['page_stack'];
   } else {
      // create new stack which starts with current script
      $page_stack[] = $_SERVER['PHP_SELF'];
      $_SESSION['page_stack'] = $page_stack;
   } // if

   // check that this script is at the end of the current stack
   $actual = $_SERVER['PHP_SELF'];
   $expected = $page_stack[count($page_stack)-1];
   if ($expected != $actual) {
      if (in_array($actual, $page_stack)) {// script is within current stack, so remove anything which follows
      while ($page_stack[count($page_stack)-1] != $actual ) {
            $null = array_pop($page_stack);
         } // while
         $_SESSION['page_stack'] = $page_stack;
      } // if
      // set script id to last entry in program stack
      $actual = $page_stack[count($page_stack)-1];
      $location = 'http://' .$_SERVER['HTTP_HOST'] .$actual;
      header('Location: ' .$location);
      exit;
   } // if

   ... // continue processing

} // initSession

A ação tomada depende se o script atual existe dentro do pilha do programa ou não. Há três possibilidades:

  • O script atual não está no array $ page_stack, caso em que é não tem permissão para continuar. Em vez disso, é substituído pelo script que está no final da matriz.
  • O script atual está na $ Array page_stack, mas não é o Última entrada. Neste caso, todos seguinte entradas na matriz está removida.
  • O script atual é a última entrada na matriz $ page_stack. Isto é a situação esperado. bebe tudo ! Rodada
Foi útil?

Solução

Essa é uma boa discussão, mas mais para o ponto que você deve estar olhando para pós Redirect Get (PRG), também conhecido como "Get após Post."

http://www.theserverside.com/patterns/thread.tss ? thread_id = 20936

Outras dicas

Se você não entender o meu artigo, então você deve ter um olhar mais atento sobre Figura 1 que retrata um cenário típico em que um usuário passa por uma série de telas - logon, menu, lista, pesquisar, adicionar e atualização. Quando descrevo um movimento de atacantes quero dizer que a tela atual é suspensa enquanto uma nova tela é ativada. Isso acontece quando o usuário pressiona um link na tela atual. Quando descrever um movimento como PARA TRÁS que significa que o utilizador termina a tela corrente (premindo o botão de PARAR ou ENVIAR) e retorna para o ecrã anterior, a qual continua o processamento a partir de onde parou. Isso pode incluir incorporando todas as alterações feitas na tela que acaba de ser encerrado.

Este é o lugar onde a manutenção de uma pilha de página que é independente do histórico do navegador é crucial - a pilha de página é mantida pela aplicação e é utilizado para verificar todas as solicitações. Estes podem ser válido na medida em que o navegador está em causa, mas podem ser identificados pela aplicação como inválido e tratadas em conformidade.

A pilha de página é mantida por duas funções:

  • scriptNext () é usado para processar uma FRENTE movimento, que acrescenta uma nova entrada no final da pilha e ativa a nova entrada.
  • scriptPrevious () é usado para processo um movimento TRÁS, que remove a última entrada da pilha e re-ativa a entrada anterior.

Agora pegue a situação no exemplo onde o usuário navegou para página 4 do ecrã da lista, ido para a tela de ADD, em seguida, retornou à página 5 do ecrã da lista. A última ação na tela de ADD foi para pressionar o botão que usou o método POST para enviar dados para o servidor que foram adicionados ao banco de dados, após o que automaticamente rescindido e retornou ao ecrã da lista ENVIAR.

Se, portanto, você pressiona o botão BACK enquanto na página 5 do ecrã da lista de histórico do navegador irá gerar uma solicitação para a última ação na tela da ADD, que era um POST. Este é um pedido válido na medida em que o navegador está em causa, mas não é tão longe como a aplicação está em causa. Como pode a aplicação decidir que o pedido é inválido? Ao verificar com sua pilha página. Quando a tela ADD foi encerrado sua entrada foi excluída da pilha de página, portanto, qualquer pedido de uma tela que não é na pilha de página pode ser sempre tratados como inválidos. Neste caso, o pedido inválido pode ser redirecionado para a última entrada na pilha.

As respostas às suas perguntas devem, portanto, ser óbvio:

  • Q: Onde você chamar cada função
  • A: Você chamar o scriptNext () função, quando o utilizador escolhe navegar para a frente para uma nova tela, e chamar o scriptPrevious () função quando termina o usuário a tela atual.
  • Q: Qual função deve ser chamado primeiro e qual em seguida, e que terceiro?
  • A: Cada função é chamada em resposta a uma ação escolhida pelo utilizador, portanto, apenas uma função é usada de cada vez.
  • Q: Será que todas as funções de ser chamado todos os arquivos em um aplicativo?
  • A: Todas as funções devem estar disponíveis em todos os arquivos em um aplicativo, mas só será chamado quando escolhido pelo usuário.

É você deseja ver estas idéias em ação, então você pode baixar o meu amostra aplicação .

A parte que eu estou particularmente interessado em se controlar o botão de volta, a fim de evitar que formam entradas duplicadas em um banco de dados quando o botão Voltar é pressionado.

A sua premissa é errada. Não existe tal coisa como "botão voltar Blues", se você projetar seu aplicativo como um aplicativo web. Se você projetar sua aplicação sem qualquer estado do lado do servidor, você nunca vai executar para esse problema no primeiro caso. Esta abordagem minimalista para aplicações web funciona muito bem, e é geralmente conhecido como REST.

@ troelskn

Se você projetar sua aplicação sem qualquer estado do lado do servidor ....

Não é possível conceber uma aplicação eficaz, que não tem estado, caso contrário, tudo que você tem é uma coleção de páginas individuais que não se comunicam uns com os outros. Como manter o estado em que o cliente está repleto de questões não existe alternativa eficaz, mas para manter o estado no servidor.

@Marston.

Eu resolvi o problema com post / redirecionamento / get mas acredito que o tutorial tem algum mérito e, talvez, Tony Marston pode elaborar sobre isso. E como poderia ser usada para resolver não necessariamente o meu problema particular, mas talvez algo similar. Ou como é que é melhor do que post / redirecionamento / get se as funções de fato pode ser usado para resolver o meu problema particular. Acho que isso vai ser um bom complemento para a comunidade aqui.

if ($_POST) {
    process_input($_POST);
    header("Location: $_SERVER[HTTP_REFERER]");
    exit;
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top