PHP Built-in and htaccess - Routing System / Friendly URL

3

I have a .htaccess file for route deviation on the server (production) and a router.php file for route deviation using the PHP 7 Built-in server.

php -S 0.0.0.0:8000 router.php

However, I would like to use router.php also in production, with the same effect.

My server has management with WHM and CPanel domains (also with PHP 7, with the same site settings).

Note that it is not just about putting content in index.php , or transferring responsibility via .htaccess, since the route file has specific commands, such as the famous .. .

return false;

... to indicate that the router.php should be bypassed and go straight to the URI folder.

And this does not work on a common access.

Practical example (purely didactic):

Project Folders / Files

1 - /api/execute.php
2 - /admin/
3 - /index.php

Routes (Source URI):

1 - /api/{servico}/{detalhe}
2 - /admin/
3 - /{caminho}/{qualquer}

How is .htaccess (production):

RewriteEngine On
RewriteRule ^api/?.*$ api/execute.php [NC,L]
RewriteRule ^admin/?(.*)$ admin/$1 [NC,L]
RewriteRule ^/?.*$ index.php

How is the router.php (local / Built-in):

<?php
if (php_sapi_name() === 'cli-server' && is_file(__DIR__ . parse_url($_SERVER[ 'REQUEST_URI' ], PHP_URL_PATH))) {
    return false;
}

// Inicializa serviço de controle de URI
$uri = new \Config\Uri();

// API
if (preg_match('/^api\/?.*$/', $uri->getUri())) {
    require_once 'api/execute.php';
    exit;
}

// ADMIN
if (preg_match('/^admin\/.*$/', $uri->getUri())) {
    return false;
}

// Site
require_once "index.php";

This is just an example, but note the use of return false; . All other router.php lines run both locally and in production.

But return false; , which aims to ignore the router and follow uri's path naturally, does not work online, obviously.

How to proceed?

Obs : This is an old system that still needs support. It is not worth changing his entire route system, since a new system is being created. So I just wanted to use the same router.php in production so I would not have to use custom .htaccess for every domain that uses the system.

    
asked by anonymous 19.10.2016 / 20:21

1 answer

2

Let's see if I can help, and if I understood the question well.

I leave here an excerpt of the code that I use in a framework that I have developed over the years, and that I use in several PHP projects.

First, what we want is a single point in PHP that is responsible for all routing logic, and for that we have to have something like this in the .htaccess file:

RewriteRule ^/?.*$ /pageHandler.php?CUSTOM_HTACCESS_VAR=$1 [QSA,NC,L]

This will redirect all requests to the pageHandler, and all URL data will be accessible in $_GET['CUSTOM_HTACCESS_VAR'] (alternatively this can also be done and accessed through internal PHP variables such as $_SERVER['REQUEST_URI'] )

In pageHandler, we create an instance of my parsing class, and call the processPage method.

The content of the class Parser stays here (only the relevant part):

<?php
class Parser {
    var $URL;
    var $file; // the current PHP file being used
    var $vars;
    var $path;
    var $timer;
    var $fullPathExists = true;

    function __construct() {
        $this->requestID = uniqid(md5(rand()), true);

        $varName = "CUSTOM_HTACCESS_VAR";
        $this->URL = array();
        if (isset($_GET[$varName])) {
            if (substr($_GET[$varName], 0, 1) == "/") $_GET[$varName] = substr($_GET[$varName], 1);
            $url = explode("/", $_GET[$varName]);
            $this->URL = $url;
        }

        unset($_GET[$varName]);
        $this->vars = array();
        $this->path = array();

        $dir = "{$_SERVER['DOCUMENT_ROOT']}/Pages/";
        $tamanhoURL = count($this->URL);
        for($i = 0; $i < $tamanhoURL; $i++) {
            $tempDir = "{$dir}{$this->URL[$i]}/";
            if (!is_dir($tempDir)) {
                break;
            }
            $dir = $tempDir;
            $this->path[] = $this->URL[$i];
        }

        # verifica se existe dentro da ultima pasta um ficheiro com o nome que nao é o index
        if (($i < $tamanhoURL) && file_exists("{$dir}{$this->URL[$i]}.php")) {
            $file = "{$dir}{$this->URL[$i]}.php";
            $script = $this->URL[$i];
            $this->path[] = $this->URL[$i];
            $i++;
        }
        else {
            $file = "{$dir}index.php";
            $script = "index";
        }

        $this->file = $file;

        for (;$i < $tamanhoURL - 1; $i++) {
            $this->vars[$this->URL[$i]] = $this->URL[++$i];
            $this->fullPathExists = false;
        }
        if ($i < $tamanhoURL) {
            $this->vars['SINGLE'] = $this->URL[$i];
            $this->fullPathExists = false;
        }

    }


    function processPage() {
        if (file_exists($this->file)) {
            require($this->file);
        }
        else {
            header("HTTP/1.0 404 Not Found");
            header("Status: 404 Not Found");
        }
    }
}
?>

Hope it helps. You may have to adapt the code to work on those sites that already have their own structure, which may differ from what I use.

It should also be noted that this class stores all the parts of the URL that do not correspond to a file in a variable named vars, and which can be used from an MVC framework perspective.

For example, the URL / test / xpto / do / action can be used to load the file /teste/xpto.php, and in the variable vars is an element, named 'do' with the value 'action' p>     

25.10.2016 / 18:47