Search code examples
php.htaccessurl-rewritingoutput-buffering

PHP URL Rewriting from Output Buffer


I am trying to rewrite my URLs in PHP using the output buffer. Ideally this is so in my source I can keep my links as example.com/index.php?action=123;sa=456;sa2=789 but when outputted to the browser it rewrites as example.com/123/456/789 It seems to be working but when it gets to the "sa2" rewriting the output buffer tends to break occasionally and all the browser sees is a blank white page. When the page loads it starts an output buffer with gzip and then an output buffer with a rewrite callback. Here is my php/.htaccess

<?php

if (!ob_start("ob_gzhandler"))
    ob_start();

// Handle Rewriting of URLs
RewriteURLs();

function RewriteURLs()
{
// rewrite URLS from output buffer
function rewrite($buffer)
{
    // pages
    $buffer = preg_replace('/index.php\?page=(.*?)/is', "page/$1", $buffer);
    // sub-sub-actions
    $buffer = preg_replace('/index.php\?action=(.*?);sa=(.*?);sa2=(.*?)/is', "$1/$2/$3", $buffer);
    // sub-actions
    $buffer = preg_replace('/index.php\?action=(.*?);sa=(.*?)/is', "$1/$2", $buffer);
    // actions
    $buffer = preg_replace('/index.php\?action=(.*?)/is', "$1", $buffer);
    // index.php removal
    $buffer = preg_replace('/index.php/is', "", $buffer);
    return $buffer;
}
// start for rewriting
ob_start('rewrite');
}

// rest of content/page loading.......
?>

.htaccess to handle the rewriting

Options +FollowSymLinks  
RewriteEngine on  
RewriteBase   /
# Rules for: pages
RewriteRule ^page/([-_!~*'()$\w]+)/?$  index.php?page=$1    [L,QSA]

# Rules for sub-sub-actions
# /{action}/{subaction}/{subsubaction}/
RewriteRule ^([-_!~*'()$\w]+)/([-_!~*'()$\w]+)/([-_!~*'()$\w]+)/?$ index.php?action=$1;sa=$2;sa2=$3

# Rules for sub-actions
# /{action}/{subaction}/
RewriteRule ^([-_!~*'()$\w]+)/([-_!~*'()$\w]+)/?$ index.php?action=$1;sa=$2

# Rules for: actions
# /{action}/
RewriteRule ^([-_!~*'()$\w]+)/?$  index.php?action=$1    [L,QSA]

This looks more and more like a PHP output buffer problem I just cannot seem to find what I am doing wrong. Any help is greatly appreciated.


Solution

  • Take care of this piece of code because based on the php version you use the buffer string sent to the rewrite function can contain only a chunk of the whole buffer (breaking the regular expression logic). You must force the chuck_size optional parameter to zero (in php version 5.4 and lower the default chuck size is 4096 bytes)

    Take a look at the documentation about ob_start:

    http://es.php.net/manual/en/function.ob-start.php

    This is probably the reason why this code "breaks occasionally"