如何在Ajax中执行PHP和SQL会话?

时间:2010-02-21 00:18:17

标签: php ajax

今天我一直在问类似的问题,但我看到我认为问题在于我如何调用我的数据?

我正在尝试用一个将内容加载到div中的ajax替换导航栏。

导航栏是这样的:

<ul>
  <li><a href="javascript:void(0)" onclick="getData('/includes/view-monthly-calendar-ajax.php', 'targetDiv')">Monthly</a></li>
  <li><a href="javascript:void(0)" onclick="getData('/includes/agenda-ajax-include.php', 'targetDiv')">Daily</a></li>
  <li><a href="javascript:void(0)" onclick="getData('/includes/hello-include.php', 'targetDiv')">Admin</a></li>
  <li><a href="javascript:void(0)" onclick="getData('/includes/view-monthly-calendar-ajax.php', 'targetDiv')">Help</a></li>
</ul>

然后我有这个替换div:

 <div id="targetDiv"></div>

getData函数是innerHTML请求:

   <script language = "javascript"> 
        function getData(dataSource, divID)
{
    $.ajax({
      url: dataSource,
      dataType: 'html',
      success: function(data) {
        $('#' + divID).html(data);
      }
    });
}
</script>

当我点击导航链接时,HTML加载到div中,但我的包含文件的内容也包含PHP函数和jQuery,它们在加载时需要执行,它们只是被忽略。我在这里看到了很多问题,但这些似乎只与jQuery有关?

要明确的是,当我点击导航链接时,我在firebug控制台中获得200 OK,但只有HTML回来并填充div。

这是我最近清理过的包含文件,其中包含Jonathan建议的更改。此时,我在帮助按钮(第15行)之后输出</tr>,但没有输出超过...

 <?php 
session_start();
?>

<table width='100%' border='0'>
 <tr class='twentyfivepxheight'><td></td></tr>
 <tr>
 <td width='40%' valign='top'>
 <div class='left_agenda_items'>
 <table width='80%' align='center' border='0'>
 <tr class='twentyfivepxheight'>
 <td align='left' class='title5 bottompadding unselectable'>Daily Agenda<a href="javascript:void(0)" class="supernote-click-note1">
 <img src="/images/help-sm.jpg" alt="Help Button" /></a>
</td>
</tr>

