Академический Документы
Профессиональный Документы
Культура Документы
2011
Advertise Here
tutsplus.com//9-useful-php-functio
08.04.2011
Now, lets see how we can build a function that accepts any number of arguments. This time we are going to utilize func_get_args(): view plaincopy to clipboardprint? 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. // 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 */
tutsplus.com//9-useful-php-functio
08.04.2011
7. ( 8. [0] => phptest.php 9. [1] => pi.php 10. [2] => post_output.php 11. [3] => test.php 12. ) 13. */ You can fetch multiple file types like this: view plaincopy to clipboardprint? 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. // 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: view plaincopy to clipboardprint? 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. $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: view plaincopy to clipboardprint? 1. 2. 3. 4. 5. 6. 7. 8. $files = glob('../images/a*.jpg'); // applies the function to each array element $files = array_map('realpath',$files); print_r($files); /* output looks like: Array
3/14
tutsplus.com//9-useful-php-functio
08.04.2011
9. ( 10. [0] => C:\wamp\www\images\apple.jpg 11. [1] => C:\wamp\www\images\art.jpg 12. ) 13. */
08.04.2011
3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24.
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: view plaincopy to clipboardprint? 1. // sleep for 3 seconds (non-busy) 2. sleep(3);
tutsplus.com//9-useful-php-functio 5/14
08.04.2011
$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: view plaincopy to clipboardprint? 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. // 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: view plaincopy to clipboardprint? 1. 2. 3. 4. 5. 6. 7. $start = microtime(true); // keep calling microtime for about 3 seconds while(microtime(true) - $start < 3) { } $data = getrusage();
6/14
tutsplus.com//9-useful-php-functio
08.04.2011
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): view plaincopy to clipboardprint? 1. 2. 3. 4. 5. 6. 7. // 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');
7/14
tutsplus.com//9-useful-php-functio
makes debugging easier. You can track down the line numbers:
view plaincopy to clipboardprint? 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. // 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"; }
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:
tutsplus.com//9-useful-php-functio 8/14
08.04.2011
view plaincopy to clipboardprint? 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. // 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(): view plaincopy to clipboardprint? 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. // 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
9/14
tutsplus.com//9-useful-php-functio
08.04.2011
22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34.
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: view plaincopy to clipboardprint? 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. // 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 ) */
10/14
tutsplus.com//9-useful-php-functio
08.04.2011
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: view plaincopy to clipboardprint? 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. $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.
08.04.2011
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: view plaincopy to clipboardprint? 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. // 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: view plaincopy to clipboardprint? 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. $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!
Like 347 people like this. Be the first of your friends.
tutsplus.com//9-useful-php-functio
12/14
08.04.2011
By Burak Guzel
Burak Guzel is a full time PHP Web Developer living in Arizona, originally from Istanbul, Turkey. He has a bachelors degree in Computer Science and Engineering from The Ohio State University. He has over 8 years of experience with PHP and MySQL. You can read more of his articles on his website at PHPandStuff.com and follow him on Twitter here.
tutsplus.com//9-useful-php-functio
13/14
08.04.2011
tutsplus.com//9-useful-php-functio
14/14