Tag Archives: C

5 PHP String Functions You Need to Know

Strings in PHP

The Task

First of all what we’d like to achieve? The task is to convert a string, most of the cases single word, by capitalize the first letter. In my case I’ve the world countries names all lower cased, while I need them with first letter capitalized. In example “united states” must become “United States”, but not “United states” or “UNITED STATES”. So here began the journey into PHP string functions, especially those for capitalization!

1. ucwords

The first thing you find in the PHP Manual is the ucwords function. It changes the first letter to a capital letter, but it does not do the job. Why? Well let me show you an example.

$str1 = 'foo bar';
$str2 = 'Foo bar';
$str3 = 'FOO BAR';
$str4 = 'фуу бар';
 
echo ucwords($str1); // Foo Bar
echo ucwords($str2); // Foo Bar
echo ucwords($str3); // FOO BAR
echo ucwords($str4); // фуу бар

Here we have four strings. A lower cased, an upper cased, a mixed cased and … a lower cased Cyrillic string. First of all the main reason why ucwords doesn’t fit here is because of the Cyrillic string. Whatever non-Latin string you have you can forget about capitalization. However the other strings conversions are also interesting. Take a look at the third string! Here the string remains “FOO BAR” instead of going “Foo Bar”, which simply means that this function only looks, and hopefully changes, the first letter.

So here we have two questions. How can we overcome the Cyrillic problem and how to “normalize” the UPPER CASE string?

2. ucfirst

This is another useful function in PHP. ucfirst as you may guess from its name converts a string by only changing its first letter. So “Foo bar” will remain “Foo bar”, while with ucwords it has become “Foo Bar”. Let’s see what this function does:

$str1 = 'foo bar';
$str2 = 'Foo bar';
$str3 = 'FOO BAR';
$str4 = 'фуу бар';
 
echo ucfirst($str1); // Foo bar
echo ucfirst($str2); // Foo bar
echo ucfirst($str3); // FOO BAR
echo ucfirst($str4); // фуу бар

Here even the first string has only one capital letter – “foo bar” became “Foo bar”, and yet again we’ve the Cyrillic string unchanged. It simply doesn’t help us here!

3. mb_convert_case

As a PHP developer you know what the “mb_” prefix means – multibyte. This is quite useful. You can convert the string whatever the encoding is, so perhaps we can overcome the Cyrillic problem. But before proceeding to tests, let’s take a look at the parameters of this function.

The first thing to note here is that mb_convert_case doesn’t contain the case in its name – upper or lower. There’s a second parameter, after the first which is the string itself, who setups that. Note that here you don’t have the typical camel case or capitals parameter name, but MB_CASE_TITLE (as you know in English the title is always capitalized):

echo mb_convert_case($str, MB_CASE_TITLE, ...

And a third one which specifies the encoding:

echo mb_convert_case($str, MB_CASE_TITLE, 'utf-8')

Now let’s see what we can achieve with it:

$str1 = 'foo bar';
$str2 = 'Foo bar';
$str3 = 'FOO BAR';
$str4 = 'фуу бар';
 
echo mb_convert_case($str1, MB_CASE_TITLE, 'utf-8'); // Foo Bar
echo mb_convert_case($str2, MB_CASE_TITLE, 'utf-8'); // Foo Bar
echo mb_convert_case($str3, MB_CASE_TITLE, 'utf-8'); // Foo Bar
echo mb_convert_case($str4, MB_CASE_TITLE, 'utf-8'); // Фуу Бар

As you can see now the Cyrillic problem doesn’t exists and mb_convert_case is intelligent enough to change “FOO BAR” into “Foo Bar” – as I said this is the English style titling. That is by no means the solution when you deal with capitalization with different encoding.

However there is another approach to overcome the all UPPER CASE conversion problem. A possible solution is to convert the string first to a lower case string.

4. strtolower

strtolower is very useful PHP string function and perhaps any PHP developer has used it at least once. But yet again – it does not do the job. Again because of the encoding problem.

echo strtolower('ФУУ БАР'); // #*&$(#*%#

As you can see the Cyrillic string cannot be lower cased! Let’s search again into the “mb_” universe.

5. mb_strtolower

This is the function. Again you’ve to specify the encoding:

echo mb_strtolower('ФУУ БАР', 'utf-8')

Conclusion

It doesn’t matter whether you’re native English speaker or not. Most of the web sites are multilingual and you cannot be sure what happens when you convert strings in Alphabets different from the Latin. Thus be careful even when everything seems to be OK with Latin string tests.

PHP: What is More Powerful Than list()

First of all list() is not an unknown method in the PHP community, where almost every PHP developer knows what it does. The pity is that it has, perhaps, remained useless, although there is hidden power in it!

What is list()?

Let’s assume you’ve two variables and one array with two elements:

$arr = array(1, 2);
$a = $arr[0];
$b = $arr[1];
// now a == 1, and b == 2

Maybe the easiest way to assign to the first variable the value of the first element of the array, and to the second variable the value of the second element of the array is to use list():

list($a, $b) = array(1, 2);
// again a == 1, and b == 2

Note that you can do the same with as many variables/array elements you want.

The funny thing is that nobody use it, while I see at least one perfect usage. You can think of a typical admin panel of any web system. For sure any developer has programmed the typical table page containing a list of “things” and a paging to switch the result set page. It’s like the posts page from the WordPress admin panel, or a search result page in Google, where you’ve one page of results and at the bottom – a number of pages where you can go to another page of the search results.

What I’ve seen in almost every project is that typically the developers prefer to set the results for the page into one list returned from one method and the count of the entire result set is returned by another method.

Thus most of the times there are two methods, performing most commonly a database queries. Something like – getList($offset, $limit) and getCount() where the first one returns the page and the second one returns the count of the result set.

This will result into two methods, two calls and two lines of code:

function getList($offset, $limit)
{
	...
	// although the entire result set contains
	// 5 elements by limiting it from the parameters
	// only three are returned
	return $list; // where $list = array('title1', 'title2', 'title3');	
}
 
function getCount()
{
	...
	// here's returned the count
	// of the entire result set
	return $count; // where $count = 5;	
}
 
$list  = getList(0, 3);
$count = getCount();

What actually you can do is to perform both queries in one method, perhaps called getItems($offset, $limit) where the returned value is an array containing both the list of results and the count:

function getItems($offset, $limit)
{
	...
	return array('list' => $list, 'count' => $count);
}

And finally when calling this method to list() that into the two variables – single lined.

list($list, $count) = getItems(0, 3);

JSON and Zend Framework? – Zend_Json

That’s really a good Zend Framework’s class that help you do the encode/decode job very easily. First of all it escapes everything for you and second it prints a correct/valid code. Note that sometimes if you have a trailing whitespace after the closing PHP tag – ?> that will result in an error.

Here’s some code:

public function jsonAction()
{
	$data = array(3,4,'test', 'my-name' => 3,4);
 
	echo Zend_Json::encode($data);
 
	$this->_helper->viewRenderer->setNoRender(true);
	$this->view->layout()->disableLayout();
}

and the result is:

{"0":3,"1":4,"2":"test","my-name":3,"3":4}

Note that all integers are printed without double quotes – which saves some space!

PHP: Conditionals Coding Style

Just to continue with PHP coding style, let me suggest a conditional statement coding standard. Just don’t use large three operands conditions like that:

condition ? if_true : if_false

If it’s too long it will be difficult to read and maintain. Better is:

(condition)
	? (if_true)
	: (if_false);