<?php


  $numric_time =  getNumericTime($_SESSION['userData']['timezone']);
  $query  =  "SELECT * FROM events WHERE date(convert_tz(StartDate,'+00:00','". $numric_time."'))='$currentDate' AND UserID='" . $_SESSION['userData']['UserID'] ."' ORDER BY StartTime";
  $result  =  mysql_query($query);
  if(mysql_num_rows($result))
  {
    while($row = mysql_fetch_assoc($result))
    {
      $eventID    =  $row['EventID'];
      $eventName    =  $row['EventName'];
      $startDate    =  $row['StartDate'];
      $description  =  $row['Description'];
      $assignedTo    =  $row['AssignedTo'];
      $PTLType    =  $row['PTLType'];
      $parentEventID  =  $row['ParentEventID'];
      $textclass    =  "greentext unselectable";
      $text      =  "Main event";
      //$url      =  SITE_URL ."/agenda-view-event.php?eventID=$eventID&date=$currentDate&day=$i&type=A&date=$currentDate";
      $url      =  SITE_URL ."/agenda-view-event.php";
      if($PTLType == 2) // To do's
      {
        //$divRed[]  =  $eventID;
        $url      =  SITE_URL ."/agenda-view-timeline.php";
        $textclass    =  "redtextDaily unselectable";
        $text      =  "To do";
        $html_todos .= '
                <tr id="redtext' . $eventID . '">
                <td id="rowbox'.$eventID.'" class="'. $textclass . '" width="30%" onclick="get_event_popup(\'' . $url . '\', \'agendaViewDiv\', \'agendaLoader\', \'eventID='.$eventID.'\', \'parentEventID='.$parentEventID.'\', \'type=A\', \'date='.$currentDate.'\');setbgagendabox(\''.$eventID.'\');return false">
                ' . $eventName . ' - (' . $text . ')
                </td>
                </tr>';
      }
      elseif($PTLType == 3) //Completed
      {
        //$divBlue[]  =  $eventID;
        $url      =  SITE_URL ."/agenda-view-timeline.php";
        $textclass    =  "blueTextDaily unselectable";
        $text      =  "Completed";
        $html_completed .= '<tr id="bluetext' . $eventID . '"><td style="display:none;" id="rowbox'.$eventID.'" class="' . $textclass . '" width="30%" onclick="get_event_popup(\'' . $url . '\', \'agendaViewDiv\', \'agendaLoader\', \'eventID='.$eventID.'\', \'parentEventID='.$parentEventID.'\', \'type=A\', \'date='.$currentDate.'\');setbgagendabox(\''.$eventID.'\');return false">' . $eventName . ' - (' . $text . ')</td></tr>';
      }  else  { //main events
        //$divMainEvent[] = $eventID;
        $html_main_events .= '<tr id="mainEvent' . $eventID . '"><td id="rowbox'.$eventID.'" class="' . $textclass . '" width="30%" onclick="get_event_popup(\'' . $url . '\', \'agendaViewDiv\', \'agendaLoader\', \'eventID='.$eventID.'\', \'date='.$currentDate.'\', \'day='.$i.'\', \'type=A\', \'date='.$currentDate.'\');setbgagendabox(\''.$eventID.'\');return false">' . $eventName . ' - (' . $text . ')</td></tr>';
      }
    }

    echo $html_main_events . $html_todos . $html_completed;

  } else  { 

    ?>
   <tr>
     <td>
     <span class="a_dateformat">You have no agenda items due today!</span>
     </td>
     </tr>

<?php
}

?>

</table>
</div>
<input type="hidden" id='lastselected' value='' style="" />
</td>
<td class='verticalborder'>&nbsp;</td>
<td width='59%' valign="top" align="center">
<div id="agendaLoader" style="display:none;">
<img src="images/ajax-loader-orange.gif" alt="wait" />
</div>
<div id="agendaViewDiv" style="display:none;"></div>
</td>
</tr>
<tr>
<td colspan="3">&nbsp;
</td>
</tr>
</table>

但是看看我如何评论jQuery以使其工作?

如果没有注释掉,我没有得到任何输出。问题是我需要jQuery才能正确构建页面。

2 个答案:

答案 0 :(得分:6)

  

对于任何偶然发现这个“答案”的人,请注意,它并不打算如此分散。在与评论中的OP交换之后,此答案的每个部分都在稍后添加。顶部的项目是最新添加的,而最下面的项目是早期的添加。

     

Jonathan Sampson

调用未定义的函数

由于此页面通常包含在内,而不是直接调用,因此可能会有一些内容在请求时无法使用。您在评论中指出函数getNumericTime()不存在,并且导致错误。

你想让它存在,但是你不想只重新声明它,否则当你将这个页面作为包含文件提供给另一个已经拥有该功能的页面时,这会给你带来麻烦。所以你要做的就是检查函数是否存在,如果没有则创建它。

if (!function_exists("getNumericTime")) {
  function getNumericTime($foo) {
    // get the function logic and place it here
  }
}

现在,当您直接调用include文件时,如果该函数不存在,将创建该函数。当您调用老式方法时,如果包含此文件,则if语句将跳过传递新函数声明,因为该函数已存在。

如果函数文件中存在此函数,则可以包含它,但请务必使用include_once()而不是include()include_once()如果之前已经包含过该文件,则不会包含该文件。鉴于此页面偶尔出现在已经发生功能的另一个环境中,我们希望确保不再包含它,因此我们使用include_once()方法。

缺少连接和选择...

您正在尝试执行查询,但此页面上没有数据库连接。也没有mysql_select_db()调用来从特定数据库中进行选择。如果没有这些,您的查询将不会成功,并且不会返回您的数据。

