九個(gè)你必須知道而且又很好用的php函數(shù)和特點(diǎn)
下面是九個(gè)PHP中很有用的功能,不知道你用過(guò)了嗎?
1. 函數(shù)的任意數(shù)目的參數(shù)
你可能知道PHP允許你定義一個(gè)默認(rèn)參數(shù)的函數(shù)。但你可能并不知道PHP還允許你定義一個(gè)完全任意的參數(shù)的函數(shù)
下面是一個(gè)示例向你展示了默認(rèn)參數(shù)的函數(shù):
// 兩個(gè)默認(rèn)參數(shù)的函數(shù)
function foo($arg1 = '', $arg2 = '') {
echo "arg1: $arg1/n";
echo "arg2: $arg2/n";
}
foo('hello','world');
/* 輸出:
arg1: hello
arg2: world
*/
foo();
/* 輸出:
arg1:
arg2:
*/
現(xiàn)在我們來(lái)看一看一個(gè)不定參數(shù)的函數(shù),其使用到了func_get_args()方法:
// 是的,形參列表為空
function foo() {
// 取得所有的傳入?yún)?shù)的數(shù)組
$args = func_get_args();
foreach ($args as $k => $v) {
echo "arg".($k+1).": $v/n";
}
}
foo();
/* 什么也不會(huì)輸出 */
foo('hello');
/* 輸出
arg1: hello
*/
foo('hello', 'world', 'again');
/* 輸出
arg1: hello
arg2: world
arg3: again
*/
2. 使用 Glob() 查找文件
很多PHP的函數(shù)都有一個(gè)比較長(zhǎng)的自解釋的函數(shù)名,但是,當(dāng)你看到glob() 的時(shí)候,你可能并不知道這個(gè)函數(shù)是用來(lái)干什么的,除非你對(duì)它已經(jīng)很熟悉了。
你可以認(rèn)為這個(gè)函數(shù)就好scandir() 一樣,其可以用來(lái)查找文件。
// 取得所有的后綴為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
)
*/
如果你想得到絕對(duì)路徑,你可以調(diào)用realpath() 函數(shù):
$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. 內(nèi)存使用信息
觀察你程序的內(nèi)存使用能夠讓你更好的優(yōu)化你的代碼。
PHP 是有垃圾回收機(jī)制的,而且有一套很復(fù)雜的內(nèi)存管理機(jī)制。你可以知道你的腳本所使用的內(nèi)存情況。要知道當(dāng)前內(nèi)存使用情況,你可以使用memory_get_usage() 函數(shù),如果你想知道使用內(nèi)存的峰值,你可以調(diào)用memory_get_peak_usage() 函數(shù)。
echo "Initial: ".memory_get_usage()." bytes /n";
/* 輸出
Initial: 361400 bytes
*/
// 使用內(nèi)存
for ($i = 0; $i < 100000; $i++) {
$array []= md5($i);
}
// 刪除一半的內(nèi)存
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";
/* 輸出峰值
Peak: 13687072 bytes
*/
4. CPU使用信息
使用getrusage() 函數(shù)可以讓你知道CPU的使用情況。注意,這個(gè)功能在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
)
*/
這個(gè)結(jié)構(gòu)上看很晦澀,除非你對(duì)CPU很了解。下面一些解釋?zhuān)?BR>ru_oublock: 塊輸出操作
ru_inblock: 塊輸入操作
ru_msgsnd: 發(fā)送的message
ru_msgrcv: 收到的message
ru_maxrss: 最大駐留集大小
ru_ixrss: 全部共享內(nèi)存大小
ru_idrss:全部非共享內(nèi)存大小
ru_minflt: 頁(yè)回收
ru_majflt: 頁(yè)失效
ru_nsignals: 收到的信號(hào)
ru_nvcsw: 主動(dòng)上下文切換
ru_nivcsw: 被動(dòng)上下文切換
ru_nswap: 交換區(qū)
ru_utime.tv_usec: 用戶(hù)態(tài)時(shí)間 (microseconds)
ru_utime.tv_sec: 用戶(hù)態(tài)時(shí)間(seconds)
ru_stime.tv_usec: 系統(tǒng)內(nèi)核時(shí)間 (microseconds)
ru_stime.tv_sec: 系統(tǒng)內(nèi)核時(shí)間?(seconds)
要看到你的腳本消耗了多少CPU,我們需要看看“用戶(hù)態(tài)的時(shí)間”和“系統(tǒng)內(nèi)核時(shí)間”的值。秒和微秒部分是分別提供的,您可以把微秒值除以100萬(wàn),并把它添加到秒的值后,可以得到有小數(shù)部分的秒數(shù)。
// 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.011552
System time: 0
*/
sleep是不占用系統(tǒng)時(shí)間的,我們可以來(lái)看下面的一個(gè)例子:
// 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.424592
System time: 0.004204
*/
這花了大約14秒的CPU時(shí)間,幾乎所有的都是用戶(hù)的時(shí)間,因?yàn)闆](méi)有系統(tǒng)調(diào)用。
系統(tǒng)時(shí)間是CPU花費(fèi)在系統(tǒng)調(diào)用上的上執(zhí)行內(nèi)核指令的時(shí)間。下面是一個(gè)例子:
$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
*/
我們可以看到上面這個(gè)例子更耗CPU。
5. 系統(tǒng)常量
PHP 提供非常有用的系統(tǒng)常量 可以讓你得到當(dāng)前的行號(hào) (__LINE__),文件 (__FILE__),目錄 (__DIR__),函數(shù)名 (__FUNCTION__),類(lèi)名(__CLASS__),方法名(__METHOD__) 和名字空間 (__NAMESPACE__),很像C語(yǔ)言。
我們可以以為這些東西主要是用于調(diào)試,當(dāng)也不一定,比如我們可以在include其它文件的時(shí)候使用?__FILE__ (當(dāng)然,你也可以在 PHP 5.3以后使用 __DIR__ ),下面是一個(gè)例子。
// 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');
下面是使用 __LINE__ 來(lái)輸出一些debug的信息,這樣有助于你調(diào)試程序:
// 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";
}
6.生成唯一的ID
有很多人使用 md5() 來(lái)生成一個(gè)唯一的ID,如下所示:
// generate unique string
echo md5(time() . mt_rand(1,1000000));
其實(shí),PHP中有一個(gè)叫uniqid() 的函數(shù)是專(zhuān)門(mén)用來(lái)干這個(gè)的:
// generate unique string
echo uniqid();
/* 輸出
4bd67c947233e
*/
// generate another unique string
echo uniqid();
/* 輸出
4bd67c9472340
*/
可能你會(huì)注意到生成出來(lái)的ID前幾位是一樣的,這是因?yàn)樯善饕蕾?lài)于系統(tǒng)的時(shí)間,這其實(shí)是一個(gè)非常不錯(cuò)的功能,因?yàn)槟闶呛苋菀诪槟愕倪@些ID排序的。這點(diǎn)MD5是做不到的。
你還可以加上前綴避免重名:
// 前綴
echo uniqid('foo_');
/* 輸出
foo_4bd67d6cd8b8f
*/
// 有更多的熵
echo uniqid('',true);
/* 輸出
4bd67d6cd8b926.12135106
*/
// 都有
echo uniqid('bar_',true);
/* 輸出
bar_4bd67da367b650.43684647
*/
而且,生成出來(lái)的ID會(huì)比MD5生成的要短,這會(huì)讓你節(jié)省很多空間。
7. 序列化
你是否會(huì)把一個(gè)比較復(fù)雜的數(shù)據(jù)結(jié)構(gòu)存到數(shù)據(jù)庫(kù)或是文件中?你并不需要自己去寫(xiě)自己的算法。PHP早已為你做好了,其提供了兩個(gè)函數(shù):serialize() 和 unserialize():
// 一個(gè)復(fù)雜的數(shù)組
$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的原生函數(shù),然而在今天JSON越來(lái)越流行,所以在PHP5.2以后,PHP開(kāi)始支持JSON,你可以使用 json_encode() 和 json_decode() 函數(shù)
// 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
)
*/
這看起來(lái)更為緊湊一些了,而且還兼容于Javascript和其它語(yǔ)言。但是對(duì)于一些非常復(fù)雜的數(shù)據(jù)結(jié)構(gòu),可能會(huì)造成數(shù)據(jù)丟失。
8. 字符串壓縮
當(dāng)我們說(shuō)到壓縮,我們可能會(huì)想到文件壓縮,其實(shí),字符串也是可以壓縮的。PHP提供了gzcompress() 和 gzuncompress() 函數(shù):
$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";
/* 輸出原始大小
Original size: 800
*/
echo "Compressed size: ". strlen($compressed)."/n";
/* 輸出壓縮后的大小
Compressed size: 418
*/
// 解壓縮
$original = gzuncompress($compressed);
幾乎有50% 壓縮比率。同時(shí),你還可以使用gzencode() 和 gzdecode() 函數(shù)來(lái)壓縮,只不用其用了不同的壓縮算法。
9. 注冊(cè)停止函數(shù)
有一個(gè)函數(shù)叫做register_shutdown_function(),可以讓你在整個(gè)腳本停時(shí)前運(yùn)行代碼。讓我們看下面的一個(gè)示例:
// 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.";
上面這個(gè)示例只不過(guò)是用來(lái)計(jì)算某個(gè)函數(shù)運(yùn)行的時(shí)間。然后,如果你在函數(shù)中間調(diào)用exit() 函數(shù),那么你的最后的代碼將不會(huì)被運(yùn)行到。并且,如果該腳本在瀏覽器終止(用戶(hù)按停止按鈕),其也無(wú)法被運(yùn)行。
而當(dāng)我們使用了register_shutdown_function()后,你的程序就算是在腳本被停止后也會(huì)被運(yùn)行:
$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.";
}
相關(guān)文章
php中隨機(jī)函數(shù)mt_rand()與rand()性能對(duì)比分析
這篇文章主要介紹了php中隨機(jī)函數(shù)mt_rand()與rand()性能對(duì)比分析,較為詳細(xì)的分析了兩個(gè)函數(shù)的具體用法,并以實(shí)例形式分析了在不同平臺(tái)下的運(yùn)行效率問(wèn)題,需要的朋友可以參考下2014-12-12php讀取二進(jìn)制流(C語(yǔ)言結(jié)構(gòu)體struct數(shù)據(jù)文件)的深入解析
本篇文章是對(duì)php讀取二進(jìn)制流(C語(yǔ)言結(jié)構(gòu)體struct數(shù)據(jù)文件)進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-06-06php的命名空間與自動(dòng)加載實(shí)現(xiàn)方法
這篇文章主要給大家介紹了關(guān)于php的命名空間與自動(dòng)加載實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用php具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-08-08關(guān)于php連接mssql:pdo odbc sql server
研究了很久,終于發(fā)現(xiàn):最新的php 5.3.6中php_mssql.dll,php_pdo_mssql.dll都已經(jīng)不見(jiàn)了。2011-07-07PHP連接Access數(shù)據(jù)庫(kù)的方法小結(jié)
有時(shí)候我們?cè)陂_(kāi)發(fā)一些小程序或簡(jiǎn)單功能的管理系統(tǒng),又沒(méi)有mysql數(shù)據(jù)庫(kù)的情況下,就可以使用access了,這里介紹下鏈接方法2013-06-06PHP simple_html_dom.php+正則 采集文章代碼
網(wǎng)上也有很多人也在用PHP Simple Dom 雖然效率慢了點(diǎn),但效果還是不錯(cuò)的從包含類(lèi)庫(kù)文件到寫(xiě)入txt文件 大概是7/8就秒。2009-12-12php策略模式簡(jiǎn)單示例分析【區(qū)別于工廠模式】
這篇文章主要介紹了php策略模式,對(duì)比工廠模式簡(jiǎn)單分析了php策略模式的原理與使用方法,需要的朋友可以參考下2019-09-09