问题
Edit: I thought about a possible solution, but I made another question as it is very specific: see AJAX proxy with PHP, is it possible?
A couple of times I've encountered this problem...
I create sites that have a certain degree of modularity. So, it is possible that there are "components" (think of a rough CMS) which carry their own PHP code, CSS, and JavaScript, all dynamically included. Think about a structure like:
{siteroot}/component/datagrid/datagrid.php
{siteroot}/component/datagrid/js/datagrid.js
{siteroot}/component/datagrid/css/datagrid.css
{siteroot}/component/datagrid/ajax/getsomedata.php
Now, the question is: for JavaScript files, and expecially AJAX calls, how do I make them context-aware with the URLs?
For example, if in datagrid.js I want to call siteroot/component/datagrid/ajax/getsomedata.php with AJAX I should write (with JQuery):
$("#ajax").load("siteroot/component/datagrid/ajax/getsomedata.php");
First problem:
siteroot changes on different installations. I've managed that by including a general
var codeBase = <? echo json_encode(Config::$siteRoot); ?>
with PHP on every page, from a Config file that can be easily edited for every installation, so I can do with whatever JavaScript something like:
$("#ajax").load(codeBase + "/component/Datagrid/ajax/getsomedata.php");
What do you think of this approach?
Second problem: but I have PHP functions that return to me also the components folder, or the folder of other components. It would be nice to make the whole URL dynamic. This would account also for changes in the structure of the component if I want. The only solution I've found is to use a
.js.php dynamic Javascript. This is very unelegant, and I have to include all the framework in the JavaScript file, like:
<?php
include "../../libs/framework.php"; // get my functions...
$myUrl = Config::$siteRoot . Framework::getComponentAjaxDir("datagrid") . "/getsomedata.php";
?>
$("#ajax").load(<?=json_encode($myUrl)?>);
Another side effect is that I have to know exactly the include the path for framework.php... I don't want this so hard-codedin my ".js.php" file.
Any smart solutions about that?
回答1:
To be honest your problems are realistic options and aren't that bad practice in general quite frankly.
But let's explore this a little further.
What would be the best approach is for you to have 1 main config.php file which you can then specify modules, i.e. your datagrid etc.
You could store all modules in an array variable like so:
$_SITE_PATH = "/var/www/html/";
$_HTTP_PATH = "http://example.com/";
$_MODULES_PATH = $_SITE_PATH."modules/"
$_MODULES = array(
"datagrid"=>$_MODULES_PATH."datagrid/init.php",
"something_else"=>$_MODULES_PATH."something_else/init.php"
);
Each module would have it's own directory with instantiation init.php so that it would load all it required to get going.
This way you could code as you liked and when you needed something (preferably in the header state) do something like this.
global $_MODULES;
require_once($_MODULES["datagrid"]);
Everything will be easily available as and when required without any variable path issues later down the line.
回答2:
As nobody answered in a suitable way, I answer to myself to provide a solution I've found out that can be useful. The key to my solution is simple:
- I create an AJAX proxy at a fixed location in my site structure, so I can use
codeBaseto reference the proxy from JavaScript I call this proxy with two parameters:
pluginandaction, which identify a) the plugin folder in which the "real" ajax is and b) the ajax file to use, along with the other params:$("#...").load( codeBase + "/main/ajax.php?plugin=Datagrid&action=gettable&otherparams"...)
In
ajax.phpI sanitize the parameters, and usepluginandactionto obtain the "real" ajax file:{serverRoot}/components/{plugin}/ajax/{action}.php
Then i simply include that file in ajax.php
来源:https://stackoverflow.com/questions/11790698/context-aware-ajax-call-in-a-modular-site