以下は PHP の 9 つの非常に便利な関数です。使ったことはありますか? 1. 関数の任意の数のパラメーター PHP では、デフォルトのパラメーターを使用して関数を定義できることはご存知かもしれません。しかし、PHP では完全に任意のパラメーターを使用して関数を定義できることはご存知ないかもしれません。デフォルトを示す例を次に示します。 PHP デフォルトパラメータを使用して関数を定義できます。しかし、PHP では完全に任意のパラメータを持つ関数を定義することもできることはご存知ないかもしれません
以下は、デフォルト パラメータを持つ関数を示す例です:
function foo($arg1 = '', $arg2 = '') { echo "arg1: $arg1\n"; echo "arg2: $arg2\n";}foo('hello','world');/* 输出:arg1: helloarg2: world*/foo();/* 输出:arg1:arg2:*/
// 是的,形参列表为空function foo() { // 取得所有的传入参数的数组 $args = func_get_args(); foreach ($args as $k => $v) { echo "arg".($k+1).": $v\n"; }}foo();/* 什么也不会输出 */foo('hello');/* 输出arg1: hello*/foo('hello', 'world', 'again');/* 输出arg1: helloarg2: worldarg3: again*/
2. Glob() を使用してファイルを検索します
多くの PHP 関数には、比較的長い一目瞭然の関数名がありますが、?glob() を参照すると、現時点では、この関数に慣れていない限り、この関数が何に使用されるのかわからないかもしれません。
この関数は、ファイルの検索に使用できる ?scandir() と考えることができます。
// 取得所有的后缀为PHP的文件$files = glob('*.php');print_r($files);/* 输出:Array( [0] => phptest.php [1] => pi.php [2] => post_output.php [3] => test.php)*/你还可以查找多种后缀名// 取PHP文件和TXT文件$files = glob('*.{php,txt}', GLOB_BRACE);print_r($files);/* 输出:Array( [0] => phptest.php [1] => pi.php [2] => post_output.php [3] => test.php [4] => log.txt [5] => test.txt)*/
//你还可以加上路径:$files = glob('../images/a*.jpg');print_r($files);/* 输出:Array( [0] => ../images/apple.jpg [1] => ../images/art.jpg)*///如果你想得到绝对路径,你可以调用?realpath()函数:$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. メモリ使用量情報
プログラムのメモリ使用量を観察すると、コードをより適切に最適化できます。
PHP には、ガベージ コレクション メカニズムと非常に複雑なメモリ管理メカニズムがあります。スクリプトが使用しているメモリ量を確認できます。現在のメモリ使用量を知るには、memory_get_usage() 関数を使用します。ピーク時のメモリ使用量を知りたい場合は、memory_get_peak_usage() 関数を呼び出します。
echo "Initial: ".memory_get_usage()." bytes \n";/* 输出Initial: 361400 bytes*/// 使用内存for ($i = 0; $i < 100000; $i++) { $array []= md5($i);}// 删除一半的内存for ($i = 0; $i < 100000; $i++) { unset($array[$i]);}echo "Final: ".memory_get_usage()." bytes \n";/* printsFinal: 885912 bytes*/echo "Peak: ".memory_get_peak_usage()." bytes \n";/* 输出峰值Peak: 13687072 bytes*/
4.CPU 使用率情報
?getrusage() 関数を使用すると、CPU 使用率を知ることができます。この機能は Windows では使用できないことに注意してください。
print_r(getrusage());/* 输出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)*/这个结构看上出很晦涩,除非你对CPU很了解。下面一些解释:ru_oublock: 块输出操作ru_inblock: 块输入操作ru_msgsnd: 发送的messageru_msgrcv: 收到的messageru_maxrss: 最大驻留集大小ru_ixrss: 全部共享内存大小ru_idrss:全部非共享内存大小ru_minflt: 页回收ru_majflt: 页失效ru_nsignals: 收到的信号ru_nvcsw: 主动上下文切换ru_nivcsw: 被动上下文切换ru_nswap: 交换区ru_utime.tv_usec: 用户态时间 (microseconds)ru_utime.tv_sec: 用户态时间(seconds)ru_stime.tv_usec: 系统内核时间 (microseconds)ru_stime.tv_sec: 系统内核时间?(seconds)要看到你的脚本消耗了多少CPU,我们需要看看“用户态的时间”和“系统内核时间”的值。秒和微秒部分是分别提供的,您可以把微秒值除以100万,并把它添加到秒的值后,可以得到有小数部分的秒数。// 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);/* 输出User time: 0.011552System time: 0*/sleep是不占用系统时间的,我们可以来看下面的一个例子:// 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);/* 输出User time: 1.424592System time: 0.004204*/这花了大约14秒的CPU时间,几乎所有的都是用户的时间,因为没有系统调用。系统时间是CPU花费在系统调用上的上执行内核指令的时间。下面是一个例子:$start = microtime(true);// keep calling microtime for about 3 secondswhile(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);/* printsUser time: 1.088171System time: 1.675315*/我们可以看到上面这个例子更耗CPU。
5. システム定数
PHP は、現在の行番号 (__LINE__)、ファイル (__FILE__)、ディレクトリ (__DIR__)、関数名 (__FUNCTION__) を取得できる非常に便利なシステム定数を提供します。 、クラス名 (__CLASS__)、メソッド名 (__METHOD__)、および名前空間 (__NAMESPACE__) は、C 言語とよく似ています。
これらは主にデバッグに使用されると考えられますが、必ずしもそうではありません。たとえば、他のファイルをインクルードする場合は、?__FILE__ を使用できます (もちろん、PHP 5.3 以降では __DIR__ を使用することもできます)。
/ this is relative to the loaded script's path// it may cause problems when running scripts from different directoriesrequire_once('config/database.php');// this is always relative to this file's path// no matter where it was included fromrequire_once(dirname(__FILE__) . '/config/database.php');//下面是使用 __LINE__ 来输出一些debug的信息,这样有助于你调试程序:// some code// ...my_debug("some debug message", __LINE__);/* 输出Line 4: some debug message*/// some more code// ...my_debug("another debug message", __LINE__);/* 输出Line 11: another debug message*/function my_debug($msg, $line) { echo "Line $line: $msg\n";}
以下に示すように、多くの人は md5() を使用して一意の ID を生成します:
// generate unique stringecho md5(time() . mt_rand(1,1000000));其实,PHP中有一个叫?uniqid()的函数是专门用来干这个的:// generate unique stringecho uniqid();/* 输出4bd67c947233e*/// generate another unique stringecho uniqid();/* 输出4bd67c9472340*/可能你会注意到生成出来的ID前几位是一样的,这是因为生成器依赖于系统的时间,这其实是一个非常不错的功能,因为你是很容易为你的这些ID排序的。这点MD5是做不到的。你还可以加上前缀避免重名:// 前缀echo uniqid('foo_');/* 输出foo_4bd67d6cd8b8f*/// 有更多的熵echo uniqid('',true);/* 输出4bd67d6cd8b926.12135106*/// 都有echo uniqid('bar_',true);/* 输出bar_4bd67da367b650.43684647*/而且,生成出来的ID会比MD5生成的要短,这会让你节省很多空间。
7. シリアル化
// 一个复杂的数组$myvar = array( 'hello', 42, array(1,'two'), 'apple');// 序列化$string = serialize($myvar);echo $string;/* 输出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";}*/// 反序例化$newvar = unserialize($string);print_r($newvar);/* 输出Array( [0] => hello [1] => 42 [2] => Array ( [0] => 1 [1] => two ) [3] => apple)*/这是PHP的原生函数,然而在今天JSON越来越流行,所以在PHP5.2以后,PHP开始支持JSON,你可以使用 json_encode() 和 json_decode() 函数// 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);/* printsArray( [0] => hello [1] => 42 [2] => Array ( [0] => 1 [1] => two ) [3] => apple)*/这看起来更为紧凑一些了,而且还兼容于Javascript和其它语言。但是对于一些非常复杂的数据结构,可能会造成数据丢失
8. 文字列圧縮
$string ="Lorem ipsum dolor sit amet, consecteturadipiscing elit. Nunc ut elit id mi ultriciesadipiscing. Nulla facilisi. Praesent pulvinar,sapien vel feugiat vestibulum, nulla dui pretium orci,non ultricies elit lacus quis ante. Lorem ipsum dolorsit amet, consectetur adipiscing elit. Aliquampretium ullamcorper urna quis iaculis. Etiam ac massased turpis tempor luctus. Curabitur sed nibh eu elitmollis congue. Praesent ipsum diam, consectetur vitaeornare a, aliquam a nunc. In id magna pellentesquetellus posuere adipiscing. Sed non mi metus, at laciniaaugue. Sed magna nisi, ornare in mollis in, mollissed nunc. Etiam at justo in leo congue mollis.Nullam in neque eget metus hendrerit scelerisqueeu non enim. Ut malesuada lacus eu nulla bibendumid euismod urna sodales. ";$compressed = gzcompress($string);echo "Original size: ". strlen($string)."\n";/* 输出原始大小Original size: 800*/echo "Compressed size: ". strlen($compressed)."\n";/* 输出压缩后的大小Compressed size: 418*/// 解压缩$original = gzuncompress($compressed);几乎有50% 压缩比率。同时,你还可以使用?gzencode()和gzdecode()函数来压缩,只不用其用了不同的压缩算法。
9. シャットダウン関数を登録する
// capture the start time$start_time = microtime(true);// do some stuff// ...// display how long the script tookecho "execution took: ". (microtime(true) - $start_time). " seconds.";上面这个示例只不过是用来计算某个函数运行的时间。然后,如果你在函数中间调用?exit()函数,那么你的最后的代码将不会被运行到。并且,如果该脚本在浏览器终止(用户按停止按钮),其也无法被运行。而当我们使用了register_shutdown_function()后,你的程序就算是在脚本被停止后也会被运行:$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.";}