【问题标题】:PHP include is re-run on AJAX Request. Is this normal behavior?PHP 包含在 AJAX 请求上重新运行。这是正常行为吗?
【发布时间】:2012-01-03 09:36:22
【问题描述】:

我有一个 header.inc.php、实际的 php 网页和一个 footer.inc.php。实际页面还使用将活动记录到数据库的包含。如此简化我的页面如下所示:

<?php
    require_once 'header.inc.php';
    require_once 'insertSearchLog.inc.php';
?>
<!--HTML and JavaScript for AJAX-->
<?php
    require_once 'footer.inc.php';
?>

AJAX 是使用带有 JQuery 插件数据表的 JQuery 完成的。

问题是包含 insertSearchLog.inc.php 对显示的数据表中的每一行执行一次,这对我来说没有意义? AJAX 的重点不是重新加载整个页面吗? 如何防止这种行为?

附加评论:似乎是 IE8 的 FireFox 问题,不会发生此问题!

编辑:

为了避免这个问题,我在插入日志之前添加了一个检查:

$searchString = $_SERVER['QUERY_STRING'];
if (!isset($_SESSION['lastQueryString'])
        || $searchString != $_SESSION['lastQueryString']) {

    // insert into log snipped

    $_SESSION['lastQueryString'] = $searchString;
}

但最初的问题仍然存在,如果这是默认的 firefox 行为,我会觉得非常令人费解。

编辑 2:部分(为简洁起见)JS 代码:

$(document).ready(function() {
    // ..snipped unrelated content

    $('#result').dataTable( { // initialize datatables plugin
        "bProcessing": true,
        "bServerSide": true,
        // ... snipped further initialization parameters of datatables
        "fnServerData": function ( sSource, aoData, fnCallback ) {                
            // ...snipped setting GET parameters for AJAX request
            $.ajax( {
                "dataType": 'json',
                "type": "GET",
                "url": sSource,
                "data": aoData,
                "success": fnCallback
            } );
        }
    } );        
} );

“结果”是一个 HTML 表格元素,数据将在其中显示。

header 和 footer.inc.php 根据要求,很明显它与问题无关:

<!-- start header.inc.php-->
<?php
session_start();
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
    "http://www.w3.org/TR/html4/strict.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <link href="../sharedRessources/css/main.css" type="text/css" rel="stylesheet" media="all">        
        <link href="../sharedRessources/css/datatables/demo_table.css" rel="stylesheet" type="text/css">               
        <script type="text/javascript" src="../sharedRessources/js/jquery-1.6.2.js"></script>        
        <script type="text/javascript" src="../sharedRessources/js/jquery.dataTables.min.js"></script> 
        <title>myApp</title>
    </head>
    <body>
        <div id="wrapper">
            <div id="head">
                <h2>myApp</h2>
                <hr>
            </div>

            <div id="columns">

<!-- end header.inc.php-->

            <!--page content-->

<!-- start footer.inc.php-->

            <?php
                if (!empty($_SESSION['Message'])) {

                    echo '<div class="message">' . $_SESSION['Message'] . '</div>';
                    unset($_SESSION['Message']);
                }
                if (!empty($_SESSION['Error'])) {

                    echo '<div class="error">' . $_SESSION['Error'] . '</div>';
                    unset($_SESSION['Error']);
                }
            ?>            
            </div>
            <div id="foot">
                <hr>
                <small>Copyright 2011</small>
            </div>
        </div>
    </body>
</html>
<!-- end footer.inc.php-->

插入Searchlog.inc.php:

