1

I'm looking to store pages for my website in dedicated directories to make them a little easier to manage and to store handlers alongside their pages but I don't want the user to see the directory structure when visiting these pages.

e.g. If a page is stored in https://mywebsite.com/faq/faq.php and a user visits this page I'd like them to see https://mywebsite.com/faq.php

Is there any way to mask the URL or to hide the internal file structure? I'd prefer to do this in PHP or server-side so as not to allow any of this masking to be visible client-side

I've tried looking into this using other SO questions but nothing seems to give the answer I need. I've found answers on using .htaccess but this just seems to allow denying users access to certain areas.

I've also taken a look into vanity URLs but the URL still changes on redirect

Adam Roberts
  • 562
  • 1
  • 5
  • 20
  • 1
    with `.htaccess` you can rewrite urls as you want via the `RewriteRule`. So you'd rewrite from `https://mywebsite.com/faq.php` to `https://mywebsite.com/faq/faq.php`. A maybe usefull read (one of the first google findings): https://mediatemple.net/community/products/dv/204643270/using-htaccess-rewrite-rules – Jeff Jan 03 '19 at 23:29
  • I think your best shot will be using .htaccess RewriteRule however it is possible to do it using PHP, but there are some work to do :) – Soren Jan 03 '19 at 23:36
  • Have you tried this? https://stackoverflow.com/questions/18973058/how-to-remove-folder-name-from-url-using-htaccess – Vörös Imi Jan 03 '19 at 23:43

2 Answers2

3

.htaccess is the fastest and easiest way to do it with RewriteRule, but if your site has hundreds of links then it won't be feasible, especially if you need to keep updating it as this process is done manually.

You could try using shortened URL's. https://bitly.com/ This way you can also keep track of clicks.

Or if you do have too many URL's then maybe you should create a redirect page. How to make a redirect in PHP?

Jacou Mata
  • 91
  • 2
1

I wrote some lines of code to help you out starting with the realization of your idea.

Create the index.php file

The first thing we need is to process all requests in one place, which is in our case going to the index.php file located in your main application folder.

Configuring the .htaccess file

We are [still] going to use the .htaccess rewriterule, so let's start by adding a basic RewriteRule to the .htaccess file that will help us hide the index.php from the URI and redirect all requests through the index.php file:

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteRule ^ index.php [L]
</IfModule>

Building the logic inside the index.php file

Now we are ready to start building the logic inside the index.php file.

The idea i thought of is making an app directory that contains all of your application's folders, which results in the following structure:

app
app\faq
app\faq\faq.php
.htaccess
index.php

To achieve this, i have made the following (explained below) code and inserted it into the index.php :

<?php
//This function is from: https://www.lucidar.me/en/web-dev/how-to-get-subdirectories-in-php/
function getSubDirectories($dir)
{
    $subDir = array();
    $directories = array_filter(glob($dir), 'is_dir');
    $subDir = array_merge($subDir, $directories);
    foreach ($directories as $directory) $subDir = array_merge($subDir, getSubDirectories($directory.'/*'));
    return $subDir;
}
function response(string $appDir, string $uri)
{
    $currentDir = __DIR__;
    $currentDirBaseName = basename($currentDir); //Get the the basename of the current directory

    $filename = str_replace('/'.$currentDirBaseName.'/', '', $uri); //Remove the current directory basename from the request uri

    if(strpos($filename, '/') > -1) { //If the user is asking for a directory respond with an exception
        http_response_code(404);
        echo "The requested file was not found.";
    }

     foreach(getSubDirectories($currentDir.'/'.$appDir) as $dir) { //Iterate through all the subdirerctories of the app directory
        $file = $dir.'/'.$filename; //Filename
        if(!is_dir($file) && file_exists($file)) { //If the $file exists and is not a directory, `include()` it
            include($dir.'/'.$filename);
            exit; //or return;
        }
    }
    http_response_code(404);
    echo "The requested file was not found.";
} 
//Get the request uri
$uri = $_SERVER['REQUEST_URI'];
//Define the app directory
$appDirectory = 'app';
response($appDirectory, $uri);

What this code actually does is taking the filename from the request uri and looking for it in all of the $appDirectory subdirectories (recursively), if the file is found it will be included in the index.php file , else an error will be displayed.

NOTE: This script is just for demonstration, and it still needs development. e.g. In some cases you might have two files with the same names in two different directories, this script will only display the first file it finds.

I also suggest reading "How to build a basic server side routing system in PHP".

Raed Yakoubi
  • 332
  • 3
  • 8
  • This is great! Thanks! I'm guessing in this situation the home page would also need to be within the app directory, with some sort of default rule/route if no URI is provided? – Adam Roberts Jan 05 '19 at 13:30
  • 1
    You can just check if the variable $filename is null, if it is, you can include your homepage from any directory, like this: ```if(is_null($filename)) { include('homepage.php'); } ``` Note that this needs to go exactly after the assignment of the $filename variable. – Raed Yakoubi Jan 05 '19 at 20:23