// Our connection to mysql
$conn = mysql_connect($host, $user, $pass) or die(mysql_error());
// Which database we're using
mysql_select_db($dbname) or die(mysql_error());

一旦建立连接(例如在index.php中),我们就可以做一个include:

include("foo.php");

foo.php的内容现在已经打开了一个连接,因此可以执行查询,调用存储过程等。这只是因为它被包含在具有开放连接的页面中。

如果我们直接访问foo.php,这是你在使用ajax-request时所做的,我们就不会得到我们想要的结果,因为foo.php没有提供自己的数据库连接 - 它取决于index.php(通常包含在其中)来提供该连接。

从PHP到HTML再到PHP ......

通常会导致通过PHP脚本逐步输出HTML的问题。通常情况下,您会看到许多echo语句后面跟着带有反斜杠的HTML字符串,以逃避某些输出。写作不仅乏味,而且在出现问题时进行搜索会很痛苦。 HTML很少需要在PHP中。当您需要输出HTML时,请暂时退出PHP标记:

<?php

  $result = mysql_query($sql) or die(mysql_error());
  if (mysql_num_rows($result)) {
    while ($row = mysql_fetch_assoc($result) { ?>

    <tr>
      <td>Data Here</td>
      <td><?php print $row["foo"]; ?></td>
    </tr>

    <?php }
  } else { ?>

    <tr>
      <td>No records found</td>
    </tr>

  <?php }
?>

请注意,当我的HTML在某个地方出错时更容易分辨,并且从编写标记到编写PHP很容易。理想情况下,你甚至不会这样做,但这比你现在的改进。

正确使用$ _SESSION

在看了你的代码之后,我注意到你正在调用$_SESSION之外的值,或者至少尝试一下。如果您在页面顶部调用session_start(),则只能执行此操作。您的代码缺少这一点,这可能是您没有得到任何回报的原因,因为缺少SQL查询的组成部分。将以下内容添加到脚本的顶部:

<?php session_start(); ?>

PHP代码未执行?

如果您的PHP没有执行,那么脚本或服务器会出现问题,但jQuery不会出现问题。检查以确保在您请求的脚本中同时包含开始和结束PHP标记:

<?php

  /* and */

?>

简化事情

您可以稍微简化和清理代码。首先,让我们创建一个新的导航栏:

<ul id="nav">
  <li><a href="index.php">Index</a></li>
  <li><a href="about.php">About</a></li>
  <li><a href="contact.php">Contact</a></li>
</ul>

请注意我是如何直接链接到文件,而不是使用任何javascript来取消我的点击。这样,当用户在没有启用JavaScript的情况下偶然发现我的网站时,他们没有遇到破坏的网站,他们仍然可以绕过。

如果没有在我们的HTML中穿插javascript,我们会将一些逻辑绑定到这些导航链接:

$(function(){
  // Attach logic to all links
  $("#nav a").click(function(e){
    // Prevent link from redirecting page
    e.preventDefault();
    // Load next page into #targetDiv
    $("#targetDiv").html("").load($(this).attr("href"));
  });
});

就是这样。你已经完成了。

答案 1 :(得分:4)

这个答案是对问题的后续部分的回应:

  

当我点击导航链接时,HTML   加载到div,但内容   我的包含文件也包含 PHP   需要的函数和 jQuery   在加载时执行它们   只是被忽略了。

请注意,当您使用XMLHttpRequestObject.responseText插入到DOM文本时,从innerHTML返回的JavaScript将无法执行。

您可能需要查看以下Stack Overflow帖子,了解有关此问题的几个解决方案:


但是,如果您使用的是jQuery,则可以使用以下内容替换getData()中的所有代码:

function getData(dataSource, divID)
{
    $.ajax({
      url: dataSource,
      dataType: 'html',
      success: function(data) {
        $('#' + divID).html(data);
      }
    });
}

当使用ajax()选项调用jQuery dataType: 'html'方法时,包含的脚本标记在插入DOM时会自动进行评估。您可能需要查看以下Stack Overflow帖子以进一步阅读: