I am creating an MVC framework with PHP. I am not able to get the query string. The following code does not return the query string
index.php
<?php
/**
* Front controller
*
* PHP version 5.4
*/
/**
* Autoloader
*/
spl_autoload_register(function ($class) {
$root = dirname(__DIR__); // get the parent directory
$file = $root . '/' . str_replace('\\', '/', $class) . '.php';
if (is_readable($file)) {
require $root . '/' . str_replace('\\', '/', $class) . '.php';
}
});
/**
* Routing
*/
$router = new Core\Router();
// Add the routes
$router->add('', ['controller' => 'Home', 'action' => 'index']);
$router->add('{controller}/{action}');
$router->add('{controller}/{id:\d+}/{action}');
$router->dispatch($_SERVER['REQUEST_URI']);
.htaccess
# Remove index.php from the request but maintain the query string
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [QSA,L]
#RewriteRule ^(.*)$ /index.php?$1
</IfModule>
#---working--
#<IfModule mod_rewrite.c>
# RewriteEngine On
# Options +FollowSymLinks -Indexes
# RewriteCond %{REQUEST_FILENAME} !-d
# RewriteCond %{REQUEST_FILENAME} !-f
# RewriteRule ^(.*)$ index.php [QSA,L]
#</IfModule>
#-also has no error---
#<IfModule mod_rewrite.c>
# RewriteEngine On
# RewriteBase /
# RewriteCond %{REQUEST_FILENAME} !-f
# RewriteCond %{REQUEST_FILENAME} !-d
# RewriteRule . /index.php [L]
#</IfModule>
<?php
namespace Core;
/**
* Router
*
* PHP version 5.4
*/
class Router
{
/**
* Associative array of routes (the routing table)
* @var array
*/
protected $routes = [];
/**
* Parameters from the matched route
* @var array
*/
protected $params = [];
/**
* Add a route to the routing table
*
* @param string $route The route URL
* @param array $params Parameters (controller, action, etc.)
*
* @return void
*/
public function add($route, $params = [])
{
// Convert the route to a regular expression: escape forward slashes
$route = preg_replace('/\//', '\\/', $route);
// Convert variables e.g. {controller}
$route = preg_replace('/\{([a-z]+)\}/', '(?P<\1>[a-z-]+)', $route);
// Convert variables with custom regular expressions e.g. {id:\d+}
$route = preg_replace('/\{([a-z]+):([^\}]+)\}/', '(?P<\1>\2)', $route);
// Add start and end delimiters, and case insensitive flag
$route = '/^' . $route . '$/i';
$this->routes[$route] = $params;
}
/**
* Get all the routes from the routing table
*
* @return array
*/
public function getRoutes()
{
return $this->routes;
}
/**
* Match the route to the routes in the routing table, setting the $params
* property if a route is found.
*
* @param string $url The route URL
*
* @return boolean true if a match found, false otherwise
*/
public function match($url)
{
foreach ($this->routes as $route => $params) {
if (preg_match($route, $url, $matches)) {
// Get named capture group values
foreach ($matches as $key => $match) {
if (is_string($key)) {
$params[$key] = $match;
}
}
$this->params = $params;
return true;
}
}
return false;
}
/**
* Get the currently matched parameters
*
* @return array
*/
public function getParams()
{
return $this->params;
}
/**
* Dispatch the route, creating the controller object and running the
* action method
*
* @param string $url The route URL
*
* @return void
*/
public function dispatch ($url)
{
$url = $this->removeQueryStringVariables($url);
#$url = trim($url, "/"); no route found
if ($this->match($url)) {
$controller = $this->params['controller'];
$controller = $this->convertToStudlyCaps($controller);
$controller = "App\Controllers\\$controller";
if (class_exists($controller)) {
$controller_object = new $controller();
$action = $this->params['action'];
$action = $this->convertToCamelCase($action);
if (is_callable([$controller_object, $action])) {
$controller_object->$action();
} else {
echo "Method $action (in controller $controller) not found";
}
} else {
echo "Controller class $controller not found";
}
} else {
echo 'No route matched.';
}
}
/**
* Convert the string with hyphens to StudlyCaps,
* e.g. post-authors => PostAuthors
*
* @param string $string The string to convert
*
* @return string
*/
protected function convertToStudlyCaps($string)
{
return str_replace(' ', '', ucwords(str_replace('-', ' ', $string)));
}
/**
* Convert the string with hyphens to camelCase,
* e.g. add-new => addNew
*
* @param string $string The string to convert
*
* @return string
*/
protected function convertToCamelCase($string)
{
return lcfirst($this->convertToStudlyCaps($string));
}
/**
* Remove the query string variables from the URL (if any). As the full
* query string is used for the route, any variables at the end will need
* to be removed before the route is matched to the routing table. For
* example:
*
* URL $_SERVER['QUERY_STRING'] Route
* -------------------------------------------------------------------
* localhost '' ''
* localhost/? '' ''
* localhost/?page=1 page=1 ''
* localhost/posts?page=1 posts&page=1 posts
* localhost/posts/index posts/index posts/index
* localhost/posts/index?page=1 posts/index&page=1 posts/index
*
* A URL of the format localhost/?page (one variable name, no value) won't
* work however. (NB. The .htaccess file converts the first ? to a & when
* it's passed through to the $_SERVER variable).
*
* @param string $url The full URL
*
* @return string The URL with the query string variables removed
*/
protected function removeQueryStringVariables($url)
{
if ($url != '') {
$parts = explode('&', $url, 2);
if (strpos($parts[0], '=') === false) {
$url = $parts[0];
} else {
$url = '';
}
}
return $url;
}
}
#-----------
Home.php
<?php
namespace App\Controllers;
/*
* Home controller
*
*/
;Class Home
{
/**
* show the index page
* @return void
*/
public function index()
{
echo 'Hello from the index action in the Home controller';
}
}
When I try URL with http://localhost/posts/index I have Hello from the index action in the Home controller
But when I try a query string in the URL like this http://localhost/posts/index?page=1
It return the same Hello from the index action in the Home controller While it should return the array [page]=1 as well
I also have the following warning Hello from the index action in the Home controllerPHP Warning: Undefined array key "REQUEST_URI"
I was looking online and in here since yesterday and tried many suggestions, but still could not get it working.
Please advise and many thanks