I'm re-writing an application previously written in CodeIgniter framework, my customer want have an independent app and a pure php code. Anyway don't tell me not to reinvent the wheel because I already know that my client is wrong. We come to the problem.
I'm looking for a simple Route class that allow me to call any files from any location. I found this simple and powerfull class, this is the repository.
I've implemented it in my project, copy the route.php
file inside the index location and change my .htaccess
as the documentation says. Instead of all, this is the structure of my project:
/ 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
when the applicationi is started from the index.php
the configuration file is included for establish the connection with the database. In the same configuration
file I've imported the route.php
. Now my index.php
page is very simple, like this:
// 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
}
so if the session
is set I redirect the user type to the correct location, against, if isn't set I show the login page. The login
page simply valorize the session variable, if the response is success the user is redirected again to the index page.
The problem now is that, for example when the admin is logged (so case 1
), the route
class doesn't valorize the $uri
, a bit example:
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);
}
}
}
check the full class here.
the $uri
variable should be valorized with the current uri
of the server but I tried with a var_dump and I get an empty value.Then the match condition is never invoked, and the correct file isn't displayed. I don't know why, I just want to understand why it is not working, I'm probably doing something wrong, someone can help me understand?
Completing the example of the admin redirect, I want to show only what is contained in the backend.php
, which should be loaded from the 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..
}
...
So how you can see, I simply want call the index
function of the backend
controller when I call ->add()
for add the url of the controller to call, and ->submit()
to perform the operation.
What am I doing wrong?
UPDATE - Router request task
First I updated the stack of my application. I think at this point it's best to ask your expert advice on which OpenSource Router allow me to implement this tasks:
1. Import controller
Import all controllers that are contained in my folder called controllers
. Once you imported I will simply call the instance of the router, and call up a specific function of the controller loaded. Example:
$router->backend->index();
where index();
It represents the function of controller called backend
.
This must be done in my entire application. Also I would make sure that we can bring up the function also via the URL, in particular, if I insert this url:
localhost/application/controllers/backend/index
I can call the same function simply referring url.
2. Requests ajax Delivery My Router must be able to run ajax requests from javascript, especially if I use this code:
$('#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)
{
I want to call the user function ajax_check_login
.
contained in the controller user
, imagine GlobalVariables.baseUrl
, what is... How can we think is the url of the base application that can obviously vary.
Note that my Controller function return a json format.
3. Load view
in my application there is the view, which are saved in .php
, but containing html file, an example of view (previously written in CodeIgniter) pul you find here.
I want to be able to call a view and show the new user html markup. I also need to call also more views at the same instant, for example at times I divide the body into:
header, body, footer
To simplify the understanding of what $this
refers to in a view, since a view is "loaded" by a controller method, the view is still run in the same scope as that method, meaning $this
can have a different context depending on which class loaded it.
For example:
class Controller1 extends CI_Controller {}
In any view file loaded in this example controller, $this
refers specifically to the Controller1 class, which can access CI_Controller
public and protected properties/methods as well (like the Loader or Input classes, which are assigned to the load and input properties of CI_Controller) since it extends that class.
Controllers are still just plain old PHP classes. If I were to do this:
class Controller1 extends CI_Controller {
$this->foobar = 'Hello';
}
class Controller2 extends CI_Controller {
$this->foobar = 'World';
}
...if we load the same view file in any method of either of these controllers, using $this->foobar
in that view file will return a different value.
But this for now it's not important, I just want to be as clear as possible.
I start a bount and lose all my rep, but I really want to get help in this and learn.
You need to look at the index.php provided with the Router as an example. You'll see how to set the routes:
'index'
, but a function body function(){...}
. Maybe reference would work as well.$router->backend->index();
, I will have a common block of code at the end of the file so you don't have to copy&paste the code many times.I'll show you with backend in your way, and then with appointments how could you make it general. So you should make your routes something like:
<?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;}
//...
}
Example of json response in 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);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With