Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Help with bootstrap and regex for PHP

I am working on a new PHP framework for personal use in future projects, and below is my planned file structure so far. I just need some help with some regex for my .htaccess file and some help for how I can load the files I want.

Basically, any "folder" after the domain should load from my "module" folder. I would like to have it load www.domain.com/account/ from www.domain.com/module/account/. I also want it in that format for any other folder I have under modules. All folders/files under "module" should load as if it were in the top level.

In this example though in my module/account/ folder, if I have a file called home.php then I should be able to access it with www.domain.com/account/home instead of www.domain.com/module/account/home.php, and www.domain.com/module/user/register.php would actually be accessed by www.domain.com/user/register

I hope this makes sense and appreciate any help and any advice. I mainly need help with the .htaccess file to make this folder structure work. I have not decided if all files should be accessed though a single index file or if I should just include a bootstrap type file into every page. The bootstrap file would set up all variables, config options, as well as auto load all class files and create objects needed.

myFramework/
--/assets/
--------/css/
--------/images/
--------/javascript/
--/includes/
---------/classes/
---------/config/
---------/language/
---------/header.php
---------/footer.php
--/module/
--------/account/
----------------/create.php
----------------/login.php
----------------/logout.php
----------------/settings.php
----------------/editprofile.php
--------/admin/
--------/blog/
--------/forums/
--------/messages/
--------/users/
--index.php
like image 636
JasonDavis Avatar asked Jan 21 '23 18:01

JasonDavis


2 Answers

The answer from jasonbar is actually almost there. All it lacks is dealing with the .php extension as you described:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !^/module
RewriteCond %{REQUEST_URI} [.]php$
RewriteRule (.*)[.]php$ /module/$1

That being said, I'd strongly encourage you to consider a front controller paradigm (as you eluded to in your problem description) as doing so allows for much greater control, encourages an MVC approach, etc. =o)

EDIT:

I corrected a few neglected points and added proper processing of the PHP extension. Note that the [L] argument at the end causes further processing to cease, making these code blocks useful as logical structures within your .htaccess file (i.e. by preventing any processing that follows); remove that argument if such functionality is not desired.

I've also added a line to specifically check that the php file being requested actually exists.

RewriteEngine On

# if the uri matches a directory in the module dir, redirect to that. Disable 
# this block if you don't wish to have either directory browsing or to have the 
# default apache file load.
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{DOCUMENT_ROOT}/module%{REQUEST_URI} -d
RewriteCond %{REQUEST_URI} !^/includes
RewriteCond %{REQUEST_URI} !^/assets
RewriteCond %{REQUEST_URI} !^/module
RewriteRule (.*) /module/$1 [L]

# if the uri matches a file sans the .php extension in the module directory, 
# then redirect to that.
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{DOCUMENT_ROOT}/module%{REQUEST_URI}.php -f
RewriteCond %{REQUEST_URI} !^/includes
RewriteCond %{REQUEST_URI} !^/assets
RewriteCond %{REQUEST_URI} !^/module
RewriteRule (.*) /module/$1.php [L]

EDIT:

To also allow files that end in ".php" to be served from the module directory, add the following to your .htaccess file:

# if the uri matches a file with the .php extension in the module directory, 
# then redirect to that.
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{DOCUMENT_ROOT}/module%{REQUEST_URI} -f
RewriteCond %{REQUEST_URI} !^/includes
RewriteCond %{REQUEST_URI} !^/assets
RewriteCond %{REQUEST_URI} !^/module
# note that the following line restricts access to php files only. comment out 
# the following line to allow any existing file under module director to be 
# accessed (or modify the following to allow other file extensions to be read)
RewriteCond %{REQUEST_URI} [.]php$  
RewriteRule (.*) /module/$1 [L]
like image 84
emanaton Avatar answered Jan 27 '23 22:01

emanaton


I'd try to solve this in PHP itself, if it were up to me. Just create a .htaccess file that maps every possible request to a single file (probably index.php), and determine what to do from there. That gives you an opportunity to do all kinds of bootstrapping and logging before delegating the request to whatever piece of code should handle that request. You could even include and use a micro framework such as Limonade to accomplish what you want. Here's an example:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d # if the requested directory does not exist,
RewriteCond %{REQUEST_FILENAME} !-f # and the requested file does not exist,
RewriteRule ^ index.php             # map everything to index.php. 

Then, in index.php, you can do a wide variety of things to make sure you get the correct response. The simplest way to use a "controller like structure", would be to include a framework such as Limonade, and use it. An example:

<?php
require_once 'vendor/limonade.php';

dispatch( 'account/home', 'accountHome' );

function accountHome( ) {
    require_once 'modules/account/home.php';
}

run( );

Obviously, that is just a suggestion. Alternatively, you could just make use of an even simpler system, although I guess you'd have to write that yourself. That way you can say, if the file exists in the modules directory, just include this file, and that's that.

<?php
$path = isset( $_SERVER['PATH_INFO'] ) ? trim( $_SERVER['PATH_INFO'], '/' ) : null;
if( $path !== null ) {
    $filename = 'module/' . $path . '.php'; /** $path could be account/home */
    if( file_exists( $filename ) ) {
        require_once $filename;
    }
    else {
        require_once 'error.php';
    }
}
else {
    require_once 'home.php';
}

That's it. Fully functional and all. You could benefit from using a library that sorts this all out for you though.

like image 37
Berry Langerak Avatar answered Jan 27 '23 23:01

Berry Langerak