ASPit - Totally ASP JSit - Totally JavaScript
Search PHPit

Use this textbox to search for articles on PHPit. Seperate keywords with a space.

Advertisements

Create your own BBCode, using PHP

(Page 1 out of 2)

If you've ever been on a bulletin board then you've probably come across BBCode (Bulletin Board Code), the HTML-like tags that can be used to format your message. Most of the popular message board scripts, like vBulletin all have inbuilt support for BBCode.

In this tutorial, I'm going to show you how to create your own BBCode for your own PHP scripts. I will first present you with some easy BBCode's (such as [b], and [i]), and then I'll have a look at nesting BBCode.

The easy one's

The simple BBCode's, like [b] and [i], are really easy, and require hardly any knowledge at all. All we need for this is the preg_replace() function, and the right regular expressions. Let's begin our bbcode_format() function, like so:

function bbcode_format ($str) {
       
        return $str;
}

This doesn't do anything yet, but it will in a minute. First of all, let's add a htmlentities() line in our function, so we don't get any unwanted HTML or XSS injection. Add the following to your bbcode_format function:

$str = htmlentities($str);

Now let's have a look at writing the code for our simple BBCode's. If you have a look at the manual for the preg_replace function, you will notice that it takes three required parameters: the pattern, the replacement and the subject. The subject is our $str, the pattern is our bbcode, and the replacement is the HTML that the bbcode represents.

The hardest part of regular expressions is creating the right pattern. But thankfully this is extremely easy for our bbcode. For example, the pattern for the [b] tag looks like this:

/\[b\](.*?)\[\/b\]/is

The (.*?) part means 'match anything', so that's the text that must be made bold. The last two characters (is) are called modifiers. They are extra options that can be set. The i modifier is used to tell the regular expression engine that case doesn't matter, so that [B] is the same [b]. The s modifier is used to match new lines (/n) as well. If you don't include the s modifier, then you won't be able to make a whole block of text bolded. (Read more about Pattern Modifiers)

The replacement is also very easy. Just write the HTML you want to be used, and include $1 somewhere. What is $1? That is the variable that contains our text. Whenever you use a 'match anything' (or a similar pattern), a new variable is created that holds the text that was matched. For our [b] tag, the replacement looks like this:

$1

Our bbcode_format now looks like this:

function bbcode_format ($str) {
        $str = htmlentities($str);

        // Do simple BBCode's
        $str = preg_replace ('/\[b\](.*?)\[\/b\]/is', '$1', $str);
        $str = preg_replace ('/\[i\](.*?)\[\/i\]/is', '$1', $str);
        $str = preg_replace ('/\[u\](.*?)\[\/u\]/is', '$1', $str);

        return $str;
}

That's all that's necessary for our simple bbcodes. But we can make it slightly simpler, and probably even faster. Instead of having to use several preg_replace calls, we only have to make ONE preg_replace call, and pass the patterns and replacements as an array. Our function would then look like this:

function bbcode_format ($str) {
        $str = htmlentities($str);

        $simple_search = array(
                                '/\[b\](.*?)\[\/b\]/is',                               
                                '/\[i\](.*?)\[\/i\]/is',                               
                                '/\[u\](.*?)\[\/u\]/is'
                                );

        $simple_replace = array(
                                '$1',
                                '$1',
                                '$1'
                                );

        // Do simple BBCode's
        $str = preg_replace ($simple_search, $simple_replace, $str);

        return $str;
}

Finally, you can also have bbcodes with multiple parameters, e.g. [url=http://www.google.com]link[/url]. To create this, you just have to use a slightly different pattern:

/\[url\=(.*?)\](.*?)\[\/url\]/is

and a somewhat different replacement (one that has two variables):

$2

It's this easy, and you can create as many as different bbcodes as you like. Let's have a look at nesting BBCode.

Next: Nesting BBCodes »



8 Responses to “Create your own BBCode, using PHP”

  1. Joshua Gigg Says:

    Thanks for this tutorial, however, wouldn’t it be better for the quote to have $str .= ‘

    ‘; as

    $str .= $close;

  2. Joshua Gigg Says:

    That was meant to be [/blockquote] replace [ with

  3. James Says:

    cool, i have a similar set up on my site however i only check for [code] … [/code]
    How could i get the syntax highlighting as you have on your site? I’ve tried using highlight_string(”$1″) but it’s not having any affect?!?

  4. myself Says:

    I can’t seem to get this to work…on the site I’m creating, I have a form, that sends to a page that puts everything into the database. and then another page that displays the messages. I have tried to put it into both those pages, and it doesn’t work on neither on…I have tried changing $str to $post and still wont work…my site just seems to ignore the function and posts everything as you type it. Any idea’s what I could be doing wrong? Its prolly something small and stupid, but I can’t figure it out
    thanks

  5. tonto Says:

    Good tut. I tried making it into a function but it wouldn’t return the variable.

  6. Mikael Says:

    If user has closed tags in wrong order it breaks web page (if using xhtml strict) like: [b]something[i]very[/b]

  7. Viper007Bond Says:

    Thanks a lot for this! Been meaning to learn regex. :D

  8. reZo Says:

    Hey there,

    Nice tutorial. However, I have a question. It’s been a few months since I’ve worked on my own BBCode class. However, when doing so, I was trying to get GeSHi to work with my BBCode class. The which I did this, was call a separate function from within my BBCode class, which would call the correct GeSHi settings and such.

    However, I found when I called GeSHi, it was messing up the value which it retrieved, and returned it as a literal \\1 or $1. Depending on what I gave it for the preg_replace parameter. I’m trying to make GeSHi work with my BBCode class basicly, so GeSHi doesn’t return \\1 or $1 but returns the parsed GeSHi output instead.

    Hope you understand what I mean, have you got any suggestions for this? I guess I should get down and dirty with GeSHi perhaps?

    As I said, it’s been a couple months since I have done any work on my BBCode class, but from memory I could return the valid output I wanted from a custom function instead of \\1 and such.

Leave a Reply

About the author
Dennis Pallett is the main contributor to PHPit. He owns several websites, including ASPit and Chill2Music. He is currently still studying.
Article Index
  1. Introduction
  2. Nesting BBCodes
Bookmark Article
Download Article
PDF
Download this article as a PDF file