Php 治好",;“后退按钮蓝色”;

Php 治好",;“后退按钮蓝色”;,php,forms,button,back,Php,Forms,Button,Back,有没有偶然发现一个你觉得很有价值但解释得不太恰当的教程?这就是我的困境。我知道它有一些价值,但我就是得不到 在哪里调用每个函数 应该调用哪个函数 第一个,下一个,哪个 第三 是否在应用程序的所有文件中调用所有函数 有谁知道有更好的方法来治疗“后退按钮忧郁症”吗 我想知道这是否会激起一些包括文章作者在内的良好对话。我特别感兴趣的部分是控制back按钮,以防止按下back按钮时在数据库中形成重复条目。基本上,您希望通过在应用程序中执行脚本期间调用以下三个函数来控制back按钮。调用函数的顺序(参见上

有没有偶然发现一个你觉得很有价值但解释得不太恰当的教程?这就是我的困境。我知道它有一些价值,但我就是得不到

  • 在哪里调用每个函数
  • 应该调用哪个函数 第一个,下一个,哪个 第三
  • 是否在应用程序的所有文件中调用所有函数
  • 有谁知道有更好的方法来治疗“后退按钮忧郁症”吗
  • 我想知道这是否会激起一些包括文章作者在内的良好对话。我特别感兴趣的部分是控制back按钮,以防止按下back按钮时在数据库中形成重复条目。基本上,您希望通过在应用程序中执行脚本期间调用以下三个函数来控制back按钮。调用函数的顺序(参见上面的问题)在教程中并不清楚

    所有向前移动由 使用我的scriptNext函数。这是 在中的当前脚本中调用 以激活新脚本

    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
    
    当任何脚本完成其 通过调用我的 编写上一个函数的脚本。这将 从末尾删除当前脚本 并重新激活 数组中的上一个脚本

    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
    
    每当激活脚本时 可以通过脚本或下一步 或编写以前的函数,或 因为后面的按钮 浏览器,它将调用以下命令 函数来验证它是否为 当前脚本根据 程序堆栈和take的内容 如果不是,则采取适当的行动

    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
    
    采取的行动取决于 当前脚本存在于 程序堆栈与否。有三个 可能性:

    • 当前脚本不在$page_堆栈数组中,在这种情况下它是 不允许继续。而是 替换为位于 数组的末尾
    • 当前脚本位于 $page_堆栈数组,但它不是 最后一项。在这种情况下,所有 数组中的以下项是 删除
    • 当前脚本是最后一个条目 在$page_堆栈数组中。这是 预期的情况。全喝 轮

    这是一个很好的讨论,但更重要的是,您应该研究PostRedirectGet(PRG),也称为“发布后获取”

    我特别感兴趣的部分是控制back按钮,以防止按下back按钮时在数据库中形成重复条目

    你的前提是错误的。如果您将应用程序设计为web应用程序,则不存在“后退按钮蓝色”这样的东西。如果您在设计应用程序时没有任何服务器端状态,那么在第一种情况下永远不会遇到此问题。这种对web应用程序的极简方法非常有效,通常称为REST。

    @troelskn

    如果您设计的应用程序没有任何服务器端状态

    要设计一个没有状态的有效应用程序是不可能的,否则您所拥有的只是一个彼此不通信的单独页面的集合。由于在客户机上维护状态充满了问题,除了在服务器上维护状态之外,没有其他有效的选择。

    @Marston


    我用post/redirect/get解决了这个问题,但是我相信这个教程有一些优点,也许Tony Marston可以详细说明一下。如何用它来解决我的问题,不一定是我的特殊问题,也许是类似的问题。或者,如果这些函数实际上可以用于解决我的特定问题,那么它如何比post/redirect/get更好呢。我认为这将是对这里社区的一个很好的补充。

    如果你不理解我的文章,那么你应该仔细看看其中描述的一个典型场景,其中用户通过一系列屏幕–登录、菜单、列表、搜索、添加和更新。当我描述向前移动时,我的意思是当前屏幕被暂停,而新屏幕被激活。当用户按下当前屏幕中的链接时会发生这种情况。当我将移动描述为向后移动时,我的意思是用户终止当前屏幕(通过按退出或提交按钮)并返回到上一个屏幕,该屏幕从停止的位置恢复处理。这可能包括合并刚刚终止的屏幕中所做的任何更改

    这就是维护独立于浏览器历史记录的页面堆栈的关键所在–页面堆栈由应用程序维护,并用于验证所有请求。就浏览器而言,这些可能是有效的,但应用程序可能会将其标识为无效并进行相应处理

    页面堆栈由两个函数维护:

    • scriptNext()用于处理 向前移动,这增加了一个新的 堆栈末尾的条目,以及 激活新条目
    • scriptPrevious()用于处理 一种向后的运动,它使 堆栈中的最后一个条目和 重新激活上一个条目
    现在以示例中的情况为例,用户导航到列表屏幕的第4页,进入添加屏幕,然后返回列表屏幕的第5页。添加屏幕中的最后一个操作是按下SUBMIT按钮,该按钮使用POST方法将添加到数据库的详细信息发送到服务器,然后服务器自动终止并返回列表屏幕

    因此,如果在列表屏幕的第5页按下后退按钮,浏览器历史记录将生成添加屏幕上最后一个操作的请求,这是一个POST。就浏览器而言,这是一个有效的请求,但就应用程序而言,这不是一个有效的请求。应用程序如何确定请求无效?签入
    if ($_POST) {
        process_input($_POST);
        header("Location: $_SERVER[HTTP_REFERER]");
        exit;
    }