AltoRouter never match subfolder - php

I tried to use the AltoRouter on my webspace in a subfolder. But the matches always false!
I have this structure on my webspace
domain.com
--/2 --> subfolder
----index.php
----.htacces
My .htaccess file looks like this:
DirectoryIndex index.php
RewriteEngine on
RewriteBase /2/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
So I setup up the router like this:
<?php
session_start();
require_once 'vendor/autoload.php';
use LemWebPortal\Config;
$latte = new Latte\Engine;
$router = new AltoRouter();
$router->setBasePath('/2/');
$router->map('GET', '/', function () {
require __DIR__ . '/src/Init/index.php';
});
$router->map('GET', '/schulungsbedarf', function () {
require __DIR__ . '/src/Init/courseRequest.php';
});
$match = $router->match();
if ($match && is_callable($match['target'])) {
call_user_func_array($match['target'], $match['params']);
} else {
// no route was matched
header($_SERVER["SERVER_PROTOCOL"] . ' 404 Not Found');
}
echo '<pre>';
var_dump($match);
Now, when I call domain.com/2/or domain.com/2/schulungsbedarfI see an empty white page with this message:
bool(false)
What did I miss here?

Related

PHP 8 - Routing can't find requested URL

I have a problem with PHP 8 routing. I'm creating my MVC "framework" to learn more about OOP. I did routing, controller and view - it works, I'm happy. But I found out that I would test my creation. This is where the problem begins, namely if the path is empty (""), it returns the "Home" view as asked in the routing, but if I enter "/ test" in the URL, for example, I have a return message "404 Not Found - The requested URL was not found on this server. " even though the given route is added to the table. What is wrong?
.htaccess file
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)$ index.php [QSA,L]
index.php with routes
<?php
/*
* Require Composer
*/
require dirname(__DIR__) . '/vendor/autoload.php';
/*
* Routing
*/
$routes = new Core\Router();
$routes->new('', ['controller' => 'HomeController', 'method' => 'index']);
$routes->new('/test', ['controller' => 'HomeController', 'method' => 'test']);
$routes->redirectToController($_SERVER['QUERY_STRING']);
Router.php file
<?php
namespace Core;
class Router
{
/*
* Routes and parameters array
*/
protected $routes = [];
protected $params = [];
/*
* Add a route to the route board
*/
public function new($route, $params = [])
{
/*
* Converting routes strings to regular expressions
*/
$route = preg_replace('/\//', '\\/', $route);
$route = preg_replace('/\{([a-z]+)\}/', '(?P<\1>[a-z-]+)', $route);
$route = '/^' . $route . '$/i';
$this->routes[$route] = $params;
}
/*
* Get all routes from table
*/
public function getRoutesTable() {
return $this->routes;
}
/*
* Checking if the specified path exists in the route table
* and completing the parameters table
*/
public function match($url)
{
foreach($this->routes as $route => $params) {
if(preg_match($route, $url, $matches)) {
foreach($matches as $key => $match) {
if(is_string($key)) {
$params[$key] = $match;
}
}
$this->params = $params;
return true;
}
}
return false;
}
/*
* Get all params from table
*/
public function getParamsTable() {
return $this->params;
}
/*
* Redirection to the appropriate controller action
*/
public function redirectToController($requestUrl) {
$requestUrl = explode('?', $requestUrl);
$url = $requestUrl[0];
if ($this->match($url)) {
$controller = $this->params['controller'];
$controller = "App\\Controllers\\$controller";
if(class_exists($controller)) {
$controller_obj = new $controller($this->params);
$method = $this->params['method'];
if(method_exists($controller, $method)) {
$controller_obj->$method();
} else {
echo "Method $method() in controller $controller does not exists!";
}
} else {
echo "Controller $controller not found!";
}
} else {
echo "No routes matched!";
}
}
}
View.php file
<?php
namespace Core;
class View {
public static function view($file) {
$filename = "../App/Views/$file.php";
if(file_exists($filename)) {
require_once $filename;
} else {
echo "View $file is not exist!";
}
}
}
HomeController file
<?php
namespace App\Controllers;
use Core\Controller;
use Core\View;
class HomeController extends Controller {
public function index() {
return View::view('Home');
}
public function test() {
return View::view('Test');
}
}
Folder structure
Routes in web browser
I'm using XAMPP with PHP 8.0 and Windows 10.
First of all, choose one of the following two options to proceed.
Option 1:
If the document root is set to be the same as the project root, e.g. path/to/htdocs, in the config file of the web server (probably httpd.conf), similar to this:
DocumentRoot "/path/to/htdocs"
<Directory "/path/to/htdocs">
AllowOverride All
Require all granted
</Directory>
then create the following .htaccess in the project root, remove any .htaccess file from the directory path/to/htdocs/Public and restart the web server:
<IfModule dir_module>
DirectoryIndex /Public/index.php /Public/index.html
</IfModule>
Options FollowSymLinks
RewriteEngine On
RewriteBase /Public/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [QSA,L]
Option 2:
If the document root is set to be the directory path/to/htdocs/Public in the config file of the web server (probably httpd.conf), similar to this:
DocumentRoot "/path/to/htdocs/Public"
<Directory "/path/to/htdocs/Public">
AllowOverride All
Require all granted
</Directory>
then create the following .htaccess in the directory path/to/htdocs/Public, remove any other .htaccess file from the project root (unless it, maybe, contains some relevant settings, other than DirectoryIndex) and restart the web server::
Options FollowSymLinks
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [QSA,L]
After you decided and proceeded with one of the options above, edit the page index.php as shown bellow:
<?php
//...
/*
* NOTE: A route pattern can not be an empty string.
* If only the host is given as URL address, the slash
* character (e.g. "/") will be set as value of the
* URI path, e.g. of $_SERVER['REQUEST_URI']. Therefore,
* the route pattern should be set to "/" as well.
*/
$routes->new('/', [
'controller' => 'HomeController',
'method' => 'index',
]);
//...
/*
* In order to get the URI path, you must use the server
* parameter "REQUEST_URI" instead of "QUERY_STRING".
*/
$routes->redirectToController(
$_SERVER['REQUEST_URI']
);
Notes:
In regard of changing $_SERVER['QUERY_STRING'] to $_SERVER['REQUEST_URI'], the credits go to #MagnusEriksson, of course.
There can't be an "MVC framework", but a "web framework for MVC-based application(s)". This is, because a framework is just a collection of libraries (not at all correlated with MVC), which, in turn, is used by one or more applications implementing the MVC pattern.
For any further questions, don't hesitate to ask us.

