PHP很有用的功能
1. 函式的任意數目的引數
你可能知道PHP允許你定義一個預設引數的函式。但你可能並不知道PHP還允許你定義一個完全任意的引數的函式
下面是一個示例向你展示了預設引數的函式:
// 兩個預設引數的函式
functionfoo($arg1='',$arg2='') {
echo"arg1: $arg1\n";
echo"arg2: $arg2\n";
}
foo('hello','world');
/* 輸出:
arg1: hello
arg2: world
*/
foo();
/* 輸出:
arg1:
arg2:
*/
|
現在我們來看一看一個不定引數的函式,其使用到了?func_get_args()方法:
// 是的,形參列表為空
functionfoo() {
// 取得所有的傳入引數的陣列
$args= func_get_args();
foreach($argsas$k=>$v) {
echo"arg".($k+1).": $v\n";
}
}
foo();
/* 什麼也不會輸出 */
foo('hello');
/* 輸出
arg1: hello
*/
foo('hello','world','again');
/* 輸出
arg1: hello
arg2: world
arg3: 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";
/* prints
Final: 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: 傳送的message
- ru_msgrcv: 收到的message
- ru_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萬,並把它新增到秒的值後,可以得到有小數部分的秒數。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
// 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是不佔用系統時間的,我們可以來看下面的一個例子:
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); /* 輸出 User time: 1.424592 System time: 0.004204 */ |
這花了大約14秒的CPU時間,幾乎所有的都是使用者的時間,因為沒有系統呼叫。
系統時間是CPU花費在系統呼叫上的上執行核心指令的時間。下面是一個例子:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
$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 */ |
我們可以看到上面這個例子更耗CPU。
5. 系統常量
PHP 提供非常有用的系統常量 可以讓你得到當前的行號 (__LINE__),檔案 (__FILE__),目錄 (__DIR__),函式名 (__FUNCTION__),類名(__CLASS__),方法名(__METHOD__) 和名字空間 (__NAMESPACE__),很像C語言。
我們可以以為這些東西主要是用於除錯,當也不一定,比如我們可以在include其它檔案的時候使用?__FILE__ (當然,你也可以在 PHP 5.3以後使用 __DIR__ ),下面是一個例子。
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' ); |
下面是使用 __LINE__ 來輸出一些debug的資訊,這樣有助於你除錯程式:
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__ ); /* 輸出 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() 來生成一個唯一的ID,如下所示:
1
2
|
// generate unique string echo md5(time() . mt_rand(1,1000000)); |
其實,PHP中有一個叫?uniqid() 的函式是專門用來幹這個的:
1
2
3
4
5
6
7
8
9
10
11
|
// generate unique string echo uniqid(); /* 輸出 4bd67c947233e */ // generate another unique string echo uniqid(); /* 輸出 4bd67c9472340 */ |
可能你會注意到生成出來的ID前幾位是一樣的,這是因為生成器依賴於系統的時間,這其實是一個非常不錯的功能,因為你是很容易為你的這些ID排序的。這點MD5是做不到的。
你還可以加上字首避免重名:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
// 字首 echo uniqid( 'foo_' ); /* 輸出 foo_4bd67d6cd8b8f */ // 有更多的熵 echo uniqid( '' ,true); /* 輸出 4bd67d6cd8b926.12135106 */ // 都有 echo uniqid( 'bar_' ,true); /* 輸出 bar_4bd67da367b650.43684647 */ |
而且,生成出來的ID會比MD5生成的要短,這會讓你節省很多空間。
7. 序列化
你是否會把一個比較複雜的資料結構存到資料庫或是檔案中?你並不需要自己去寫自己的演算法。PHP早已為你做好了,其提供了兩個函式:?serialize() 和 unserialize():
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
|
// 一個複雜的陣列 $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() 函式
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 ) */ |
這看起來更為緊湊一些了,而且還相容於Javascript和其它語言。但是對於一些非常複雜的資料結構,可能會造成資料丟失。
8. 字串壓縮
當我們說到壓縮,我們可能會想到檔案壓縮,其實,字串也是可以壓縮的。PHP提供了?gzcompress() 和gzuncompress() 函式:
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" ; /* 輸出原始大小 Original size: 800 */ echo "Compressed size: " . strlen ( $compressed ). "\n" ; /* 輸出壓縮後的大小 Compressed size: 418 */ // 解壓縮 $original = gzuncompress( $compressed ); |
幾乎有50% 壓縮比率。同時,你還可以使用?gzencode() 和 gzdecode() 函式來壓縮,只不用其用了不同的壓縮演算法。
9. 註冊停止函式
有一個函式叫做?register_shutdown_function(),可以讓你在整個指令碼停時前執行程式碼。讓我們看下面的一個示例:
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." ; |
上面這個示例只不過是用來計算某個函式執行的時間。然後,如果你在函式中間呼叫?exit() 函式,那麼你的最後的程式碼將不會被執行到。並且,如果該指令碼在瀏覽器終止(使用者按停止按鈕),其也無法被執行。
而當我們使用了register_shutdown_function()後,你的程式就算是在指令碼被停止後也會被執行:
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." ; }
http://coolshell.cn/articles/2394.html
|
相關文章
- 九個PHP很有用的功能PHP
- Apache Spark和Hive有用的功能ApacheSparkHive
- 24個有用的PHP類庫分享PHP
- 20個很有用的PHP類庫PHP
- 24個有用的PHP類庫分享(上)PHP
- 24個有用的PHP類庫分享(下)PHP
- 20個非常有用的PHP類庫PHP
- 17個非常有用的PHP類和庫PHP
- 超級有用的9個PHP程式碼片段PHP
- 快手小程式的分銷功能有用嗎?
- 一個很簡單的PHP框架lyuePHP框架
- [精選]php 如何使用最近很火的ChatGPTPHPChatGPT
- 最簡單易懂的laravel事件,這個功能非常的有用Laravel事件
- Eclipse 中隱藏的 5 個非常有用的功能Eclipse
- 你需要知道的、有用的 Python 功能和特點Python
- 40+個對初學者非常有用的PHP技巧(二)PHP
- 2014 年 10 款有用的 PHP 測試框架PHP框架
- 40+個對初學者非常有用的PHP技巧(一)PHP
- 分享一個功能很全的視訊播放器播放器
- 10個超級有用、必須收藏的PHP程式碼樣例PHP
- PHP中的LDAP功能函(轉)PHPLDA
- php抽獎功能PHP
- PHP註冊功能PHP
- 聽說最近這4款堪稱神器的黑科技APP很熱門,你有用過嗎?APP
- 前端實現很哇塞的瀏覽器端掃碼功能?前端瀏覽器
- 有用的命令
- PHP 5.3、5.4、5.5、5.6 中的新特性(7出來但是一樣有用)PHP
- 小米米家掃地機器人詳情曝光:功能很強大!機器人
- 有用的 oracle 包Oracle
- 有用的廢話
- 有用的資料
- iOS 圖解一個功能很全的視訊播放器的使用iOS圖解播放器
- [翻譯] PHP 7.2 中棄用的功能PHP
- 8個開發必備的PHP功能PHP
- PHP面試經常被問到的知識點彙總,對你非常有用PHP面試
- 很全很全的JavaScript的模組講解JavaScript
- PHP8 都有哪些新功能,說說PHP8的新增特性PHP
- PHP中很屌但經常被各種忽略的過濾器函式PHP過濾器函式