Alaa M.
Alaa M.

Reputation: 5273

How to allow special tags in php?

I have a textarea for commenting. I need to allow tags such as ' and \ as well as html tags (e.g <b> , <i> , <br>).

I tried htmlspecialchars($comment,ENT_QUOTES); , but this way ' and \ are allowed but html tags aren't. That is the input assassin's <b>creed becomes exactly assassin's <b>creed. But i need it to become assassin's creed.

Whereas if i don't use htmlspecialchars($comment,ENT_QUOTES); , assassin's <b>creed makes trouble... because of the ' . But assassins <b>creed becomes assassin's creed as it should.

How could i solve this problem?

I hope it's clear enough

Thanks

edit:

This is how it should be:

input: assassin's <b>creed

output: assassin's creed

by using htmlspecialchars:

input: assassin's <b>creed

output: assassin's <b>creed

without using any functions:

input: assassin's <b>creed

can't insert to database

without using any functions:

input: assassins <b>creed

output: assassins creed

Upvotes: 1

Views: 130

Answers (3)

Andrew Mackrodt
Andrew Mackrodt

Reputation: 1826

Your best option is to use a library such as htmlpurifier (mentioned in optional's answer). If this isn't an option, a function like the following will allow you to preserve html tags:

function htmlspecialchars_whitelist(
        array $whitelist,
        $string,
        $flags = ENT_COMPAT,
        $encoding = 'UTF-8',
        $double_encode = true) {

    $regex = implode('|', $whitelist);
    preg_match_all("#<(?:(?:$regex) ?/?|/(?:$regex))>#", $string, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE);

    $pos = 0;
    $buffer = '';

    foreach ($matches as $match) {
        $off = $match[0][3];
        $substr = substr($string, $pos, $off - $pos);
        $substr = htmlspecialchars($substr, $flags, $encoding, $double_encode);
        $buffer .= $substr;
        $buffer .= $match[0][0];
        $pos = $off + strlen($match[0][0]);
    }

    $buffer .= htmlspecialchars(substr($string, $pos), $flags, $encoding, $double_encode);

    return $buffer;
}

Example:

$whitelist = array('b', 'strong', 'i', 'em', 'strike', 'br');
$html = "<p>The <strike>quick</strike> \"brown\" <strong>fox</strong> jumped <hr /> 'over' the <em>lazy dog</em>.</p>";
echo htmlspecialchars_whitelist($whitelist, $html, ENT_QUOTES);
// &lt;p&gt;The <strike>quick</strike> &quot;brown&quot; <strong>fox</strong> jumped &lt;hr /&gt; &#039;over&#039; the <em>lazy dog</em>.&lt;/p&gt;

http://phpfiddle.org/main/code/yru-fb1

Note: you must still guard against SQL injection. Phil Cross' answer tackles this.

Upvotes: 0

Phil Cross
Phil Cross

Reputation: 9302

Your problem is you're using htmlspecialchars() to escape database data.

This shouldn't be used to escape data destined for a database. It would seem that you are inadvertantly SQL injecting yourself.

As I don't know how your connecting to your database, I'll post a couple of ways to escape your data properly:

mysql Although you shouldn't be using this functionality, as its deprecated and not supported, I'll post how to escape properly:

$data = "Assassin's <b>creed</b>";

$data = mysql_real_escape_string($data);
$result = mysql_query("INSERT INTO .... ");

PDO

$conn = new PDO("{$connection_string}");

$data = "Assassin's <b>Creed</b>";
$conn->prepare("INSERT INTO tbl_games (title) VALUES (?)");
$conn->execute(array($data));

CodeIgniter

$this->db->insert('tbl_games', array('title' => "Assassin's <b>Creed</b>"));

I'm not sure of mysqli functionality (or others). In any case, you shouldn't need to use htmlspecialchars() to escape your data.

Either use the database's built in functionality for escaping the data, or research prepared statements.

Upvotes: 1

optional
optional

Reputation: 92

if you want to allow html tags etc you can not sanitize data with htmlspecialchars or similar php functions. You have to use libraries for this purpose (sanitizing data while allowing tags inoffensively) I recommend htmlpurifier

Or you may use WYSIWYG web editors like http://www.tinymce.com/ or http://ckeditor.com/

Upvotes: 0

Related Questions