路线 class 无法正常工作
Route class doesn't working properly
我正在重写一个以前用 CodeIgniter 框架编写的应用程序,我的客户想要一个独立的应用程序和一个纯 php 代码。反正别告诉我不要重新发明轮子因为我已经知道我的客户错了。我们来解决问题。
我正在寻找一个简单的路由 class,它允许我从任何位置调用任何文件。我发现这个简单而强大 class、this is the repository。
我已经在我的项目中实现了它,将 route.php
文件复制到索引位置并按照文档所述更改我的 .htaccess
。这是我项目的结构,而不是全部:
/ PUBLIC_HTML
/ application
/ controllers
/backend.php
/user.php
/ helpers
/ models
/ views
/backend
/backend.php
/calendar.php
/user
/users.php
/panel.php
/ assets
/ files used by frontend...
/ system
/ configuration
/ constant
/ .htaccess
/ index.php
/ route.php
当应用程序从 index.php
启动时,包含用于与数据库建立连接的配置文件。在同一个 configuration
文件中,我导入了 route.php
。现在我的 index.php
页面非常简单,像这样:
// Check if the session is set
if(isset($_SESSION['user_info']['id_roles']))
{
switch($_SESSION['user_info']['id_roles'])
{
case 1: //Admin
$route->add('/application/controllers/backend', 'index');
$route->submit();
break;
case 2: //Provider
$route->add('/application/controllers/backend');
$route->submit();
break;
case 3: //Customer
$route->add('/application/controllers/appointments');
$route->submit();
break;
}
}
else
{
// Session isn't set, so I redirect user to login page
header('Location: application/views/user/login.php');
exit; // stop
}
因此,如果设置了 session
,我会将用户类型重定向到正确的位置,否则,如果未设置,我将显示登录页面。 login
页面简单地评估会话变量,如果响应成功,用户将再次重定向到索引页面。
现在的问题是,例如,当管理员登录时(所以 case 1
),route
class 不会对 $uri
赋值,举个例子:
public function submit()
{
$uri = isset($_REQUEST['uri']) ? $_REQUEST['uri'] : '/';
$uri = trim($uri, $this->_trim);
$replacementValues = array();
// Iterate on the list of URI
foreach($this->_listUri as $listKey => $listUri)
{
// Looking for a match..
if(preg_match("#^$listUri$#", $uri))
{
// Replace the values
$realUri = explode('/', $uri);
$fakeUri = explode('/', $listUri);
// Get value with .+ with real URI value
foreach($fakeUri as $key => $value)
{
if ($value == '.+')
{
$replacementValues[] = $realUri[$key];
}
}
// Pass array arguments..
call_user_func_array($this->_listCall[$listKey], $replacementValues);
}
}
}
$uri
变量应该使用服务器的当前 uri
进行赋值,但我尝试使用 var_dump 并且我得到一个空的 value.Then 匹配条件是从未调用过,并且未显示正确的文件。我不知道为什么,我只是想了解为什么它不起作用,我可能做错了什么,有人可以帮助我理解吗?
完成管理重定向的示例,我只想显示 backend.php
中包含的内容,这些内容应该从 route
.
中加载
<?php
session_start();
class Backend
{
// Construct of class
public function __construct()
{
}
// Display the main backend page
public function index($appointment_hash = '')
{
$_SESSION['user_info']['hash'] = $appointment_hash;
$_SESSION['user_info']['dest_url'] = SystemConfiguration::$base_url . "backend";
// some content..
}
...
所以你怎么看,我只是想调用 backend
控制器的 index
函数,当我调用 ->add()
将控制器的 url 添加到调用,然后 ->submit()
执行操作。
我做错了什么?
更新 - 路由器请求任务
首先我更新了应用程序的堆栈。
我认为此时最好就哪个 OpenSource Router 允许我执行此任务征求您的专家意见:
1.导入控制器
导入我名为 controllers
的文件夹中包含的所有控制器。一旦你导入,我将简单地调用路由器的实例,并调用加载的控制器的特定功能。示例:
$router->backend->index();
其中index();
表示控制器的功能叫backend
。
这必须在我的整个应用程序中完成。我还要确保我们也可以通过 URL 调出该函数,特别是如果我插入此 url:
localhost/application/controllers/backend/index
我可以简单地引用 url.
调用相同的函数
2。请求 ajax
交付 我的路由器必须能够 运行 ajax 来自 javascript 的请求,特别是如果我使用此代码:
$('#login-form').submit(function(event)
{
var postUrl = GlobalVariables.baseUrl + 'user/ajax_check_login';
var postData =
{
'username': $('#username').val(),
'password': $('#password').val()
};
$('.alert').addClass('hidden');
$.post(postUrl, postData, function(response)
{
我想调用用户函数ajax_check_login
。
包含在控制器user
中,想象一下GlobalVariables.baseUrl
,这是什么……我们怎么能想到是可以明显变化的基础应用程序的url。
请注意,我的控制器函数 return 是 json 格式。
3。加载视图
在我的应用程序中有保存在 .php
中的视图,但包含 html 文件,一个视图示例(以前用 CodeIgniter 编写)pul 你会发现 here .
我希望能够调用视图并显示新用户 html 标记。我还需要同时调用更多视图,例如有时我将正文分为:
header, body, footer
为了简化对视图中 $this
所指内容的理解,由于视图是由控制器方法“加载”的,视图仍然 运行 在与该方法相同的范围内,这意味着 $this
可以有不同的上下文,这取决于 class 加载它。
例如:
class Controller1 extends CI_Controller {}
在此示例控制器中加载的任何视图文件中,$this
特指 Controller1 class,它可以访问 CI_Controller
public 并受保护 properties/methods 以及(如加载器或输入 classes,它们被分配给 CI_Controller 的加载和输入属性)因为它 扩展 class.
控制器仍然只是普通的旧 PHP classes。如果我这样做:
class Controller1 extends CI_Controller {
$this->foobar = 'Hello';
}
class Controller2 extends CI_Controller {
$this->foobar = 'World';
}
...如果我们在这些控制器中的任何一个的任何方法中加载相同的视图文件,在该视图文件中使用 $this->foobar
将 return 不同的值。
但这暂时不重要,我只想尽可能清楚。
我开始赏金并失去了所有代表,但我真的很想在这方面获得帮助并学习。
你需要以路由器自带的index.php为例。您将看到如何设置路线:
- 你总是必须有 2 个参数:1.uri,2.function
- 根据示例,函数必须不是函数名
'index'
,而是函数体 function(){...}
。也许参考也可以。
- 恕我直言,路由不应依赖于会话(虽然它可能是,但这不是通常的做法)
- 而不是
$router->backend->index();
,我将在文件末尾有一个公共代码块,这样您就不必多次复制和粘贴代码。
我将以您的方式向您展示后端,然后再向您展示如何使其通用化的约会。所以你应该让你的路线类似于:
<?php
session_start();
include 'route.php';
$phpClass = false;
$view = false;
$func = false;
$route = new Route();
if(isset($_SESSION['user_info']) && isset($_SESSION['user_info']['id_roles'])) {
$route->add('/application/controllers/backend', function(){
echo 'You are now at backend page, and the role is ';
switch($_SESSION['user_info']['id_roles']) {
case 1: echo 'Admin'; break;
case 2: echo 'Provider'; break;
case 3: echo 'Customer'; break;
}
include 'backend.php';
$backend = new Backend();
$backend->index(/* I don't know what 'hash' could be */);
});
// more general case:
$route->add('/application/controllers/appointments', function(){
// we only set the global $phpClass variable, and the rest is common, see below
global $phpClass, $func;
$phpClass = 'Appointements';
$func = 'index'; // default is index, if it wasn't given on the url
});
$route->add('/application/controllers/appointments/add', function(){
// we only set the global $phpClass variable, and the rest is common, see below
global $phpClass, $func;
$phpClass = 'Appointements';
$func = 'add';
});
$route->add('/application/controllers/appointments/delete', function(){
// we only set the global $phpClass variable, and the rest is common, see below
global $phpClass, $func;
$phpClass = 'Appointements';
$func = 'delete';
});
$route->add('/application/controllers/foo', function(){
global $phpClass;
$phpClass = 'Foo';
});
$route->add('/application/controllers/bar', function(){
global $phpClass;
$phpClass = 'Bar';
});
$route->add('/application/views/bar', function(){
global $phpClass, $view;
$phpClass = 'View';
$func = 'show';
$view = 'bar.php';
});
$route->submit();
} else {
// Session isn't set, so I redirect user to login page
header('Location: /application/views/user/login.php');
exit; // stop
}
if ($phpClass === false || $func === false) {
die("You have to have both controller and function un the url");
}
// if we got here it means we're in the common case
// include the necessary controller. If you want you can
// include all of them at the top of the php and remove this line
include 'application/controllers/' . strtolower($phpClass) . '.php';
$controller = new $phpClass();
// this is instead of `$router->backend->index();`:
$controller->$func(/*$hash*/);
// I don't know what '$hash' could be, maybe javascript could send it via ajax
?>
controllers/view.php:
class View {
public function show() {
global $view;
include 'application/views/' . $view;
}
// here you'll need to have all the things that any of
// your views access as $this->bar :
$config = new stdClass(...);
$array = array();
function get_lang() {global $lang; return $lang;}
//...
}
json 在 controllers/user 中的响应示例。php:
class User {
public function logged_in() {
$username = isset($_SESSION) && isset($_SESSION['username']) ? $_SESSION['username'] : false;
$response = array(
'success' => $username !== false ? 'OK' : 'ERROR',
'username' => $username
);
echo json_encode($response);
}
}
我正在重写一个以前用 CodeIgniter 框架编写的应用程序,我的客户想要一个独立的应用程序和一个纯 php 代码。反正别告诉我不要重新发明轮子因为我已经知道我的客户错了。我们来解决问题。
我正在寻找一个简单的路由 class,它允许我从任何位置调用任何文件。我发现这个简单而强大 class、this is the repository。
我已经在我的项目中实现了它,将 route.php
文件复制到索引位置并按照文档所述更改我的 .htaccess
。这是我项目的结构,而不是全部:
/ PUBLIC_HTML
/ application
/ controllers
/backend.php
/user.php
/ helpers
/ models
/ views
/backend
/backend.php
/calendar.php
/user
/users.php
/panel.php
/ assets
/ files used by frontend...
/ system
/ configuration
/ constant
/ .htaccess
/ index.php
/ route.php
当应用程序从 index.php
启动时,包含用于与数据库建立连接的配置文件。在同一个 configuration
文件中,我导入了 route.php
。现在我的 index.php
页面非常简单,像这样:
// Check if the session is set
if(isset($_SESSION['user_info']['id_roles']))
{
switch($_SESSION['user_info']['id_roles'])
{
case 1: //Admin
$route->add('/application/controllers/backend', 'index');
$route->submit();
break;
case 2: //Provider
$route->add('/application/controllers/backend');
$route->submit();
break;
case 3: //Customer
$route->add('/application/controllers/appointments');
$route->submit();
break;
}
}
else
{
// Session isn't set, so I redirect user to login page
header('Location: application/views/user/login.php');
exit; // stop
}
因此,如果设置了 session
,我会将用户类型重定向到正确的位置,否则,如果未设置,我将显示登录页面。 login
页面简单地评估会话变量,如果响应成功,用户将再次重定向到索引页面。
现在的问题是,例如,当管理员登录时(所以 case 1
),route
class 不会对 $uri
赋值,举个例子:
public function submit()
{
$uri = isset($_REQUEST['uri']) ? $_REQUEST['uri'] : '/';
$uri = trim($uri, $this->_trim);
$replacementValues = array();
// Iterate on the list of URI
foreach($this->_listUri as $listKey => $listUri)
{
// Looking for a match..
if(preg_match("#^$listUri$#", $uri))
{
// Replace the values
$realUri = explode('/', $uri);
$fakeUri = explode('/', $listUri);
// Get value with .+ with real URI value
foreach($fakeUri as $key => $value)
{
if ($value == '.+')
{
$replacementValues[] = $realUri[$key];
}
}
// Pass array arguments..
call_user_func_array($this->_listCall[$listKey], $replacementValues);
}
}
}
$uri
变量应该使用服务器的当前 uri
进行赋值,但我尝试使用 var_dump 并且我得到一个空的 value.Then 匹配条件是从未调用过,并且未显示正确的文件。我不知道为什么,我只是想了解为什么它不起作用,我可能做错了什么,有人可以帮助我理解吗?
完成管理重定向的示例,我只想显示 backend.php
中包含的内容,这些内容应该从 route
.
<?php
session_start();
class Backend
{
// Construct of class
public function __construct()
{
}
// Display the main backend page
public function index($appointment_hash = '')
{
$_SESSION['user_info']['hash'] = $appointment_hash;
$_SESSION['user_info']['dest_url'] = SystemConfiguration::$base_url . "backend";
// some content..
}
...
所以你怎么看,我只是想调用 backend
控制器的 index
函数,当我调用 ->add()
将控制器的 url 添加到调用,然后 ->submit()
执行操作。
我做错了什么?
更新 - 路由器请求任务
首先我更新了应用程序的堆栈。 我认为此时最好就哪个 OpenSource Router 允许我执行此任务征求您的专家意见:
1.导入控制器
导入我名为 controllers
的文件夹中包含的所有控制器。一旦你导入,我将简单地调用路由器的实例,并调用加载的控制器的特定功能。示例:
$router->backend->index();
其中index();
表示控制器的功能叫backend
。
这必须在我的整个应用程序中完成。我还要确保我们也可以通过 URL 调出该函数,特别是如果我插入此 url:
localhost/application/controllers/backend/index
我可以简单地引用 url.
调用相同的函数2。请求 ajax 交付 我的路由器必须能够 运行 ajax 来自 javascript 的请求,特别是如果我使用此代码:
$('#login-form').submit(function(event)
{
var postUrl = GlobalVariables.baseUrl + 'user/ajax_check_login';
var postData =
{
'username': $('#username').val(),
'password': $('#password').val()
};
$('.alert').addClass('hidden');
$.post(postUrl, postData, function(response)
{
我想调用用户函数ajax_check_login
。
包含在控制器user
中,想象一下GlobalVariables.baseUrl
,这是什么……我们怎么能想到是可以明显变化的基础应用程序的url。
请注意,我的控制器函数 return 是 json 格式。
3。加载视图
在我的应用程序中有保存在 .php
中的视图,但包含 html 文件,一个视图示例(以前用 CodeIgniter 编写)pul 你会发现 here .
我希望能够调用视图并显示新用户 html 标记。我还需要同时调用更多视图,例如有时我将正文分为:
header, body, footer
为了简化对视图中 $this
所指内容的理解,由于视图是由控制器方法“加载”的,视图仍然 运行 在与该方法相同的范围内,这意味着 $this
可以有不同的上下文,这取决于 class 加载它。
例如:
class Controller1 extends CI_Controller {}
在此示例控制器中加载的任何视图文件中,$this
特指 Controller1 class,它可以访问 CI_Controller
public 并受保护 properties/methods 以及(如加载器或输入 classes,它们被分配给 CI_Controller 的加载和输入属性)因为它 扩展 class.
控制器仍然只是普通的旧 PHP classes。如果我这样做:
class Controller1 extends CI_Controller {
$this->foobar = 'Hello';
}
class Controller2 extends CI_Controller {
$this->foobar = 'World';
}
...如果我们在这些控制器中的任何一个的任何方法中加载相同的视图文件,在该视图文件中使用 $this->foobar
将 return 不同的值。
但这暂时不重要,我只想尽可能清楚。
我开始赏金并失去了所有代表,但我真的很想在这方面获得帮助并学习。
你需要以路由器自带的index.php为例。您将看到如何设置路线:
- 你总是必须有 2 个参数:1.uri,2.function
- 根据示例,函数必须不是函数名
'index'
,而是函数体function(){...}
。也许参考也可以。 - 恕我直言,路由不应依赖于会话(虽然它可能是,但这不是通常的做法)
- 而不是
$router->backend->index();
,我将在文件末尾有一个公共代码块,这样您就不必多次复制和粘贴代码。
我将以您的方式向您展示后端,然后再向您展示如何使其通用化的约会。所以你应该让你的路线类似于:
<?php
session_start();
include 'route.php';
$phpClass = false;
$view = false;
$func = false;
$route = new Route();
if(isset($_SESSION['user_info']) && isset($_SESSION['user_info']['id_roles'])) {
$route->add('/application/controllers/backend', function(){
echo 'You are now at backend page, and the role is ';
switch($_SESSION['user_info']['id_roles']) {
case 1: echo 'Admin'; break;
case 2: echo 'Provider'; break;
case 3: echo 'Customer'; break;
}
include 'backend.php';
$backend = new Backend();
$backend->index(/* I don't know what 'hash' could be */);
});
// more general case:
$route->add('/application/controllers/appointments', function(){
// we only set the global $phpClass variable, and the rest is common, see below
global $phpClass, $func;
$phpClass = 'Appointements';
$func = 'index'; // default is index, if it wasn't given on the url
});
$route->add('/application/controllers/appointments/add', function(){
// we only set the global $phpClass variable, and the rest is common, see below
global $phpClass, $func;
$phpClass = 'Appointements';
$func = 'add';
});
$route->add('/application/controllers/appointments/delete', function(){
// we only set the global $phpClass variable, and the rest is common, see below
global $phpClass, $func;
$phpClass = 'Appointements';
$func = 'delete';
});
$route->add('/application/controllers/foo', function(){
global $phpClass;
$phpClass = 'Foo';
});
$route->add('/application/controllers/bar', function(){
global $phpClass;
$phpClass = 'Bar';
});
$route->add('/application/views/bar', function(){
global $phpClass, $view;
$phpClass = 'View';
$func = 'show';
$view = 'bar.php';
});
$route->submit();
} else {
// Session isn't set, so I redirect user to login page
header('Location: /application/views/user/login.php');
exit; // stop
}
if ($phpClass === false || $func === false) {
die("You have to have both controller and function un the url");
}
// if we got here it means we're in the common case
// include the necessary controller. If you want you can
// include all of them at the top of the php and remove this line
include 'application/controllers/' . strtolower($phpClass) . '.php';
$controller = new $phpClass();
// this is instead of `$router->backend->index();`:
$controller->$func(/*$hash*/);
// I don't know what '$hash' could be, maybe javascript could send it via ajax
?>
controllers/view.php:
class View {
public function show() {
global $view;
include 'application/views/' . $view;
}
// here you'll need to have all the things that any of
// your views access as $this->bar :
$config = new stdClass(...);
$array = array();
function get_lang() {global $lang; return $lang;}
//...
}
json 在 controllers/user 中的响应示例。php:
class User {
public function logged_in() {
$username = isset($_SESSION) && isset($_SESSION['username']) ? $_SESSION['username'] : false;
$response = array(
'success' => $username !== false ? 'OK' : 'ERROR',
'username' => $username
);
echo json_encode($response);
}
}