<?php
    if (isset($_GET)) {

        $searchString = $_SERVER['QUERY_STRING'];

        if (!isset($_SESSION['lastQueryString'])
                || $searchString != $_SESSION['lastQueryString']) {

            $conn = getDatabaseConnection();
            if (!$conn) {
                $e = oci_error();
                trigger_error(htmlentities($e['message'], ENT_QUOTES), E_USER_ERROR);
            }
            $sqlLog = "INSERT INTO log_table (user_id,search_string) VALUES(:userId,:searchString)";
            $preparedStatement = oci_parse($conn, $sqlLog);
            oci_bind_by_name($preparedStatement, ':userId', $_SESSION['login']);
            oci_bind_by_name($preparedStatement, ':searchString', $searchString);
            oci_execute($preparedStatement);
            oci_free_statement($preparedStatement);
            oci_close($conn);
            $_SESSION['lastQueryString'] = $searchString;
        }
    }
?>

【问题讨论】:

    标签: php ajax firefox


    【解决方案1】:

    这是正常行为,您可以使用 jQuery.load() 仅选择要包含在页面上的元素,如下所示:

    $(element).load('page.php div#content')
    

    这样,您的页眉或页脚中的任何内容都不会被调用。

    或者,您可以通过 GET 请求将变量传递给服务器,并且仅在未设置变量时设置页眉和页脚:为您的 AJAX 请求调用此 URL:

    'page.php?ajax=true'
    

    然后把这个 PHP 放到你的 AJAX 页面中:

    <?php
      if (!isset($_GET['ajax']) {
        require_once('header.inc.php');
        require_once('insertSearchLog.inc.php');
      }
    
      // HTML etc...
    
      if (!isset($_GET['ajax']) {
        require_once('footer.inc.php');
      }
    

    【讨论】:

    • 如果它是正常的,为什么它在 IE8 中“像我预期的那样工作”? IE8错误?我仍然有点困惑,为什么 AJAX 调用会重新运行 php 脚本?我认为 AJAX 的意义在于不需要这样做。
    • 另请注意,ajax 调用可以返回多行,并且包含似乎被调用的次数与返回的行数一样多,即使它只是 1 个 AJAX 请求。 Firefox 3.6 和 9.0.1 中的行为也相同。
    • 因为在 jQuery 中使用 AJAX 加载请求会自动返回 标记中的所有内容,我的猜测是在早期版本的 IE 中,它不会这样做,而是返回所有 HTML。
    • 你是否真的尝试过这个解决方案,或者只是决定反对它而不看它是否有效?
    • 我认为他的意思是 $_GET['ajax'] 而不是 $_GET('ajax') 哈哈。 $_GET 不是函数。
    【解决方案2】:

    这取决于您通过 AJAX 加载的内容,如果您调用的 PHP 脚本包含那些需要行,那么每次您发出 AJAX 请求时都会调用它们。

    require_once 指令在脚本级别起作用,如果多次调用脚本,require_once 将被多次调用。

    创建一个单独的脚本来处理不需要日志记录功能的 AJAX 调用,或者将变量传递给 AJAX 调用,让脚本根据此变量的存在来决定是否需要。

    【讨论】:

    • 实际数据当然是在单独的脚本中检索的,因此包含应该只运行一次。由于它在 IE8 中按预期工作,我认为它是 a)firefox b)jquery 或 c)数据表问题,但在这里或使用谷歌没有找到任何东西。
    • 那么我建议添加更多信息。例如,您是如何进行 Ajax 调用的,可能有一些东西正在触发页面重新加载或其他东西。您提供的信息越多,人们就越容易回答您的问题。
    • 我确实发布了该信息。 ajax 调用由名为 datatables 的 JQuery 插件完成。
    • 在任一浏览器中加载此文件时是否检查过 JS 错误? Chrome 中的行为是什么?
    • 我真的不同意,问题是从目前的数据来看,尚不清楚:您是如何请求数据的,因此,当时是否有任何问题,或者是什么您正在调用的脚本看起来像这样,因此无法查看 require 指令是否存在。您还说“似乎是 Firefox 问题”,我建议您坚持事实以避免混淆或红鲱鱼。
    猜你喜欢
    • 1970-01-01
    • 2021-10-22
    • 2015-04-07
    • 2013-12-08
    • 1970-01-01
    • 2016-09-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多