dou6495
dou6495
2012-06-15 02:49

用jQuery.ajax()加载的PHP文件无法访问加载的函数

已采纳

Skip to the last two paragraphs if you can't be bothered to read details of the setup...

I am transitioning from a linear PHP+JavaScript CMS to an object-oriented PHP model with some bells and whistles a la jQuery and Ajax. I am trying to centralize as much code as possible with the following setup:

index.php

  • calls (via require_once()) setup.php (easy access to common variables (such as directories), constants, preferences, turning debugging on and off, etc.), actions.php (the file used by jQuery.ajax() to determine which function or object to send the data off to), functions.php (miscellaneous functions), objects.php (objects used, usually, for prepping incoming/outgoing data to/from the MySQL database)
  • calls functions.js, jQuery (from Google), tiny_mce, and fancybox (these last two are likely not variables in the problem, but I thought I'd mention them anyway)
  • includes div#content so that jQuery.ajax() has a place to load content

functions.js

  • includes a script for loading content into index.php's div#content via $(#content).html...
  • includes scripts for prepping form content, use .ajax() to send data to actions.php, accept success or error message from server, and display message to the user
  • includes a doc.ready function that adds a .live('submit') method to the forms

/inc/ folder

  • includes PHP files, mostly forms, for loading via .ajax() into the index's div#content

Most everything works fine. The part that doesn't work is that the forms loaded into the index's div#content do not have access to the various PHP files already loaded by the index (namely setup.php and functions.php). These forms need the occasional function in order to populate themselves.

For example, I have a "form" that displays all the pages in the website so that a user can edit or delete them. In my old CMS model I'd store that function (let's call it getPages()) in the functions.php so that a page could simply echo getPages();

Currently the form cannot access the getPages() function because the files loaded by .ajax() don't recognize functions.php as loaded by index.php. I can get around this by adding a require_once('functions.php'); to the top of every file in the /inc/ folder, but I'd rather not. I'd rather my forms just be forms.

In the past, I've loaded forms into place with just PHP and POST/GET, which obviously reloads the index headers, required files, and new content as one cohesive family. So how can I get the same results in conjunction with Ajax and its lack of reloading? Is it even possible? Am I going about this the wrong way?

Some notes:

  • I'd prefer a jQuery, JavaScript, or PHP solution, if any. Most of what I'm doing is already new to me so adding another library might make my head explode. ...but if that's the only way... I'll do what I have to do.
  • while I am happy to copy/paste some code as needed, none of the files are available online; it's just on my XAMPP development server
  • since these files are all on my server, there's obviously no cross-domain bidness to factor in

Thanks in advance!

index.php (everything in this file seems to work fine)...

<?php
require_once('setup.php');
require_once('functions.php'); //functions.php calls to objects.php
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
...
<link href="styles/styles.css" type="text/css" media="screen" rel="stylesheet" />
<link href="fancybox/jquery.fancybox-1.3.4.css" type="text/css" media="screen" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.18/jquery-ui.min.js"></script>
...
<script src="js/functions.js"></script>
</head>
<body>
<div id="pagewrapper">
<div id="header">unimportant header content</div><!-- /header -->

<div id="nav_area">
  <ul id="nav">
    <li class="parent">Pages</li>
    <ul class="children">
      <li class="child" onclick="navto('inc/add_page.php');">Add a Page</li>
    </ul>
  </ul>
</div><!-- mana_nav_area -->

<div id="content"><!-- This is the DIV where the forms will appear -->
<?php
echo getPagesAsSelect(); //the function works here, although it doesn't make any sense to put it here. It's only here for illustrative purposes. 
?>
</div><!-- mana_content -->
</div><!-- pagewrapper -->
</body>
</html>

functions.js (everything in this file seems to work fine)...

jQuery(document).ready(function(){
// called by index.php, this function adds an event handler to our example form
    ...
    $("#add_page_form").live("submit", function () { add_page(); return false; });
        ...
});

function navto(destination) {
// use JQuery's ajax method to control main navigation
    var request = $.ajax({
        url: destination
    });

    request.done(function(msg) {
        $("#content").html( msg );
    });

    request.fail(function(jqXHR, textStatus) {
        alert( "Request failed: " + textStatus );
    });
}

function add_page() {
// this function grabs the data from the add_page_form and sends it to actions.php
// actions.php determines what function or object to send it to
// JS-based security is not an issue at this time
    var serialized = $('#add_page_form').serialize();
    var dataString = 'action=add_page&' + serialized;
    var destination = 'actions.php';

    var jqXHR = $.ajax({
        type: "GET",
        url: destination,
        data: dataString,
        cache: true,
        error: function(response) {
            $('msg').append(response);
        },
        success: function(response) {
            $('#msg').append(response);
        }
    });
    return false;
}

An example page: add_page.php which gives the user the opportunity to create a page for their site. In order to determine whether or not the user's new page is a sub-page of another page (the later being called the parent in the form below), a <SELECT> is created and populated with <OPTION>s via a PHP function (located in the functions.php file) called getPagesAsSelect().

<?php
// if I leave this code in place, it works
require_once('../functions.php'); //(you may recall that this file is in an /inc folder)
// this require_once() is the one I'd like to remove if possible
?>
<fieldset id="fieldset">
<legend>Add a Page</legend>
<form id="add_page_form" name="add_page" action="" method="get">

<label for="name">Page Name:</label> 
    <input type="text" id="name" name="name" value="" /><br />
<label for="parent">Parent:</label>
    <select id="parent" name="parent">
        <option value="0">No parent</option>
    <?php
            echo getPagesAsSelect();
            // getPagesAsSelect() queries the database and returns eligible
            // pages as a series of <option value="pageID">pageName</option>
            // Unless functions.php is loaded on this page, this call fails
            // and the page stops loading here
        ?>
        </select>
    <br />
<input id="submit_add_page" type="submit" name="add_page" value="Submit" class="save" /><input type="reset" value="Cancel" class="cancel" />
</form>
<div id="msg"><!-- where success or error messages show upon completion --></div>
</fieldset>

To summarize: .ajax() pulls the above add_page.php into index.php's div#content. Even though the functions.php file has been loaded by index.php, using .ajax() prevents the new content from being able to call the functions it needs.

While I don't doubt that everything is working as it should, I'm not a fan of my workaround, which is to require the functions.php with every file loaded by the .ajax(). I'm looking for alternatives, if any.

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

3条回答

  • dongtao5055 dongtao5055 9年前

    Small summary: you want to use a function in a php file without having to have require_once the file with it's definitions there. 2 solutions:

    1. Don't load that file directly, but 1 simple file that loads the functions file & then includes file you want (called with for instance `/pagecontent.php?page=pagename.php (do whitelist the name, don't go including random files).
    2. Create an auto_prepend setting.
    点赞 评论 复制链接分享
  • dphnn333971 dphnn333971 9年前

    It's not a workaround, it's how PHP works. Because PHP is server side, you cannot connect to the functions you have loaded in a different server call. They don't connect. PHP was made for this. Use it.

    点赞 评论 复制链接分享
  • doulun1939 doulun1939 9年前

    Your "functions" aren't accessible in ajax calls because they are completely separate requests from the original (index.php). These calls have they're own call stack (so to speak) and know nothing of the previous requests. There is no work around. If you need access to those functions defined in other files, you must include/require those files. If you don't want to use include/require in your files, then you need to re-think your implementation.

    点赞 评论 复制链接分享

相关推荐