WEB DEVELOPMENT
[edit]

Router

PHP can be written to route webpages with the help of an .htaccess file


<htaccess>
    RewriteEngine On
    RewriteCond %{REQUEST_URI}  !(.png|.jpg|.webp|.gif|.jpeg|.zip|.css|.svg|.js)$
    RewriteRule (.*) routes.php [QSA,L]
</htaccess>


session_start();


function get($route, $path_to_include)
{
    if( $_SERVER['REQUEST_METHOD'] == 'GET' ){ 
        route($route, $path_to_include);
    }  
}


function post($route, $path_to_include)
{
    if( $_SERVER['REQUEST_METHOD'] == 'POST' ){
        route($route, $path_to_include);
    }    
}


function put($route, $path_to_include)
{
    if( $_SERVER['REQUEST_METHOD'] == 'PUT' ){
        route($route, $path_to_include);
    }    
}


function patch($route, $path_to_include)
{
    if( $_SERVER['REQUEST_METHOD'] == 'PATCH' ){
        route($route, $path_to_include);
    }    
}


function delete($route, $path_to_include)
{
    if( $_SERVER['REQUEST_METHOD'] == 'DELETE' ){
        route($route, $path_to_include);
    }    
}


function any($route, $path_to_include)
{
    route($route, $path_to_include); 
}


function route($route, $path_to_include)
{
  
    // Callback function
    if( is_callable($path_to_include) ){
        call_user_func($path_to_include);
        exit();
    }    
  
    $ROOT = $_SERVER['DOCUMENT_ROOT'];
    
    if($route == "/404"){
        include_once("$ROOT/$path_to_include");
        exit();
    }  

    $request_url = filter_var($_SERVER['REQUEST_URI'], FILTER_SANITIZE_URL);
    $request_url = rtrim($request_url, '/');
    $request_url = strtok($request_url, '?');
    $route_parts = explode('/', $route);
    $request_url_parts = explode('/', $request_url);
    array_shift($route_parts);
    array_shift($request_url_parts);
    
    if( $route_parts[0] == '' && count($request_url_parts) == 0 ){
        include_once("$ROOT/$path_to_include");
        exit();
    }
    
    if( count($route_parts) != count($request_url_parts) ){
        return;
    }  
    
    $parameters = [];
    for( $__i__ = 0; $__i__ < count($route_parts); $__i__++ ){
    
        $route_part = $route_parts[$__i__];
        
        if( preg_match("/^[$]/", $route_part) ){
            $route_part = ltrim($route_part, '$');
            array_push($parameters, $request_url_parts[$__i__]);
            $$route_part=$request_url_parts[$__i__];
        }
        
        else if( $route_parts[$__i__] != $request_url_parts[$__i__] ){
            return;
        }
        
    }
    
    include_once("$ROOT/$path_to_include");
    exit();
}


function out($text)
{
    echo htmlspecialchars($text);
}


function set_csrf()
{
    if( ! isset($_SESSION["csrf"]) ){
        $_SESSION["csrf"] = bin2hex(random_bytes(50));
    }
    
    echo '<input type="hidden" name="csrf" value="'.$_SESSION["csrf"].'">';
}


function is_csrf_valid()
{
    if( ! isset($_SESSION['csrf']) || ! isset($_POST['csrf'])){
        return false;
    }
    
    if( $_SESSION['csrf'] != $_POST['csrf']){
        return false; 
    }
    
    return true;
}

require_once("{$_SERVER['DOCUMENT_ROOT']}/router.php");

// ##################################################
// ##################################################
// ##################################################

// Static GET
// In the URL -> http://localhost
// The output -> Index
get('/', 'index.php');

// Dynamic GET. Example with 1 variable
// The $id will be available in user.php
get('/user/$id', 'user.php');

// Dynamic GET. Example with 2 variables
// The $name will be available in user.php
// The $last_name will be available in user.php
get('/user/$name/$last_name', 'user.php');

// Dynamic GET. Example with 2 variables with static
// In the URL -> http://localhost/product/shoes/color/blue
// The $type will be available in product.php
// The $color will be available in product.php
get('/product/$type/color/:color', 'product.php');

// Dynamic GET. Example with 1 variable and 1 query string
// In the URL -> http://localhost/item/car?price=10
// The $name will be available in items.php which is inside the views folder
get('/item/$name', 'views/items.php');

// ##################################################
// ##################################################
// ##################################################
// any can be used for GETs or POSTs

// For GET or POST
// The 404.php which is inside the views folder will be called
// The 404.php has access to $_GET and $_POST
any('/404','views/404.php');