Monday 4 October 2010

Output buffering

This is just a wee bit of example code I made as a test so I thought I would share it.
What it does is allows me to parse an entire page through a filter to change things you want into whatever language a user has it set on, this example isn't awesome I did it in like 10 minutes but I'm posting it here to serve as an exmaple of what you CAN do with PHP and similar functions...

<?
ob_start('callbackLangParse');
session_start();

if(isset($_GET['lang'])) $_SESSION['lang'] = $_GET['lang'];
if(!isset($_SESSION['lang'])) $_SESSION['lang'] = 'en';

$lang = array();
$lang['en'] = array();
$lang['en']['1'] = 'shit';

$lang['de'] = array();
$lang['de']['1'] = 'scheisse';
$lang['de']['2'] = 'testicles';

function callbackLangParse($buffer){
    global $lang;
    preg_match_all('|\{\[text([0-9]+)\]\}|',$buffer,$text);
    $text['1'] = array_unique($text['1']);
    foreach($text['1'] as $var):
        if(isset($lang[$_SESSION['lang']][$var])):
            $buffer = str_ireplace('{[text'.$var.']}',$lang[$_SESSION['lang']][$var],$buffer);
        endif;
    endforeach;
   
    return $buffer;
}

echo "This is {[text1]} {[text2]} {[text1]}!!!";
?>


As you can see, that's the code I use so now I'ma run through what it all means...

<?
That basically starts parsing shit as PHP. (Obviously.)

ob_start('callbackLangParse');
session_start();
That's me telling the script to start the output buffer (ob_start) and when it's ready to output I told it to parse the buffer through the "callbackLangParse" function.
Then I started the session.
if(isset($_GET['lang'])) $_SESSION['lang'] = $_GET['lang'];
if(!isset($_SESSION['lang'])) $_SESSION['lang'] = 'en';
That checks to see if $_GET['lang'] is set, and if it is it tells the script to change $_SESSION['lang'] to whatever $_GET['lang'] is. (This basically means that users won't need to keep setting the language on every page as long as that session exists for them. You could also use cookies if you wanted.)
The next line checks to see if $_SESSION['lang'] exists at all and if it doesn't, it sets it to a default value. (And since I'm a native English speaker, I set it to "en".)
 
$lang = array();
$lang['en'] = array();
$lang['en']['1'] = 'shit';

$lang['de'] = array();
$lang['de']['1'] = 'scheisse';
$lang['de']['2'] = 'testicles';
This is just me setting the variables for the text that gets parsed, etc...
You could put these into seperate files and just include them if needed and such but I just put them in this file 'cause it was just an example.   

function callbackLangParse($buffer){
That's me just declaring the callbackLangParse function, and since this is a function used with ob_start, we need to allow it to have the $buffer variable which is passed on through the output buffering.

global $lang;
Normally in a function unless it's a superglobal or a global variable, a function won't be able to use it so here we're just telling thing function to basically look at the $lang variable as if it was that... (Or some pish like that.)

preg_match_all('|\{\[text([0-9]+)\]\}|',$buffer,$text);
Here we're using regular expression to do a search in the buffer text and then store all matches to the variable named $text.

$text['1'] = array_unique($text['1']);
Since the way I'm doing it I'm using str_ireplace I only need to know that something has been called at least once so this function removes any duplicates from the array.

foreach($text['1'] as $var):
Here we have a foreach to run through each variable in the $text['1'] array. (You'll note I'm using a ":" at the end and not a "{", I'll leave a note about this at the end of it.)

if(isset($lang[$_SESSION['lang']][$var])):
    $buffer = str_ireplace('{[text'.$var.']}',$lang[$_SESSION['lang']][$var],$buffer);
endif;
So here's we just doing a check to make sure that variable for the language chosen actually exists and if it does exist we do a search for the text used to look for the variable then we check it using str_ireplace to whatever the variable is. (Again, I used a ":" and not a "{", I'll leave a note, blah blah...)
 
endforeach;  
 Ok, this is just me closing that foreach that we started.
You might be used to normally using braces ({'s and }'s) but personally I dislike that and find it much easier to read code that tells you what has been closed and such, you'll notice I did the same with the above IF conditional, and you can do this with FOR and WHILE loops as well.
For more info, just go to http://www.php.net/manual/en/control-structures.alternative-syntax.php and I might also make a post on this as well if people want. 

return $buffer;
This basically just outputs the buffer once it's been parsed, 'nuff said?

}
Closes the callbackLangParse function.

echo "This is {[text1]} {[text2]} {[text1]}!!!";
?>
This just outputs the above string and then tells the script to stop parsing as PHP, but remember we're using output buffering so that shit doesn't just get displayed there automatically, it gets run through the callbackLangParse function as defined in the second line of this.


Ok, well that's the run through of the code done, so lets say you saved this as index.php and went to view it as it was without any modifications it would display the following if you just went to index.php

This is shit {[text2]} shit!!!

You'll noticed that one of the strings never got parsed, this is because that string wasn't defined in the language variables so instead it outputs what it is in the buffer before getting parsed otherwise it would just be blank...
So now if we went to index.php?lang=de, this is what it would show...

This is scheisse testicles scheisse!!!

As you can see, it ran through the parser and changed it, and if you were to go to index.php again without the lang var being in the URL, it would display the same since the users lang session ver has been set to de and all that jazz, to get it back to English you would need to go to index.php?lang=en and that would display the first example...


Anyways, that's me done for now, if you liked this leave a comment, if you think this sucks, leave a comment, if I did something wrong, leave a comment... You get the picture...
And if there's anything you want me to cover just leave a comment letting me know and I'll get to it as soon as I can. 

No comments:

Post a Comment