PHP Developers Network

A community of PHP developers offering assistance, advice, discussion, and friendship.
 
Loading
It is currently Fri Aug 18, 2017 3:11 pm

All times are UTC - 5 hours




Post new topic Reply to topic  [ 10 posts ] 
Author Message
PostPosted: Wed Feb 13, 2013 5:23 pm 
Offline
Tranquility In Moderation
User avatar

Joined: Sun Feb 06, 2005 8:18 pm
Posts: 5001
Location: Indiana
This fit my needs perfectly and is very simple and allows for a great amount of flexibility. This will allow me to write any amount of pretty url's with unlimited depth while maintaining a single directory structure for my files.

Example URL: example.com/foo-bar/ would use /foo-bar.php
Example URL: example.com/foo-bar/string/ would use /foo-bar_string.php
Example URL: example.com/foo-bar/string/subsection would use /foo-bar_string_subsection.php
Example URL: example.com/a/b/c/d/e/f/g/h/i would use /a_b_c_d_e_f_g_h_i.php

This file should be used as index.php.

The following .htaccess rules should be used (thanks to requinix @ forums.devnetwork.net)
Syntax: [ Download ] [ Hide ]
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/?(.*) index.php [L]



$_GET and $_POST will still be abailable in their usual manner

Syntax: [ Download ] [ Hide ]
<?php

/**
 * A very simple URL manager/rewriter/router, set this file as index.php
 * With .htaccess rule, allows any length of "pretty URL's" to be written and
 * funneled to this index.php and routed to their actual scripts.
 *
 * For example, a URL of /foo-bar/ would be directed to /foo-bar.php
 * For example, a URL of /foo-bar/example/ would be directed to
 *     /foo-bar_example.php
 * For example a URL of /foo-bar/example/detail/subsection/ would be directed
 *     to /foo-bar_example_detail_subscection.php
 *
 * The .htacess file should look like this: (thanks to requinix @ forums.devnetwork.net)
 *
 * RewriteEngine On
 * RewriteCond %{REQUEST_FILENAME} !-f
 * RewriteCond %{REQUEST_FILENAME} !-d
 * RewriteRule ^/?(.*) index.php [L]
 *
 * @file        index.php
 * @author      Scott Martin <sjm.dev1 -[at]-gmail-[dot]- com>
 * @date        Feb 13th, 2013
 * @package     None
 */

 
if (!empty($_SERVER['REQUEST_URI']))
{
        //to avoid recursion, actual index content must be in separate script
        if ($_SERVER['REQUEST_URI'] == '/' || $_SERVER['REQUEST_URI'] == '/index')
        {
                require_once 'index_content.php';
                exit;
        }
       
        //request uri will be available and stored in $fileName
        $fileName = $_SERVER['REQUEST_URI'];
       
        //get rid of the query string if present (it is still available in $_GET)
        if (strpos($fileName, '?') !== false)
        {
                $fileName = strtok($fileName, '?');
        }
       
        //replace beginning and trailing slashes
        $fileName = trim($fileName, '/');
       
        //replace slashes with underscores, and lowercase
        $fileName = strtolower(str_replace('/', '_', $fileName));
       
        //check for appropriate characters and file exists
        if (preg_match('#^[a-zA-Z0-9_-]+$#', $fileName) && file_exists($_SERVER['DOCUMENT_ROOT'] . '/' . $fileName . '.php'))
        {
                require_once $_SERVER['DOCUMENT_ROOT'] . '/' . $fileName . '.php';
                exit;
        }
}

//if we reach this point, we send a 404 header
header('HTTP/1.0 404 Not Found');
require_once '404.php';
exit;

_________________
Set Search Time - A google chrome extension. When you search only results from the past year (or set time period) are displayed. Helps tremendously when using new technologies to avoid outdated results.


Top
 Profile  
 
PostPosted: Wed Feb 13, 2013 5:53 pm 
Offline
Site Administrator
User avatar

Joined: Wed Aug 25, 2004 7:54 pm
Posts: 13421
Location: New York, NY, US
s.dot wrote:
Example URL: example.com/a/b/c/d/e/f/g/h/i would use /a_b_c_d_e_f_g_h_i.php

This part confuses me. Why not just have the URL example.com/a_b_c_d_e_f_g_h_i and use the / for actual directory separators? Seems confusing. Or reverse it and use pear style naming so example.com/a_b_c_d_e_f_g_h_i would load /a/b/c/d/e/f/g/h/i.php?

