Programming
Article
By Thomas Rutter

Title Case in PHP

By Thomas Rutter
Help us help you! You'll get a... FREE 6-Month Subscription to SitePoint Premium Plus you'll go in the draw to WIN a new Macbook SitePoint 2017 Survey Yes, let's Do this It only takes 5 min

The PHP functions strtoupper and ucwords capitalise all characters in a string, and the first letter of every word in a string, respectively. However, there exists in the standard PHP library no way of achieving Title Case, which involves capitalising all words except for small words (such as conjunctions) when they are not the first word.

The following mini-tutorial will provide a solution similar to the one I came up with for displaying thread titles in the SitePoint Forums’ Highlighted Forum Discussions.

First, we’ll need a list of all the words which we don’t want to capitalise when they are not the first word. The words we should be concerned about are conjunctions (such as and, or), prepositions (in, on) and internal articles (the, a). However, I’m no expert in English grammar so I’ll just call them ‘small words’. Here’s a selection of the ones I use.


$smallwordsarray = array(
'of','a','the','and','an','or','nor','but','is','if','then','else','when',
'at','from','by','on','off','for','in','out','over','to','into','with'
);

The explode function in PHP can be used to split any string into an array of strings, using a character as a split character. So if we split with a space character (‘ ‘), we can use explode to split our string into words.


$words = explode(' ', 'this is a title');

$words becomes an array of strings, each string representing one word from the original $title. Here it would be equal to array(‘This’, ‘is’, ‘a’, ‘title’).

We can now operate on each word separately. We need to test each word to determine if it is one of our ‘small words’. If it is not a small word, or it’s the first word, it should be capitalised. To operate on each member of an array in turn, we can use the PHP language construct foreach. To check if a word is one of our small words, we can use in_array


foreach ($words as $key => $word)
{
if (!$key or !in_array($word, $smallwordsarray))
$words[$key] = ucwords($word);
}

Notice here that I assigned the value to $words[$key] and not to $word. The reason for this is that $word was created by the foreach statement. Modifying $word will not cause any change to the original array $words. So I need to modify the entry in the original array $words that corresponds to the current array key.

By this point, we have an array of all the words in our title. Those words which should be capitalised have been, and all that’s left is to join the words together again into a single string. This can be done with implode, which works in the opposite direction to explode.


$newtitle = implode(' ', $words);

Here’s the entire script as a function you’re welcome to use in your application.


function strtotitle($title)
// Converts $title to Title Case, and returns the result.
{
// Our array of 'small words' which shouldn't be capitalised if
// they aren't the first word. Add your own words to taste.
$smallwordsarray = array(
'of','a','the','and','an','or','nor','but','is','if','then','else','when',
'at','from','by','on','off','for','in','out','over','to','into','with'
);

// Split the string into separate words
$words = explode(' ', $title);

foreach ($words as $key => $word)
{
// If this word is the first, or it's not one of our small words, capitalise it
// with ucwords().
if ($key == 0 or !in_array($word, $smallwordsarray))
$words[$key] = ucwords($word);
}

// Join the words back into a string
$newtitle = implode(' ', $words);

return $newtitle;
}

Notice that if the input already contains capital letters, those letters will remain. This ensures that letters that must always be capital, such as acronyms, will remain so.

Try it out with a title, such as


echo strtotitle("this is a title");

The result? “This is a Title”.

As an aside, a quick search on Google found a solution to the same problem in JavaScript. However, it is a nightmare of code – unnecessarily complex. It checks every letter separately! You’d be better off porting my script to JavaScript.

By the way, here’s a similar solution in ColdFusion.

Login or Create Account to Comment
Login Create Account
Recommended
Sponsors
Get the most important and interesting stories in tech. Straight to your inbox, daily.Is it good?