9 Useful PHP Functions and Features You Need to Know

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:

// function with 2 optional arguments
function foo($arg1 = '', $arg2 = '') {

	echo "arg1: $arg1\n";
	echo "arg2: $arg2\n";

}
foo('hello','world');
/* prints:
arg1: hello
arg2: world
*/

foo();
/* prints:
arg1:
arg2:
*/

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():

// yes, the argument list can be empty
function foo() {

	// returns an array of all passed arguments
	$args = func_get_args();

	foreach ($args as $k => $v) {
		echo "arg".($k+1).": $v\n";
	}

}

foo();
/* prints nothing */

foo('hello');
/* prints
arg1: hello
*/

foo('hello', 'world', 'again');
/* prints
arg1: hello
arg2: world
arg3: again
*/

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.

// get all php files
$files = glob('*.php');

print_r($files);
/* output looks like:
Array
(
    [0] => phptest.php
    [1] => pi.php
    [2] => post_output.php
    [3] => test.php
)
*/

You can fetch multiple file types like this:

// get all php files AND txt files
$files = glob('*.{php,txt}', GLOB_BRACE);

print_r($files);
/* output looks like:
Array
(
    [0] => phptest.php
    [1] => pi.php
    [2] => post_output.php
    [3] => test.php
    [4] => log.txt
    [5] => test.txt
)
*/

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

$files = glob('../images/a*.jpg');

print_r($files);
/* output looks like:
Array
(
    [0] => ../images/apple.jpg
    [1] => ../images/art.jpg
)
*/

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

$files = glob('../images/a*.jpg');

// applies the function to each array element
$files = array_map('realpath',$files);

print_r($files);
/* output looks like:
Array
(
    [0] => C:\wamp\www\images\apple.jpg
    [1] => C:\wamp\www\images\art.jpg
)
*/

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.

echo "Initial: ".memory_get_usage()." bytes \n";
/* prints
Initial: 361400 bytes
*/

// let's use up some memory
for ($i = 0; $i < 100000; $i++) {
	$array []= md5($i);
}

// let's remove half of the array
for ($i = 0; $i < 100000; $i++) {
	unset($array[$i]);
}

echo "Final: ".memory_get_usage()." bytes \n";
/* prints
Final: 885912 bytes
*/

echo "Peak: ".memory_get_peak_usage()." bytes \n";
/* prints
Peak: 13687072 bytes
*/

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.

print_r(getrusage());
/* prints
Array
(
    [ru_oublock] => 0
    [ru_inblock] => 0
    [ru_msgsnd] => 2
    [ru_msgrcv] => 3
    [ru_maxrss] => 12692
    [ru_ixrss] => 764
    [ru_idrss] => 3864
    [ru_minflt] => 94
    [ru_majflt] => 0
    [ru_nsignals] => 1
    [ru_nvcsw] => 67
    [ru_nivcsw] => 4
    [ru_nswap] => 0
    [ru_utime.tv_usec] => 0
    [ru_utime.tv_sec] => 0
    [ru_stime.tv_usec] => 6269
    [ru_stime.tv_sec] => 0
)

*/

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_msgrcv: messages received
  • 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_nsignals: signals received
  • 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:

// sleep for 3 seconds (non-busy)
sleep(3);

$data = getrusage();
echo "User time: ".
	($data['ru_utime.tv_sec'] +
	$data['ru_utime.tv_usec'] / 1000000);
echo "System time: ".
	($data['ru_stime.tv_sec'] +
	$data['ru_stime.tv_usec'] / 1000000);

/* prints
User time: 0.011552
System time: 0
*/

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:

// loop 10 million times (busy)
for($i=0;$i<10000000;$i++) {

}

$data = getrusage();
echo "User time: ".
	($data['ru_utime.tv_sec'] +
	$data['ru_utime.tv_usec'] / 1000000);
echo "System time: ".
	($data['ru_stime.tv_sec'] +
	$data['ru_stime.tv_usec'] / 1000000);

/* prints
User time: 1.424592
System time: 0.004204
*/

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:

$start = microtime(true);
// keep calling microtime for about 3 seconds
while(microtime(true) - $start < 3) {

}

$data = getrusage();
echo "User time: ".
	($data['ru_utime.tv_sec'] +
	$data['ru_utime.tv_usec'] / 1000000);
echo "System time: ".
	($data['ru_stime.tv_sec'] +
	$data['ru_stime.tv_usec'] / 1000000);

/* prints
User time: 1.088171
System time: 1.675315
*/

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):

// this is relative to the loaded script's path
// it may cause problems when running scripts from different directories
require_once('config/database.php');

// this is always relative to this file's path
// no matter where it was included from
require_once(dirname(__FILE__) . '/config/database.php');

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

