# 9 Useful PHP Functions and Features You Need to Know

Twice a month, we revisit some of our readers’ favorite posts from throughout the history of Nettuts+.

Even after using PHP for years, we stumble upon functions and features that we did not know about. Some of these can be quite useful, yet underused. With that in mind, I've compiled a list of nine incredibly useful PHP functions and features that you should be familiar with.

## 1. Functions with Arbitrary Number of Arguments

You may already know that PHP allows you to define functions with optional arguments. But there is also a method for allowing completely arbitrary number of function arguments.

First, here is an example with just optional arguments:

 1 2 // function with 2 optional arguments  3 function foo($arg1 = '',$arg2 = '') {  4 5  echo "arg1: $arg1\n";  6  echo "arg2:$arg2\n";  7 8 }  9 10 11 foo('hello','world');  12 /* prints:  13 arg1: hello  14 arg2: world  15 */  16 17 foo();  18 /* prints:  19 arg1:  20 arg2:  21 */ 

Now, let's see how we can build a function that accepts any number of arguments. This time we are going to utilize func_get_args():

 1 2 // yes, the argument list can be empty  3 function foo() {  4 5  // returns an array of all passed arguments  6  $args = func_get_args();  7 8  foreach ($args as $k =>$v) {  9  echo "arg".($k+1).":$v\n";  10  }  11 12 }  13 14 foo();  15 /* prints nothing */  16 17 foo('hello');  18 /* prints  19 arg1: hello  20 */  21 22 foo('hello', 'world', 'again');  23 /* prints  24 arg1: hello  25 arg2: world  26 arg3: again  27 */ 

## 2. Using Glob() to Find Files

Many PHP functions have long and descriptive names. However it may be hard to tell what a function named glob() does unless you are already familiar with that term from elsewhere.

Think of it like a more capable version of the scandir() function. It can let you search for files by using patterns.

 1 2 // get all php files  3 $files = glob('*.php');  4 5 print_r($files);  6 /* output looks like:  7 Array  8 (  9  [0] => phptest.php  10  [1] => pi.php  11  [2] => post_output.php  12  [3] => test.php  13 )  14 */ 

You can fetch multiple file types like this:

 1 2 // get all php files AND txt files  3 $files = glob('*.{php,txt}', GLOB_BRACE);  4 5 print_r($files);  6 /* output looks like:  7 Array  8 (  9  [0] => phptest.php  10  [1] => pi.php  11  [2] => post_output.php  12  [3] => test.php  13  [4] => log.txt  14  [5] => test.txt  15 )  16 */ 

Note that the files can actually be returned with a path, depending on your query:

 1 2 $files = glob('../images/a*.jpg');  3 4 print_r($files);  5 /* output looks like:  6 Array  7 (  8  [0] => ../images/apple.jpg  9  [1] => ../images/art.jpg  10 )  11 */ 

If you want to get the full path to each file, you can just call the realpath() function on the returned values:

 1 2 $files = glob('../images/a*.jpg');  3 4 // applies the function to each array element  5 $files = array_map('realpath',$files);  6 7 print_r($files);  8 /* output looks like:  9 Array  10 (  11  [0] => C:\wamp\www\images\apple.jpg  12  [1] => C:\wamp\www\images\art.jpg  13 )  14 */ 

## 3. Memory Usage Information

By observing the memory usage of your scripts, you may be able optimize your code better.

PHP has a garbage collector and a pretty complex memory manager. The amount of memory being used by your script. can go up and down during the execution of a script. To get the current memory usage, we can use the memory_get_usage() function, and to get the highest amount of memory used at any point, we can use the memory_get_peak_usage() function.

 1 2 echo "Initial: ".memory_get_usage()." bytes \n";  3 /* prints  4 Initial: 361400 bytes  5 */  6 7 // let's use up some memory  8 for ($i = 0;$i < 100000; $i++) {  9 $array []= md5($i);  10 }  11 12 // let's remove half of the array  13 for ($i = 0; $i < 100000;$i++) {  14  unset($array[$i]);  15 }  16 17 echo "Final: ".memory_get_usage()." bytes \n";  18 /* prints  19 Final: 885912 bytes  20 */  21 22 echo "Peak: ".memory_get_peak_usage()." bytes \n";  23 /* prints  24 Peak: 13687072 bytes  25 */ 

## 4. CPU Usage Information

