好的,我所知道的描述场景的最好方法是首先举例:
假设我有一个名为index.php的页面;
在 <html>
标记之前的最顶部,可以找到;
<?php session_start();
$_SESSION['user_id'] = 1234;
require_once "db.con.php";
?>
在 <body>
标记内,可以找到:
<div id="div_ajax">
<?php require_once "ajax.php"; ?>
</div>
现在在ajax.php页面中,有一个按钮,点击后会发出一个ajax请求。发出请求后,将生成一个简单的Db查询语句,用于根据user_id选择用户信息。问题是,在AJAX请求之后,似乎user_id会话和已经包含的Db连接“丢失”。
我知道我可以使用条件语句检查AJAX请求,只需添加行......
session_start();
require_once "db.con.php";
..在ajax.php页面的顶部,但我想知道是否有更好的方法来做到这一点?我不想总是将这两行添加到每个名为PHP页面的ajax中。它有点挫败了主页(index.php)上的行开头的目的。我想我可以使用一个名为page的ajax并且只包含一堆case语句,但仍然想知道是否有更好的方法。
非常感谢。
答案 0 :(得分:0)
我不认为有更好的方法,但这并不意味着没有。
阅读问题时只需注意几点: 1)为所有标题信息使用包装文件。因此,在页面的开头,添加:
require_once('package.php'); // that's what I call mine
然后在包装中,我有:
require_once('session.start.php');
require_once('db.con.php');
这样,你所有的页面都在访问同一个东西。如果你需要改变它,那就容易多了。
require_once,include_once,include和require之间存在速度差异。我不知道它有多重要。
表示框架在制作页面时包含60多个文件,所以我总是认为它不是太糟糕。会话信息存储在服务器上的文件夹中。 PHP将其默认为/ tmp(您应将其更改为私人文件夹/不可访问Web)。
确保您正在验证发送给AJAX的任何信息。请记住,它就像它自己的网页一样,因此任何权限或数据库敏感信息都应该受到同样的保护。
“我想我可以使用一个名为page的ajax,只包含一堆case语句,但仍然想知道是否有更好的方法。”
控制器模式对于这类事物非常有用。在一个文件中包含大量case语句很难维护。当你切换到只有1或2个函数的文件时,你的生活将变得如此简单。
根据项目的大小,您可能希望实现框架。查看MVC框架。如果我没有实现框架,我仍然实现控制器模式。
我从博客中解除了这个问题。我现在使用的东西看起来都不像这样,但它从这里开始:
在Presentation层中,我正在确定要实现哪些元素。对于我想要实现的每个元素,我启动控制器,如下所示:
$controller = new Controller();
$context = $controller->getContext();
$context->addParam('action', 'login');
$template->setContent( $controller->process() );
我正在使用Matt Zandstra的PHP Objects,Patterns和Practice 3rd Ed中的Controller进行自己的修改。
以下是发生的事情:
abstract class Command {
}
class CommandContext {
private $params = array();
private $error = "";
function __construct(){
$this->params = $_REQUEST;
}
function addParam( $key, $val ){
$this->params[$key] = $val;
}
function get( $key ){
return $this->params[$key];
}
function issetCheck( $key ){
if( ! empty( $this->params[$key] ) ){
return true;
}
return false;
}
function setError( $error ){
$this->error = $error;
}
function getError(){
return $this->error;
}
}
class CommandNotFoundException extends Exception { }
class CommandFactory {
private static $dir = 'include/classes/command/';
static function getCommand( $action = 'Default', $flag = 0 ){
switch( $flag ){
case 1:
$template = new TemplateQuickViewOnly();
break;
case 2:
$template = new TemplateQuickViewToggle();
break;
default:
$template = new TemplateMainBodyOnly();
break;
}
if( preg_match ( '/\W/', $action ) ){
throw new Exception("illegal characters in action");
}
$class = UCFirst(strtolower($action))."Command";
$file = ROOT_PATH."".self::$dir."{$class}.php";
if( ! file_exists( $file ) ){
throw new CommandNotFoundException( "could not find '$file'" );
}
include_once( $file );
if( ! class_exists($class) ){
throw new CommandNotFoundException( "no '$class' class located" );
}
$cmd = new $class( $template );
return array( $cmd, $template );
}
}
class Controller {
private $context;
function __construct(){
$this->context = new CommandContext();
}
function getContext(){
return $this->context;
}
function process( $method = 'execute', $flag = 0 ){
list( $cmd, $template ) = CommandFactory::getCommand( $this->context->get('action'), $flag );
if( ! $cmd->$method( $this->context ) ){
// handle failure
// $template->setMessage( UCFirst($this->context->get('action')).' failed to execute.');
return $template->getMessage();
}else{
// success dispatch view
return $template->getMessage();
}
}
}
逻辑层位于固定目录中。对象的实例已经由Controller层实例化,这意味着构造函数已被触发。此外,控制器层已经调用了方法“执行”(默认)或其他方法,例如“getLoginForm”。另外,请注意,当Controller调用方法“execute”时,它也会将CommandContext传递给方法,因此我们可以使用它们。
class LoginCommand extends Command {
public function __construct( ){ }
function execute ( CommandContext $context ){
if( $context->get('login_user_name') == 'demo' ){
$this->view->setMessage('Success is true!');
return true;
}
return false;
}
function getLoginForm( CommandContext $context ){
$this->view->setMessage('Second sucess is even more true!');
return true;
}
}
答案 1 :(得分:0)
AJAX请求是单独的网页请求,您在服务器端的index.php中所做的任何事情都不会在后续请求中提供(会话中的任何变量除外)。它的工作原理如下:
另一种思考方式:从服务器端看,AJAX请求几乎与您直接将浏览器指向ajax.php一样。
答案 2 :(得分:0)
就我的经验而言,我认为你的问题可以用FrontController pattern来解决。
基本思想是你整个应用程序总是调用相同的文件,例如index.php(也称为单一入口点)。
index.php然后执行每个页面上所需的所有任务(如启动会话或包含库类),然后调用您想要请求的页面。
这看起来像这样:(现在无法测试)
的index.php:
<?php
session_start();
$_SESSION['user_id'] = 1234;
require_once("db.con.php");
if($_REQUEST['Request_Type'] == 'website'){
require_once("header.html");
switch($_REQUEST['Request_Url']){
case 'SomePage':
require('SomePage.php');
break;
case 'SomeOtherPage':
require('SomeOtherPage.php');
break;
default:
require('ajax.php');
}
require_once("footer.html");
}elseif($_REQUEST['Request_Type'] == 'ajax'){
switch($_REQUEST['Ajax_Function']){
case 'ProcessButton':
require('ProcessButton.php');
break;
}
}
?>
ajax.php
echo '<input type="button" onClick="ajaxRequest(\"index.php\",\"ProcessButton\")" Value="ClickMe!" />';
ajaxRequest()Javascript函数必须向index.php发送一个Ajax请求设置参数
Request_Type ='ajax'
Ajax_Function ='ProcessButton'