標籤:uip pdb wav 它的 msf tag nim pem amt
一 foreach的引用
$arr = range(1,3); //[1,2,3] foreach($arr as &$val) { } foreach($arr as $val) { } print_r($arr);
上面的代碼會輸出什嗎?
Array ( [0] => 1 [1] => 2 [2] => 2 )
這是因為foreach的原始碼中,對變數進行了引用。導致其作用之後,將地址賦值於最後一個
例:
tmp是var的引用,指向的是var的儲存空間,當tmp改變的時候,var也改變
$var = 123;
$tmp = &$var;
$tmp = 200;
echo $var;
//20
:
解決方案:
//方法1 foreach ($arr as &$value) { } unset($value); foreach ($arr as $value) { } print_r($arr); //[1,2,3]
//方法2 foreach ($arr as &$value) {} foreach ($arr as $val) {} print_r($arr); //[1,2,3]
//方法3 foreach ($arr as &$value) {} foreach ($arr as &$value) { } print_r($arr); //[1,2,3]
二 擅於用array_walk 和 foreach, for
<?php/** * array_walk 和 foreach, for 的效率的比較。 * 我們要測試的是foreach, for, 和 array_walk的效率的問題。 *///產生一個10000的一個數組。$max = 10000;$test_arr = range(0, $max);$temp;//我們分別用三種方法測試求這些數加上1的值的時間。// for 的方法$t1 = microtime(true);for ($i = 0; $i < $max; $i++) { $temp = $temp + 1;}$t2 = microtime(true);$t = $t2 - $t1;echo "就使用for, 沒有對數組操作 花費: {$t}\n";$t1 = microtime(true);for ($i = 0; $i < $max; $i++) { $test_arr[$i] = $test_arr[$i] + 1;}$t2 = microtime(true);$t = $t2 - $t1;echo "使用for 並且直接對數組進行了操作 花費: {$t}\n";$t1 = microtime(true);for ($i = 0; $i < $max; $i++) { addOne($test_arr[$i]);}$t2 = microtime(true);$t = $t2 - $t1;echo "使用for 調用函數對數組操作 花費 : {$t}\n";$t1 = microtime(true);foreach ($test_arr as $k => &$v) { $temp = $temp + 1;}$t2 = microtime(true);$t = $t2 - $t1;echo "使用 foreach 沒有對數組操作 花費 : {$t}\n";$t1 = microtime(true);foreach ($test_arr as $k => &$v) { $v = $v + 1;}$t2 = microtime(true);$t = $t2 - $t1;echo "使用 foreach 直接對數組操作 : {$t}\n";$t1 = microtime(true);foreach ($test_arr as $k => &$v) { addOne($v);}$t2 = microtime(true);$t = $t2 - $t1;echo "使用 foreach 調用函數對數組操作 : {$t}\n";$t1 = microtime(true);array_walk($test_arr, ‘addOne‘);$t2 = microtime(true);$t = $t2 - $t1;echo "使用 array_walk 花費 : {$t}\n";function addOne(&$item) { $item = $item + 1;}
執行的結果:
就使用for, 沒有對數組操作 花費: 0.15388584136963
使用 foreach 沒有對數組操作 花費 : 0.076934814453125
使用for 並且直接對數組進行了操作 花費: 0.14769005775452
使用 foreach 直接對數組操作 : 0.076115131378174
使用for 調用函數對數組操作 花費 : 0.32393312454224
使用 foreach 調用函數對數組操作 : 0.25716996192932
使用 array_walk 花費 : 0.17966890335083
在對10000個數的操作過程中,這個實驗我們可以得出這樣的結論:
foreach 的效率要比for 高很多,也許有很大的一個原因是for 要進行很多次條件判斷。所以以後能用foreach的地方就用foreach,可以提高1倍的效率。
如果迴圈內要調用函數,用array_walk 最好,它的效率要比for 高出1倍,要比foreach高出43%的效率。
還有一個提示就是如果你這個程式對效率的要求是很高的,那不要在很深的迴圈中調用函數,要調用函數也要用array_walk,最好的直接把代碼寫在迴圈裡面。
同時,我們來看一下這兩個函數的區別:
array_walk 主要是要對數組內的每個值進行操作,操作結果影響原來的數組array_map主要是對數組中的值進行操作後返回數組,以得到一個新數組wallk 可以沒有傳回值 map要有,因為要填充數組
三 為什麼要用聯合索引 ?
1 在多條件查詢時,聯合索引效率要高。在允許的範圍內,多條件個條件查詢的時候,應該根據業務建立多個聯合索引。這樣效率比分開建立多個索引要快
2 查詢條件中出現聯合索引第一列,或者全部,則能利用聯合索引.
換句話說:查詢條件中沒有出現聯合索引的第一列,而出現聯合索引的第二列,或者第三列,都不會利用聯合索引查詢.
而單一索引:只要條件列中出現索引列,無論在什麼位置,都能利用索引查詢.
我本地電腦有如下表:
CREATE TABLE `t_log_change_name` ( `id` int(11) NOT NULL AUTO_INCREMENT, `player_id` int(11) NOT NULL DEFAULT ‘0‘, `old_name` varchar(255) NOT NULL DEFAULT ‘‘, `day` int(11) NOT NULL DEFAULT ‘20110101‘, PRIMARY KEY (`id`), KEY `idx_player_id` (`player_id`,`day`) USING BTREE) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT;
當我使用聯合條件查詢,
EXPLAIN select * from t_log_change_name where player_id =344 and `day`>=‘20161012‘;
結果當然是沒問題的,直接選中想要的資料,影響行為3行
當我用只使用第一列為條件查詢,
EXPLAIN select * from t_log_change_name where player_id =344;
它處於索引的第一列,因此是可以命中索引的
當我使用第二列為條件查詢,
EXPLAIN select * from t_log_change_name where `day`>=‘20161012‘;
那不好意思,它屬於索引的第二列,因此無法命中索引,全部行都檢索一遍
所以務必根據業務需求而去建立合適的索引
,同時注意聯合索引的順序,失效情況。
分享php工作中遇到的一些探究和技巧【1】