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
functions.js
/inc/ folder
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:
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.
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:
auto_prepend
setting.