// some code
// ...
my_debug("some debug message", __LINE__);
/* prints
Line 4: some debug message
*/

// some more code
// ...
my_debug("another debug message", __LINE__);
/* prints
Line 11: another debug message
*/

function my_debug($msg, $line) {
	echo "Line $line: $msg\n";
}

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:

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

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

// generate unique string
echo uniqid();
/* prints
4bd67c947233e
*/

// generate another unique string
echo uniqid();
/* prints
4bd67c9472340
*/

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:

// with prefix
echo uniqid('foo_');
/* prints
foo_4bd67d6cd8b8f
*/

// with more entropy
echo uniqid('',true);
/* prints
4bd67d6cd8b926.12135106
*/

// both
echo uniqid('bar_',true);
/* prints
bar_4bd67da367b650.43684647
*/

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():

// a complex array
$myvar = array(
	'hello',
	42,
	array(1,'two'),
	'apple'
);

// convert to a string
$string = serialize($myvar);

echo $string;
/* prints
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";}
*/

// you can reproduce the original variable
$newvar = unserialize($string);

print_r($newvar);
/* prints
Array
(
    [0] => hello
    [1] => 42
    [2] => Array
        (
            [0] => 1
            [1] => two
        )

    [3] => apple
)
*/

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:

// a complex array
$myvar = array(
	'hello',
	42,
	array(1,'two'),
	'apple'
);

// convert to a string
$string = json_encode($myvar);

echo $string;
/* prints
["hello",42,[1,"two"],"apple"]
*/

// you can reproduce the original variable
$newvar = json_decode($string);

print_r($newvar);
/* prints
Array
(
    [0] => hello
    [1] => 42
    [2] => Array
        (
            [0] => 1
            [1] => two
        )

    [3] => apple
)
*/

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:

$string =
"Lorem ipsum dolor sit amet, consectetur
adipiscing elit. Nunc ut elit id mi ultricies
adipiscing. Nulla facilisi. Praesent pulvinar,
sapien vel feugiat vestibulum, nulla dui pretium orci,
non ultricies elit lacus quis ante. Lorem ipsum dolor
sit amet, consectetur adipiscing elit. Aliquam
pretium ullamcorper urna quis iaculis. Etiam ac massa
sed turpis tempor luctus. Curabitur sed nibh eu elit
mollis congue. Praesent ipsum diam, consectetur vitae
ornare a, aliquam a nunc. In id magna pellentesque
tellus posuere adipiscing. Sed non mi metus, at lacinia
augue. Sed magna nisi, ornare in mollis in, mollis
sed nunc. Etiam at justo in leo congue mollis.
Nullam in neque eget metus hendrerit scelerisque
eu non enim. Ut malesuada lacus eu nulla bibendum
id euismod urna sodales. ";

$compressed = gzcompress($string);

echo "Original size: ". strlen($string)."\n";
/* prints
Original size: 800
*/
echo "Compressed size: ". strlen($compressed)."\n";
/* prints
Compressed size: 418
*/

// getting it back
$original = gzuncompress($compressed);

We were able to achive almost 50% size reduction. Also the functions gzencode() and gzdecode() achive similar results, by using a different compression algorithm.


9. Register Shutdown Function

There is a function called register_shutdown_function(), which will let you execute some code right before the script finishes running.

Imagine that you want to capture some benchmark statistics at the end of your script execution, such as how long it took to run:

// capture the start time
$start_time = microtime(true);

// do some stuff
// ...

// display how long the script took
echo "execution took: ".
		(microtime(true) - $start_time).
		" seconds.";

At first this may seem trivial. You just add the code to the very bottom of the script and it runs before it finishes. However, if you ever call the exit() function, that code will never run. Also, if there is a fatal error, or if the script is terminated by the user (by pressing the Stop button in the browser), again it may not run.

When you use register_shutdown_function(), your code will execute no matter why the script has stopped running:

$start_time = microtime(true);

register_shutdown_function('my_shutdown');