For this, we are going to utilize the getrusage() function. Keep in mind that this is not available on Windows platforms.

 1 2 print_r(getrusage());  3 /* prints  4 Array  5 (  6  [ru_oublock] => 0  7  [ru_inblock] => 0  8  [ru_msgsnd] => 2  9  [ru_msgrcv] => 3  10  [ru_maxrss] => 12692  11  [ru_ixrss] => 764  12  [ru_idrss] => 3864  13  [ru_minflt] => 94  14  [ru_majflt] => 0  15  [ru_nsignals] => 1  16  [ru_nvcsw] => 67  17  [ru_nivcsw] => 4  18  [ru_nswap] => 0  19  [ru_utime.tv_usec] => 0  20  [ru_utime.tv_sec] => 0  21  [ru_stime.tv_usec] => 6269  22  [ru_stime.tv_sec] => 0  23 )  24   25 */ 

That may look a bit cryptic unless you already have a system administration background. Here is the explanation of each value (you don't need to memorize these):

• ru_oublock: block output operations
• ru_inblock: block input operations
• ru_msgsnd: messages sent
• ru_maxrss: maximum resident set size
• ru_ixrss: integral shared memory size
• ru_idrss: integral unshared data size
• ru_minflt: page reclaims
• ru_majflt: page faults
• ru_nvcsw: voluntary context switches
• ru_nivcsw: involuntary context switches
• ru_nswap: swaps
• ru_utime.tv_usec: user time used (microseconds)
• ru_utime.tv_sec: user time used (seconds)
• ru_stime.tv_usec: system time used (microseconds)
• ru_stime.tv_sec: system time used (seconds)

To see how much CPU power the script has consumed, we need to look at the 'user time' and 'system time' values. The seconds and microseconds portions are provided separately by default. You can divide the microseconds value by 1 million, and add it to the seconds value, to get the total seconds as a decimal number.

Let's see an example:

 1 2 // sleep for 3 seconds (non-busy)  3 sleep(3);  4 5 $data = getrusage();  6 echo "User time: ".  7  ($data['ru_utime.tv_sec'] +  8  $data['ru_utime.tv_usec'] / 1000000);  9 echo "System time: ".  10  ($data['ru_stime.tv_sec'] +  11  $data['ru_stime.tv_usec'] / 1000000);  12 13 /* prints  14 User time: 0.011552  15 System time: 0  16 */  Even though the script took about 3 seconds to run, the CPU usage was very very low. Because during the sleep operation, the script actually does not consume CPU resources. There are many other tasks that may take real time, but may not use CPU time, like waiting for disk operations. So as you see, the CPU usage and the actual length of the runtime are not always the same. Here is another example:  1 2 // loop 10 million times (busy)  3 for($i=0;$i<10000000;$i++) {  4 5 }  6 7 $data = getrusage();  8 echo "User time: ".  9  ($data['ru_utime.tv_sec'] +  10  $data['ru_utime.tv_usec'] / 1000000);  11 echo "System time: ".  12  ($data['ru_stime.tv_sec'] +  13  $data['ru_stime.tv_usec'] / 1000000);  14 15 /* prints  16 User time: 1.424592  17 System time: 0.004204  18 */  That took about 1.4 seconds of CPU time, almost all of which was user time, since there were no system calls. System Time is the amount of time the CPU spends performing system calls for the kernel on the program's behalf. Here is an example of that:  1 2 $start = microtime(true);  3 // keep calling microtime for about 3 seconds  4 while(microtime(true) - $start < 3) {  5 6 }  7 8 $data = getrusage();  9 echo "User time: ".  10  ($data['ru_utime.tv_sec'] +  11 $data['ru_utime.tv_usec'] / 1000000);  12 echo "System time: ".  13  ($data['ru_stime.tv_sec'] +  14 $data['ru_stime.tv_usec'] / 1000000);  15 16 /* prints  17 User time: 1.088171  18 System time: 1.675315  19 */ 

Now we have quite a bit of system time usage. This is because the script calls the microtime() function many times, which performs a request through the operating system to fetch the time.

Also you may notice the numbers do not quite add up to 3 seconds. This is because there were probably other processes on the server as well, and the script was not using 100% CPU for the whole duration of the 3 seconds.

## 5. Magic Constants

PHP provides useful magic constants for fetching the current line number (__LINE__), file path (__FILE__), directory path (__DIR__), function name (__FUNCTION__), class name (__CLASS__), method name (__METHOD__) and namespace (__NAMESPACE__).

We are not going to cover each one of these in this article, but I will show you a few use cases.

When including other scripts, it is a good idea to utilize the __FILE__ constant (or also __DIR__ , as of PHP 5.3):

 1 2 // this is relative to the loaded script's path  3 // it may cause problems when running scripts from different directories  4 require_once('config/database.php');  5 6 // this is always relative to this file's path  7 // no matter where it was included from  8 require_once(dirname(__FILE__) . '/config/database.php'); 

Using __LINE__ makes debugging easier. You can track down the line numbers:

 1 2 // some code  3 // ...  4 my_debug("some debug message", __LINE__);  5 /* prints  6 Line 4: some debug message  7 */  8 9 // some more code  10 // ...  11 my_debug("another debug message", __LINE__);  12 /* prints  13 Line 11: another debug message  14 */  15 16 function my_debug($msg,$line) {  17  echo "Line $line:$msg\n";  18 } 

## 6. Generating Unique ID's

There may be situations where you need to generate a unique string. I have seen many people use the md5() function for this, even though it's not exactly meant for this purpose:

 1 2 // generate unique string  3 echo md5(time() . mt_rand(1,1000000)); 

There is actually a PHP function named uniqid() that is meant to be used for this.

 1 2 // generate unique string  3 echo uniqid();  4 /* prints  5 4bd67c947233e  6 */  7 8 // generate another unique string  9 echo uniqid();  10 /* prints  11 4bd67c9472340  12 */ 

You may notice that even though the strings are unique, they seem similar for the first several characters. This is because the generated string is related to the server time. This actually has a nice side effect, as every new generated id comes later in alphabetical order, so they can be sorted.

To reduce the chances of getting a duplicate, you can pass a prefix, or the second parameter to increase entropy:

 1 2 // with prefix  3 echo uniqid('foo_');  4 /* prints  5 foo_4bd67d6cd8b8f  6 */  7 8 // with more entropy  9 echo uniqid('',true);  10 /* prints  11 4bd67d6cd8b926.12135106  12 */  13 14 // both  15 echo uniqid('bar_',true);  16 /* prints  17 bar_4bd67da367b650.43684647  18 */ 

This function will generate shorter strings than md5(), which will also save you some space.

## 7. Serialization

Have you ever needed to store a complex variable in a database or a text file? You do not have to come up with a fancy solution to convert your arrays or objects into formatted strings, as PHP already has functions for this purpose.

There are two popular methods of serializing variables. Here is an example that uses the serialize() and unserialize():

 1 2 // a complex array  3 $myvar = array(  4  'hello',  5  42,  6  array(1,'two'),  7  'apple'  8 );  9 10 // convert to a string  11 $string = serialize($myvar);  12 13 echo$string;  14 /* prints  15 a:4:{i:0;s:5:"hello";i:1;i:42;i:2;a:2:{i:0;i:1;i:1;s:3:"two";}i:3;s:5:"apple";}  16 */  17 18 // you can reproduce the original variable  19 $newvar = unserialize($string);  20 21 print_r($newvar);  22 /* prints  23 Array  24 (  25  [0] => hello  26  [1] => 42  27  [2] => Array  28  (  29  [0] => 1  30  [1] => two  31  )  32   33  [3] => apple  34 )  35 */  This was the native PHP serialization method. However, since JSON has become so popular in recent years, they decided to add support for it in PHP 5.2. Now you can use the json_encode() and json_decode() functions as well:  1 2 // a complex array  3 $myvar = array(  4  'hello',  5  42,  6  array(1,'two'),  7  'apple'  8 );  9 10 // convert to a string  11 $string = json_encode($myvar);  12 13 echo $string;  14 /* prints  15 ["hello",42,[1,"two"],"apple"]  16 */  17 18 // you can reproduce the original variable  19 $newvar = json_decode($string);  20 21 print_r($newvar);  22 /* prints  23 Array  24 (  25  [0] => hello  26  [1] => 42  27  [2] => Array  28  (  29  [0] => 1  30  [1] => two  31  )  32   33  [3] => apple  34 )  35 */ 

It is more compact, and best of all, compatible with javascript and many other languages. However, for complex objects, some information may be lost.

## 8. Compressing Strings

When talking about compression, we usually think about files, such as ZIP archives. It is possible to compress long strings in PHP, without involving any archive files.

In the following example we are going to utilize the gzcompress() and gzuncompress() functions:

## Conclusion

Are you aware of any other PHP features that are not widely known but can be quite useful? Please share with us in the comments. And thank you for reading!