0

I've created a function that cleans a posted title.

function title_var($title_variable) {
   $title_variable = mysql_real_escape_string(ucwords(strtolower(trim(htmlspecialchars($title_variable, ENT_QUOTES)))));
   return stripslashes($title_variable);
}

I now need to be able to make anything between () or [] all uppercase. For instance "my business name (cbs) limited" or "my business name [cbs] limited", becomes "My Business Name (CBS) Limited", with "CBS" being in all capitals.

I've done the first part of making all the words capital, I just need a way of making anything between the brackets capital.

esqew
  • 42,425
  • 27
  • 92
  • 132
WOWDesign
  • 56
  • 9
  • 2
    [**Please, don't use `mysql_*` functions in new code**](http://bit.ly/phpmsql). They are no longer maintained [and are officially deprecated](http://j.mp/XqV7Lp). See the [**red box**](http://j.mp/Te9zIL)? Learn about [*prepared statements*](http://j.mp/T9hLWi) instead, and use [PDO](http://php.net/pdo) or [MySQLi](http://php.net/mysqli) - [this article](http://j.mp/QEx8IB) will help you decide which. If you choose PDO, [here is a good tutorial](http://j.mp/PoWehJ). – esqew Jul 01 '14 at 15:55
  • Thanks @esqew. I will shortly be trying to switch over to MySQLi, but having some 40-45 websites to change, plus my own CMS they use - and as a one man band- it's a lot of work! Is there an easy way you know of making the switch over? Things like finding and chaning all instances of "mysql_query()" to the new MySQLi version? – WOWDesign Jul 01 '14 at 16:01
  • See [this SO question](http://stackoverflow.com/questions/1390607/how-could-i-change-this-mysql-to-mysqli). – esqew Jul 01 '14 at 16:02

1 Answers1

5

Always use context-based escaping

Do not try to build a single function to handle all the possible cases. Just don't. It's pointless. In your function, you're trying to "clean" the string by removing certain characters. You can't clean a string by removing a set of characters. That idea is flawed because you're always going to have to allow the use of some characters that are special in some syntax or the other.

Instead, treat the string according to the context where it's going to be used. For example:


Solving the problem at hand

Use preg_replace_callback() to accomplish this. You can use the following regex to match the text inside the brackets (including the brackets):

[\(\[].*?[\)\]] 

Explanation:

  • [\(\[] - Matches the opening bracket
  • .*? - Matches the text in between
  • [\)\]] - Matches the closing bracket

$m[0] will contain the entire matched string. You can just transform it into upper-case with strtoupper().

Modifying your function, it becomes just:

function get_title($title) {
    $title = ucwords(strtolower(trim($title, ENT_QUOTES)));
    return preg_replace_callback('/[\(\[].*?[\)\]]/', function ($m) {
        return strtoupper($m[0]);
    }, $title);
}

Demo

Community
  • 1
  • 1
Amal Murali
  • 75,622
  • 18
  • 128
  • 150
  • Hi @Amal. Sorry, but if you read my post again, I want to keep the brackets (which ever type) around the word, as in "My Business Name (CBS) Limited" or "My Business Name [CBS] Limited". Cheers G – WOWDesign Jul 01 '14 at 16:12
  • Thanks @Amal, this is perfect! So in your opinion using ENT_QUOTES and mysql_real_escape_string together is over kill? The forms are public and I was trying to prevent mysql injection. Just using ENT_QUOTES is enough then? G – WOWDesign Jul 01 '14 at 16:21
  • @WOWDesign: No, absolutely not. This function does not take care of any of the escaping; you'll need to escape it based on the context. For example, if you're going to insert the title into database, escape it *just* before that (preferably using [prepared statements](http://www.php.net/manual/en/mysqli.quickstart.prepared-statements.php)). I've updated the answer to include some generic advice. Hope that helps! – Amal Murali Jul 01 '14 at 16:33