// do some stuff
// ...
function my_shutdown() {
	global $start_time;

	echo "execution took: ".
			(microtime(true) - $start_time).
			" seconds.";
}

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!

Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more
  • http://www.nickbloor.co.uk/ Nick Bloor

    I’ve seen require_once(dirname(__FILE__) . ‘/somefile.php’) in a few PHP applications before but I never realised why, thanks!

    In response to section 7 on serialization – be careful when serializing data for storage in a database! I spent a day debugging a website when some serialized data grew too large which resulted in the data being truncated to fit into a database field: http://www.nickbloor.co.uk/2011/03/serializing-data-and-databases/

  • http://www.cliqet.com Julius

    Nice Tutorial! I’ve only tried functions with arbitrary number of arguments and the memory usage function but the other haven’t tried them yet in my coding experience. Thanks guys!

  • http://theeasyapi.com Chad R. Smith

    My service started to get in the 1 Million a month of requests, putting a strain on the code and the server itself. It really started to make me have to look at what I was using for my API. It was initially built with CakePHP and was good for a while but when you start working with thousands of requests a day and all hitting 5-10 a second then it puts a strain on things.

    What I did is completely abandon CakePHP in favor of a light weight solution. Something pure class based that I wrote from the ground up. Spending a month to write a really nice fast API I found that there were still memory gaps and remainders. Going on point #3 I used those functions to determine that if you call a class within a class that you have to explicitly destroy the class that you referenced. Since it will not unload itself properly. Using the techniques in #3 I found the memory holes and got them patched.

    Now my system The Easy API – http://theeasyapi.com – is running over a million requests a month and have heavy hitters like Radian6 and others who are using us entirely for their data. I also completely got rid of Apache -> Nginx -> Lighttpd -> Cherokee. Finally I stopped with Cherokee because it’s a great little server that really kicks with dynamic applications. Nginx and Lighty is great for more “static” content but the dynamic stuff it chokes and throws 500′s. Cherokee is great, go check them out.

  • http://phpsymfony.com Guillaume BRETOU

    Thanks for this article.
    Of course there are many other useful functions that you need to know. It all depends on what you want to do.
    I believe that the best thing is to have php.net as bookmark ;)

    • http://irie-design.fr yorote

      Same here, totally agree with you.

    • http://www.ryandennler.com Ryan Dennler

      Absolutely agreed

  • http://www.axia.co.uk Yatrik

    Nice article. I was using the optional arguments in functions a lot and had to modify the function and its use in programm when I had any update in function or argument. Thanks for sharing this.

  • http://www.movieviews.be Dennis

    Thanks for the article !
    I didn’t knew you could compress your strings and decompress them.

    It made my day :D

    Grtz,

    D.

  • Taqi Ahmed Taha

    The following functions are also very useful.

    // The range function
    // Print alphabets from A to Z
    foreach (range(‘A’, ‘Z’) as $letter) {
    echo $letter;
    }

    // file_get_contents function
    $homepage = file_get_contents(‘http://www.example.com/’);
    echo $homepage;

    // OR

    $file = file_get_contents(‘./people.txt’, FILE_USE_INCLUDE_PATH);

    // Read 14 characters starting from the 21st character
    $section = file_get_contents(‘./people.txt’, NULL, NULL, 20, 14);
    var_dump($section);

    // OR

    // Create a stream
    $opts = array(
    ‘http’=>array(
    ‘method’=>”GET”,
    ‘header’=>”Accept-language: en\r\n” .
    “Cookie: foo=bar\r\n”
    )
    );

    $context = stream_context_create($opts);

    // Open the file using the HTTP headers set above
    $file = file_get_contents(‘http://www.example.com/’, false, $context);

    // file_put_contents function
    $file = ‘people.txt’;
    // Open the file to get existing content
    $current = file_get_contents($file);
    // Append a new person to the file
    $current .= “John Smith\n”;
    // Write the contents back to the file
    file_put_contents($file, $current);

    // OR

    $file = ‘people.txt’;
    // The new person to add to the file
    $person = “John Smith\n”;
    // Write the contents to the file,
    // using the FILE_APPEND flag to append the content to the end of the file
    // and the LOCK_EX flag to prevent anyone else writing to the file at the same time
    file_put_contents($file, $person, FILE_APPEND | LOCK_EX);

    // Using closures or referred to as Anonymous functions in the PHP manual
    $greet = function($name)
    {
    printf(“Hello %s\r\n”, $name);
    };

    $greet(‘World’);
    $greet(‘PHP’);

    • Mop

      “Using closures or referred to as Anonymous functions….”

      I get the following error: “Parse error: syntax error, unexpected T_FUNCTION on line 2″

      See http://codepad.org/sIwUMMxI

      • Mop

        Ok I’ve found the issue, codepad interpretter isn’t PHP 5.3!

  • http://snowsoft.co.nz Andrew Snowball

    Brilliant. I’ve been looking for a way to get the name of embedded script modules for ages. Never came across these before.

    Thanks man.
    ~AS.

  • http://www.thomas-bousquet.com Thomas

    Thanks for this nice tutorial :)

  • Ronny

    I read through all of the comments, and nobody has mentioned parse_url() which lets you parse an URL and return all of the URLs components. Scheme (e.g. http, https), host, port, username, password, path, query (after the question mark ?) and fragment (after the hashmark #).

    Could be very useful if you need to read the URL.

  • Umut

    Perfect thanks

  • http://phpnewsletter.org newsletter software

    Deep research in PHP. Thank you for your sharing! It is useful for php beginner.
    It is great!

  • http:// 

    great blog post, i clearly adore this web site, keep on it.

  • http://reygcalantaol.com Rey

    Is there a way that the function in php will return a multi value?

  • http://www.armeki.com Armeki

    thanks. excellent article for php

  • Chris

    What is the benefit of #8? Storing large strings in a Database? That would hurt search capabilities no?

    • Wil

      Only if you choose to use it to store searchable data. If the shoe doesn’t fit, don’t wear it. One great application for serialization is continuations. For example you have a script which must process vast iterations of something which requires both large amounts of CPU and idle time, and you want to return to the caller immediately. Instead of sending your 1,000,000 emails out synchronously and having the client time out and never know whether it was successful, you can instead write the entire state of your program out to the database and have a cron job reload that state and send the emails in the background, even in several parallel processes, and as it processes the list(s) it can create linked records for the various successes and failures, which could then be updated periodically to the user interface via AJAX, even over the course of several days if necessary.

  • http://www.carlosja.com CarlosJa

    good stuff..

    My favorite function

    $unwanted_characters = array(“#”, “/”, “\\”, “;”, “:”, “(“, “)”, “‘”, “\”", “,”, “.”, “$”, “_”, ” “);
    $StripString = str_replace($unwanted_characters, “_”, ‘Rewrite Your Name Here Replace Any Character with under score.’);

  • http://www.loy-webdesign.de Bärbel Loy

    Thanks for this php article! I didn’t knew you could compress your strings
    and decompress them. Thanks for sharing this.

  • http://www.sstudio.me Web dizajn Crna Gora

    Thanks , I just start with php

  • http://www.schannak.com svs

    Wouldn’t it be better to set Arguments equal to “NULL” in “Functions with Arbitrary Number of Arguments” like $arg1 = NULL ?

  • http://www.tarikguney.com Tarik Guney

    This is an fabulous article and I love the tricks.

    Thanks.

  • http://www.coresystemsusa.com Industrial computer

    I wonder if it disappears absolutely or partially. To me, partial would seem to be much more logical. Often a web page with a lot of nofollow hyperlinks (let’s say a popular weblog post) would lead to virtually not placing the ability to pass on any pagerank at all.

  • Brown agent

    Great! Thank you!

  • Eric P

    debug_backtrace() is invaluable for pinpointing “where” things happened … potentially among hundreds of files in an app. Nothing worse than not being able to tell where you put that damn “echo” 8 days ago.

  • Rajmishra

    Respected sir my facebook id please started now

    • raghu

      ???

      • raghu

        facebook kaha se aaya bich mein …. Lund saala ! ! !

  • anonym

    pls tell me,
    how to create a hompage using with css/html

  • saurav

    hi tutsplus
    realy nice tutorial.

  • http://theranjeet.com/ Ranjeet

    Thanks for your information ..very nice

  • http://www.claindsilva.com Clain Dsilva

    Lovely Article, Its really good to know these functions and you know what, I have come across most of the situations described here and End up in writing my own custom PHP codes.

    Great one Burak..!!

  • http://www.preduzeca.me Poslovni adresar Crna Gora

    I really like this, it is great

  • http://pctechsupport.sytes.net jay

    Hi i need some help creating a script that counts up to see how long a page is open before its closed (I do not mean execution time or load time) so i can see what pages are most popular,

    can anyone help with this please?

  • http://www.gurusafrik.tk kesty

    nice tut

  • http://musichub.co gautam

    hello, sir i using ajax for deleting record but not use perfect . pls. help me

  • http://www.ns-designer.com Nikolai

    Very good post. Very userful!

  • http://net.tutsplus.com/tutorials/php/9-useful-php-functions-and-features-you-need-to-know/ Olayinka

    Please am a beginner can u help look into this function statement if am right. thanks

  • http://www.loverofevening.blogspot.com കണ്ണൻ | Kannan

    Superp post. really nice. thanks

  • Medicol

    Cool

  • RED

    This is a nice set of function..

  • Akhhilesh Kumar thakur

    Nice,Good set of function

  • Garry

    very useful examples….

  • George

    Very Good.
    Thanks a lot.

  • revillwebdesign

    Awesome! Great set of functions, some I have never used :)

  • Md. Rakibul Hasan

    Thanks a lot.

  • http://www.facebook.com/arvindkthakur.jnr Arvind Thakur

    Nice one and thank you for your time to put this information up. For debugging in php i found this useful php function someone may be interested in.

  • Munish Pathak

    These functions are very good.
    Thanks for publishing them…….