_________________
(#10850)


Top
 Profile  
 
PostPosted: Wed Feb 13, 2013 6:06 pm 
Offline
Tranquility In Moderation
User avatar

Joined: Sun Feb 06, 2005 8:18 pm
Posts: 5001
Location: Indiana
I am doing a quick just for fun site. I just wanted a single directory for the files, and a way to map the structured url to the file it would use. /Category/Pagename would look much better than /category_pagename and allows me to maintain a pseudo directory structure.

Works for my purposes, even if it's not standard practices.

_________________
Set Search Time - A google chrome extension. When you search only results from the past year (or set time period) are displayed. Helps tremendously when using new technologies to avoid outdated results.


Top
 Profile  
 
PostPosted: Wed Feb 13, 2013 7:29 pm 
Offline
Forum Regular
User avatar

Joined: Tue Sep 28, 2010 11:41 am
Posts: 983
Location: Columbus, Ohio
There is a problem with your preg_match in that it is checking for a single instance of the class of [a-zA-Z0-9_-] to match ANYWHERE in $filename.

You should do:
Syntax: [ Download ] [ Hide ]
preg_match('/^[a-z0-9_-]+$/i', $fileName)

which says match one or more of the class, anchored to both the start and end of the string.


Top
 Profile  
 
PostPosted: Wed Feb 13, 2013 7:35 pm 
Offline
Tranquility In Moderation
User avatar

Joined: Sun Feb 06, 2005 8:18 pm
Posts: 5001
Location: Indiana
Good catch!

I wanted to use ctype_alnum but it won't allow for _ and -. I don't like using a regex there. I'll update the main post now.

_________________
Set Search Time - A google chrome extension. When you search only results from the past year (or set time period) are displayed. Helps tremendously when using new technologies to avoid outdated results.


Top
 Profile  
 
PostPosted: Thu Feb 14, 2013 12:33 am 
Offline
Site Administrator
User avatar

Joined: Wed Aug 25, 2004 7:54 pm
Posts: 13421
Location: New York, NY, US
Here is one I have used in the past, but it uses PATH_INFO instead. I modified it to look/work more like yours and added the / - translation you do.
Syntax: [ Download ] [ Hide ]
$ConfigArray = array(
        'path' => dirname(__FILE__) . '/pages/',
        'index' => 'index_content',
        'error' => '404',
        );

$fileName = isset($_SERVER['PATH_INFO']) ? trim($_SERVER['PATH_INFO'], '/.') : '';
if ($fileName == '') {
        $fileName = $ConfigArray['index'];
}

//replace slashes with underscores, and lowercase
$fileName = strtolower(str_replace('/', '_', $fileName));

//check for appropriate characters
if (preg_match('/^[a-zA-Z0-9_-]*$/', $fileName)) {
        //check if file exists
        if (!file_exists($ConfigArray['path'] . $fileName . '.php')) {
                $error = 2;             // route does not exist
                $fileName = $ConfigArray['error'];
        }
} else {
        $error = 1;                     // illegal route name
        $fileName = $ConfigArray['error'];
}
require_once $ConfigArray['path'] . $fileName . '.php';

This is more of a Front Includer rather than a Front Controller that dispatches Action Controllers. I think it would probably double the size of the code to support standard /class/method/ style routes that loaded and instantiated a class and called a method.

_________________
(#10850)


Top
 Profile  
 
PostPosted: Mon Feb 25, 2013 4:26 pm 
Offline
Tranquility In Moderation
User avatar

Joined: Sun Feb 06, 2005 8:18 pm
Posts: 5001
Location: Indiana
Nice Chris. :)

Today, after i left my computer on for a few days, I went to go browse my website and everything went to the index page. I did a print_r() on $_SERVER and every page was REQUEST_URI = '/'.

Then my browser crashed.

I restarted it and then it started working fine again. Was this just something screwy with my browser, or is request_uri unreliable?

_________________
Set Search Time - A google chrome extension. When you search only results from the past year (or set time period) are displayed. Helps tremendously when using new technologies to avoid outdated results.


Top
 Profile  
 
PostPosted: Mon Feb 25, 2013 7:37 pm 
Offline
Site Administrator
User avatar

Joined: Wed Aug 25, 2004 7:54 pm
Posts: 13421
Location: New York, NY, US
s.dot wrote:
or is request_uri unreliable?

I don't remember. I know you need to be careful of values in $_SERVER because some come from the user via Apache/webserver without much validation/filtering. Those values cannot be fully trusted, but I don't know if they can get corrupted.

_________________
(#10850)


Top
 Profile  
 
PostPosted: Wed Feb 27, 2013 5:05 pm 
Offline
Tranquility In Moderation
User avatar

Joined: Sun Feb 06, 2005 8:18 pm
Posts: 5001
Location: Indiana
Corruption wouldn't matter in this case because it would just send a 404 based on the rewriter script. But as long as REQUEST_URI is always set I'm good. I know the value comes from the server, and has seemed to be set in every instance except this one where the browser crashed.

_________________
Set Search Time - A google chrome extension. When you search only results from the past year (or set time period) are displayed. Helps tremendously when using new technologies to avoid outdated results.


Top
 Profile  
 
PostPosted: Wed Feb 27, 2013 10:54 pm 
Offline
Site Administrator
User avatar

Joined: Wed Aug 25, 2004 7:54 pm
Posts: 13421
Location: New York, NY, US
The code I posted does an isset() check on the $_SERVER value first. You should probably do that as well.

_________________
(#10850)


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 10 posts ] 

All times are UTC - 5 hours


Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Jump to:  
Powered by phpBB® Forum Software © phpBB Group