- foreach ($prices as $key => $value)
- echo $key.'=>'.$value.'
';
-
複製代碼如下所示的代碼將使用each()結構列印$prices數組的內容:
- while( $element = each($prices))
- {
- echo $element['key'];
- echo ' - ';
- echo $element['value'];
- echo '
';
- }
-
複製代碼each()函數將返回數組的當前元素,並將下一個元素作為當前元素。因為在while迴圈中調用each()函數,它將按順序返回數組中每個元素,並且當它到達數組末尾時,迴圈操作將終止。在 這段代碼中,變數$element是一個數組。當調用each()時,它將返回一個帶有4個數值和4個指向數組位置的索引的數組。位置key和0包含了當 前元素的關鍵字,而位置value和1包含了當前元素的值。雖然這與選哪一種方法沒什麼不同,但我們選擇了使用命名位置,而不是數字索引位置。此外,還有一種更為進階和常見的方式來完成相同的操作。函數list()可以用來將一個數組分解為一系列的值。可以按照如下方式將函數each()返回的兩個值分開:
- list( $product, $price) = each( $price);
複製代碼以上代碼使用each()從$prices數組中取出當前元素,並且將它作為數組返回,然後再指向下一個元素。它還使用list()將從each()返回的數組中所包含0、1兩個元素變為兩個名為$product和$price的新蠻量。我們可以迴圈遍曆整個$prices數組,使用如下所示的簡短指令碼顯示它的內容:
- while(list($prodct, $pirce) = each($prices))
- echo "$product - $price
";
複製代碼這段代碼的輸出結果與前面指令碼的輸出結果相同,但它更容易閱讀,因為list()允許為新變數命名。需要注意的一點是,當使用each()函數時,數組將記錄當前元素。如果希望在相同的指令碼中兩次使用該數組,就必須使用函數reset()將當前元素重新設定到數組開始處。要再次遍曆prices數組,可以使用如下所示的代碼:
- reset($prices);
- while(list($product, $price) = each($prices))
- echo "$product - $price
";
複製代碼3.4 數組操作符+聯合,==等價,===恒等,!=不等價,<>不等價,!==不恒等。聯合操作符嘗試將$b中的元素添加到$a的末尾。如果$b中的元素與$a中的一些元素具有相同的索引,它們將不會被添加。即$a中的元素將不會被覆蓋。 3.5 多維陣列數組不一定就是一個關鍵字和值的簡單列表——數組中的每個位置還可以儲存另一個數組。使用這種方法,可以建立一個二維數組。可以把二維數組當成一個矩陣,或者是一個具有寬度和高度或者行和列的網路。 3.6 數組排序 3.6.1 使用sort()函數sort()函數是區分字母大小寫。所有的大家字母都在小寫字母的前面。所以‘A’小於‘Z’,而'Z'小於‘a’。該 函數的第二個參數是可選的。這個選擇性參數可以傳遞SORT_REGULAR(預設值)、SORT_NUMERIC或SORT_STRING。指定排序類型 的功能是非常有用的,例如,當要比較可能包含有數字2和12的字串時。從數學角度看,2要小於12,但是作為字串,‘12’卻要小於‘2’。 3.6.2 使用asort()函數和ksort()函數對相關數組排序函數asort()根據數組的每個元素值進行排序。ksort()函數是按關鍵字排序而不是按值排序。 3.6.3 反向排序函數rsort()將一個一維數字索引數組按降序排序。函數arsort()將一個一維相關數組按每個元素值的降序排序。函數krsort()針根據數組元素的關鍵字將一維數組按照降序排序。為了訪問一個一維數組中的資料,需要使用數組的名稱和元素的索引,除了一個元素具有兩個索引——行和列外,二維數組和一維數組是類似的。可以使用雙重for迴圈來實現同樣的效果:
- for ( $row=0; $row<3; $row++ )
- {
- for ( $column=0; $column<3; $column++ )
- {
- echo '|'.$products[$row][$column];
- |
- echo '|
';
- }
-
複製代碼如果對一個大數組使用這種代碼,那麼將簡潔得多。你可能更喜歡建立列名稱來代替數字。可以使用如下代碼:
- $products = array ( array ( 'Code'=>'TIR', 'Descrīption'=>'Tires', 'Price'=>100 ), array ( 'Code'=>'OIL', 'Descrīption'=>'Oil', 'Price'=>10 ), array ( 'Code'=>'SPK', 'Descrīption'=>'Spark Plugs', 'Price'=>4 ) };
-
複製代碼如果希望檢索單個值,那麼使用這個數組會容易得多。請記住,將所描述的內容儲存到用它的名 稱命名的列中,與將其儲存到所謂的第一列中相比,前者更容易記憶。使用描述性索引,不需要記住某個元素是存放在[x][y]位置的。使用一對有意義的行和 列的名稱作為索引可以使用你很容易找到所需的資料。然後,我們卻不能使用一個簡單的for迴圈按順序遍曆每一列。可以使用for迴圈遍曆外部的數 字索引數組$products。$products數組的每一行都是一個具有描述性索引的數組。在while迴圈中使用each()和list()函數, 可以遍曆整個內部數組。因此,需要一個內嵌有while迴圈的for迴圈。
- for ( $row = 0; $row < 3; $row++ }
- {
- while ( list ( $key, $value ) = each ( $products[$row] ) )
- {
- echo "|$value";
- }
- echo '|
';
- }
-
複製代碼三維數組具有高、寬、深的概念。如果能輕鬆地將一個二維數組想像成一個有行和列的表格,那麼就可以將三維數組想像成一堆像這樣的表格。每個元素可以通過層、行和列進行引用。根據建立多維陣列的方法,可以建立四維、五維或六維數組。在PHP中,並沒有設定數組維數的限制,但人們很難設想一個多於三維的數組。大多數的實際問題在邏輯上只需要使用三維或者更少維的數組結構就可以了。 3.7 多維陣列的排序對 多於一維的數組進行排序,或者不按字母和數位順序進行排,要複雜得多。PHP知道如何比較兩個數字或字串,但在多維陣列中,每個元素都是一個數組。 PHP不知道如何比較兩個數組,所以需要建立一個比較它們的方法。在大多數情況下,單詞和數位順序是顯而易見的——但對於複雜的對象,問題就會多一些。 3.7.1 使用者定義排序usort()中的“u”代表“user”,因為這個函數要求傳入使用者定義的比較函數。asort和ksort對應的版本uasort()和uksort()也要求傳入使用者定義的比較函數。類似於asort(),當對非數字索引數組的值進行排序時,uasort()才會被使用。如果值是簡單的數字或文本則可以使用asort。如果要比較的值像數組一樣複雜,可以定義一個比較函數,然後使用uasort()。類似於ksort(),當對非數字索引數組的關鍵字進行排序時才使用uksort()。如果值是簡單的數字或文本就使用ksort。如果要比較的對象像數組一樣複雜,可以定義一個比較函數,然後使用uksort()。 3.7.2 反向使用者排序函數sort()、asort()和ksort()都分別對應一個帶字母“r”的反向排序函數。使用者定義的排序沒有反向變體,但可以對一個多維陣列進行反向排序。 3.8 對數組進行重新排序 3.8.1 使用shuffle()函數在PHP的早期版本中,shuffle()要求調用srand()函數時首先提供一個隨機數產生器。如今,這個步驟已經不再需要了。如果這個函數對你非常重要,可以在程式中應用該函數之前在伺服器上測試它。由於並不需要真正重新排序整個數組,使用array_rand()函數可以實現相同的功能。 3.8.2 使用array_reverse()函數array_reverse()函數使用一個數組作參數,返回一個內容與參數數組相同但順序相反的數組。因為單獨使用range()函數將建立一個升序序列,所以必須使用sort()函數或array_reverse()函數將數組中的數字變為降序。或者,也可以使用for迴圈通過一次一個元素的方式建立這個數組。如:
- $numbers = array();
- for ($i=10; $i>0; $i--)
- array_push( $numbers, $i );
複製代碼一個for迴圈可以像這樣按降序方式運行。可以將計數器一個for迴圈可以像這樣按降序方式運行。可以將計數器的初始值設為一個大數,在每次迴圈末尾使用運算子“--”將計數器減1。在這裡,我們建立了一個空數組,然後使用array_push()函數將每個新元素添加到數組的末尾。請注意,和array_push()相反的函數是array_pop(),這個函數用來刪除並返回數組末尾的一個元素。或者,也可以使用array_reverse()函數將由range()函數所建立的數組進行反向排序。請注意,array_reverse()函數將返回一個原數組修改後的副本。如果不再需要原來的數組,比如在這個例子中,可以用新的副本覆蓋原來的版本。如果資料只是一系列的整數,可以通過將-1作為range()函數的第三個可選調參數,以相反的順序建立該數組。 3.9 從檔案載入數組使用file()函數將整個檔案載入一個數組中。檔案中的每行則成為數組中的一個元素。使用了count()函數來統計數組中的元素個數。explode("\t", $orders[$i])explode()函數可以將傳入的字串分割成一個個小塊。每個定位字元成為兩個元素之間的斷點。這個函數的選擇性參數limit可以用來限制被返回的最大塊數。可以使用許多方法從字串中提取數字。在這裡,我們使用了intval()函數。它可以將一個字串轉化成一個整數。這個轉換是相當智能化的,它可以忽略某些部分,例如標籤就不能轉換成數字。 3.10 執行其他的數組操作 3.10.1 在數組中瀏覽:each()、current()、reset()、end()、next()、pos()和prev()前面已經提到,每個數組都有一個內部指標指向數組中的當前元素。當使用函數each()時,就間接地使用了這個指標,但是也可以直接使用和操作這個指標。如果建立一個新數組,那麼當前指標就將被初始化,並指向數組的第一個元素。調用next()或each()將使指標前移一個元素。調用each($array_name)會在指標前移一個位置之前返回當前元素。next()函數則有些不同——調用next($array_name)是將指標前移,然後再返回新的當前元素。調用end($array_name)可以將指標移到數組末尾。要反向遍曆一個數組,可以使用end()和prev()函數。prev()函數和next()函數相反。它是將當前指標往回移一個位置然後再返回新的當前元素。 3.10.2 對數組的每一個元素應用任何函數:array_walk()array_walk()函數需要三個參數。第一個是arr,也就是需要處理的數組。第二個是func,也就是使用者自訂並將作用於數組中每個元素的函數。第三個參數userdata是可選的,如果使用它,它可以作為一個參數傳遞給我們自己的函數。看一個銷微複雜點的例子:
- function my_multiply(&$value, $key, $factor)
- {
- $value *= $factor;
- }
- array_walk(&$array, 'my_multiply', 3);
複製代碼在這裡,我們定義了一個名為my_multiply()的函數,它可以用所提供的乘法因子去乘以數組中的每個元素。此外,還有一個需要注意的問題是傳遞毿數$value的方式。在my_multiply()的函數定義中,變數前面的地址符(&)意味著$value是按引用方式傳遞的。按引用方式傳遞允許函數修改數組的內容。 3.10.3 統計數組元素個數:count()、sizeof()和array_count_values()count()函數和sizeof()函數具有同樣的用途,都可以返回數組元素的個數。可以得到一個常規標量變數中的元素個數,如果傳遞給這個函數的數組是一個空數組,或者是一個沒有經過設定的變數,返回的數組個數就是0。如 果調用array_count_values($array),這個函數將會統計每個特定的值在數組$array中出現過的次數(這就是數組的基數集)。 這個函數將返回一個包含頻率表的相關數組。這個數組包含數組$array中的所有值,並以這些值作為相關數組的關鍵字。每個關鍵字所對應的數值就是關鍵字 在數組$array中出現的次數。 3.10.4 將數群組轉換成標量變數:extract()對於一個非數字索引數組,而該數組又有許多關鍵字-值對,可以使用函數extract()將它們轉換成一系列的標量變數。函數extract()的作用是通過一個數組建立一系列的標量變數,這些變數的名稱必須是數組中關鍵字的名稱,而變數值則是數組中的值。extract()函數具有兩個選擇性參數:extract_type和prefix。變數extract_type將告訴extract()函數如何處理衝突。有時可能已經存在一個和數組關鍵字同名的變數,該函數的預設操作是覆蓋已有的變數。兩個最常用的選項是EXTR_OVERWRITE(預設值)和EXTR_PREFIX_ALL。當知道會發生特定的衝突並且希望跳過該關鍵字或要給它加上首碼時,可能會用到其他選項。extract()可以提取出一個元素,該元素的關鍵字必須是一個有效變數名稱,這就意味著以數字開始或包含空格的關鍵字將被跳過。 |