PHP site run correct on the localhost:8000 but gives erreurs on XAMPP or other server. How to create .htaccess?

This is my first experience to create a site in PHP.
My project run correct on the php interne server , but not on the Xampp ni on the server ovh
ovh serveur erreur: App\Router::run(): Failed opening required '/home/myla/www/views/.php' (include_path='.:/usr/share/php': var $view false
localhost:8000 work correct: var $view post/index
XAMPP erreur : Trying to access array offset on value of type bool :
var $view false
The probleme is in the var $view in the function run().
public function run ():self
{
$match = $this->router->match();
$view= $match['target'] ;
$params= $match['params'];
$router= $this;
$isAdmin= strpos($view, 'admin/') !== false;
$isUser =strpos($view, 'user/') !== false;
if(!$isAdmin && !$isUser){
$layout = 'layouts/default';
}
if($isUser){
$layout = 'user/layouts/default';
}
if ($isAdmin) {
$layout = 'admin/layouts/default';
}
try{
ob_start();
require $this->viewPath . DIRECTORY_SEPARATOR . $view . '.php';
$content = ob_get_clean();
require $this->viewPath . DIRECTORY_SEPARATOR . $layout . '.php';
} catch (ForbiddenException $e) {
header('Location: ' . $this->url('login') . '?forbidden=1');
die();
}
return $this;
}
I use run() in the index.php :
$router = new App\Router(dirname(__DIR__) . '/views');
$router
->get('/', 'post/index', 'home')
->get('/blog/category/[*:slug]-[i:id]', 'category/show', 'category')
->get('/blog/[*:slug]-[i:id]', 'post/show', 'post')
->match('/login','auth/login','login')
->match('/register','auth/register','register')
->post('/logout','auth/logout','logout')
->run();
I try to create .htaccess to re-write the rule, but i didnt found the good configuration.
File index.php is in the folder public and folders public,src,views are in the racine of the projet .
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ /public/index.php [L]
Its not work.
Can you kindly help me to configurate .htaccess
Thanks en advance.
Here is a good configuration:
RewriteEngine On
RewriteBase /
RewriteCond %{THE_REQUEST} /public/([^\s?]*) [NC]
RewriteRule ^ %1 [L,NE,R=302]
RewriteRule ^((?!public/).*)$ public/$1 [L,NC]

Altorouter can't execute routes

I am using Altorouter in a basic PHP App(No framework) but somehow it's not working. Below are details:
index.php
<?php
error_reporting(E_ALL);
ini_set('display_errors',1);
require_once __DIR__ . '/vendor/autoload.php';
$router = new AltoRouter();
$router->map( 'GET', '/', function() {
include __DIR__ . 'home.php';
});
print "Done";
It prints Done and no error in php log.
htaccess
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . index.php [L]
I am access it as `http://localhost/home/myapp/
Ok I figured out the issue. The URL I want to access is:
http://localhost/home/myapp/
Altorouter does not know about root URL so basePath needs to be set. it is done as:
$router->setBasePath('/home/myapp');
Do note that there's no trailing / should be put in setBasePath because we will put that in our map function like that:
$router->map('GET', '/', 'home.php', 'home');
$match = $router->match();
if ($match) {
require $match['target'];
} else {
header("HTTP/1.0 404 Not Found");
require '404.html';
}

Klein routes don't return anything

I've got this code in my index.php
<?php
require 'vendor/autoload.php';
$router = new \Klein\Klein();
$router->respond('/hello-world', function () {
return 'Hello World!';
});
$router->dispatch();
and htaccess:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . /index.php [L]
and when i try to open /hello-world (or index.php/hello-world) it just gives me a blank white screen.
If i have only this route:
$router->respond(function () {
return 'All the things';
});
it works on index.php/ but not on /
I'm looking for a long time but can't see whats wrong?
Try this and change /path/to/app with your real path to the app
define('APP_PATH', '/path/to/app');
require_once 'vendor/autoload.php';
$request = \Klein\Request::createFromGlobals();
$request->server()->set('REQUEST_URI', substr($_SERVER['REQUEST_URI'], strlen(APP_PATH)));
$klein = new \Klein\Klein();
$klein->respond('GET', '/hello', function () {
return 'Hello World!';
});
$klein->dispatch($request);
It looks like the rewrite does not work. Just try to echo something simple in the php without any framework like so:
index.php (only these three lines)
<?php
echo 'does it work?';
?>
Then try to call something like /hello-world. If it does not show your message, maybe your host does not support mod_redirect.
You should be able to display all activated apache modules with the function apache_get_modules:
<?php
print_r(apache_get_modules());
?>
There should be mod_rewrite listed.

How to prevent 403, 400 errors URL forwarding?

Site works good when user enter any url which doesn't exist and forward request to error controller.
But
If you write a script in url site throw 403 error
If you write some asp codes site throw 400 error
How can i prevent this and forward them to custom 403 and 404 pages? I tried forward with htaccess but i couldn't succeed it.
Another problem:
If you write ANY ascii code in adress bar, bootstrap forward to welcome page (controller ->index.php) .How is possible?
Directory structures, htaccess and bootstrap codes are below. Thank you for any help.
Directory structure:
/config
/libs
-bootstrap.php
/controllers
/models
/views
/public_html
-index.php
htaccess
htaccess
htaccess in main directory
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteRule ^$ public_html/ [L]
RewriteRule (.*) public_html/$1 [L]
</IfModule>
htaccess in public_html directory
Options -Indexes
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?url=$1 [PT,L]
</IfModule>
index.php in public_html
<?php
define('DS', DIRECTORY_SEPARATOR);
define('ROOT', dirname(dirname(__FILE__)));
require_once (ROOT . DS . 'libs' . DS . 'bootstrap.php');
$app = new Bootstrap();
bootstrap.php in libs
<?php
class Bootstrap {
function __construct() {
$url = isset($_GET['url']) ? $_GET['url'] : null;
$url = rtrim($url, '/');
$url = explode('/', $url);
print_r($url);
if (empty($url[0])) {
require '../controllers/index.php';
$controller = new Index();
$controller->index();
return false;
}
$file = '../controllers/' . $url[0] . '.php';
if (file_exists($file)) {
require $file;
} else {
$this->error();
return false;
}
$controller = new $url[0];
// calling methods
if (isset($url[2])) {
if (method_exists($controller, $url[1])) {
$controller->{$url[1]}($url[2]);
} else {
$this->error();
}
} else {
if (isset($url[1])) {
if (method_exists($controller, $url[1])) {
$controller->{$url[1]}();
} else {
$this->error();
}
} else {
$controller->index();
}
}
}
function error() {
require '../controllers/error.php';
$controller = new Error();
$controller->index();
return false;
}
}

Categories