使用陣列
陣列是一個可以儲存一組或一系列數值的變數。一個陣列可以有許多個元素。每個元素都有一個值,例如文字、數字或另一個陣列。一個包含其他陣列的陣列稱為多維數組。
什麼是陣列
一個標量變數就是一個用來儲存數值的命名區域。同樣,一個陣列就是一個用來儲存一系列變數值的命名區域,因此,可以使用陣列來組織標量變數。
儲存在陣列中的值稱為陣列元素。每個數組元素有一個相關的索引(也稱為關鍵字),它可以用來存取元素。在大多數程式語言中,數組都有數字索引,而且這些索個通常是從0或1開始的。
數字索引數組
在PHP中,數字索引的預設值是從0開始的,當然也可以改變它。
1. 數字索引數組的初始化
$porducts = array( 'Tires', 'Oil', 'Spark Plugs' );
就像echo語句一樣,array()其實是語言結構,而不是一個函數。
根據對陣列內容的需求不同,可能不需要再像上述範例一樣對它們進行手動的初始化操作。如果所需資料保存在另一個陣列中,可以使用運算子“=”簡單地將陣列複製到另一個陣列。
如果需要將按升序排列的數字保存在一個陣列中,可以使用range()函數自動建立這個陣列。如下這行程式碼將建立一個從1到10的數字數組:$numbers = range(1,10);
range()函數具有一個可選的第三個參數,這個參數允許設定值之間的步驟。例如,如需建立一個1到10之間的奇數數組,可以使用以下程式碼:$odds = range(1,10,2);
range()函數也可以對字元進行操作,如:$letters = range('a', 'z');
2. 存取陣列的內容
要存取一個變數的內容,可以直接使用其名稱。如果該變數是數組,可以使用變數名稱和關鍵字或索引的組合來存取其內容。關鍵字或索引將指定我們要存取的變數。索引在變數名稱後面用方括號括起來。
在預設的情況下,0元素是陣列的第一個元素。
請注意,雖然PHP的字串解析功能非常強大且智能,但是可能會造成混淆。當你將陣列或其他變數嵌入雙引號中的字串時,如果不能正確解釋它們,可以將它們放置在雙引號之外,或者查找第4章的「字串運算與正規表示式」獲得更複雜的語法。
就像PHP的其他變數一樣,陣列不需要預先初始化或建立。在第一次使用它們的時候,它們會自動建立。
3. 使用循環存取數組
由於數組使用有序的數字作為索引,所以使用一個for循環就可以輕鬆顯示數組的內容。
for ($i=0; $i<3; $i++)
echo "$products[$i]";
使用一個簡單的循環就可以存取每個元素是數字索引數組的一個非常好的特性。也可以使用foreach循環,這個循環語句是專門為數組而設計的。如:
foreach ($products as $current)
echo $current. ' ';
使用不同索引的陣列
PHP也支援相關陣列。在相關數組中,可以將每個變數值與任何關鍵字或索引關聯起來。
1 初始化相關陣列
如下所示的程式碼可以建立一個以產品名稱作為關鍵字、以價格作為值的相關陣列:
$prices = array( 'Tires'=>100, ' Oil'=>10, 'Spark Plugs'=>4 );
關鍵字和值之間的符號只是一個大於號與等於符號。
2 存取陣列元素
同樣,可以使用變數名稱和關鍵字來存取陣列的內容。例如$prices['Tires']。
3 使用循環語句
因為相關數組的索引不是數字,因此無法在for循環語句中使用一個簡單的計數器對數組進行操作。但是可以使用foreach迴圈或list()和each()結構。
當使用foreach迴圈語句對相關陣列進行操作時,foreach()迴圈具有不同的結構。可以如下使用關鍵字:
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
";
陣列運算子
+聯合,==等價,===恆等,!=不等價,<>不等價, !==不恆定等。
聯合運算子嘗試將$b中的元素加入$a的末端。如果$b中的元素與$a中的某些元素具有相同的索引,它們將不會被添加。即$a中的元素將不會被覆蓋。
多維數組
數組不一定就是一個關鍵字和值的簡單列表-數組中的每個位置還可以保存另一個數組。使用這種方法,可以建立一個二維數組。可以把二維數組當成矩陣,或是具有寬度和高度或行和列的網路。
陣列排序
1 使用sort()函數
sort()函數是區分字母大小寫的。所有的大家字母都在小寫字母的前面。所以‘A’小於‘Z’,而'Z'小於‘a’。
該 函數的第二個參數是可選的。這個選用參數可以傳遞SORT_REGULAR(預設值)、SORT_NUMERIC或SORT_STRING。指定排序類型 的功能是非常有用的,例如,當要比較可能包含有數字2和12的字串時。從數學角度看,2要小於12,但是作為字串,‘12’卻要小於‘2’。
2 使用asort()函數和ksort()函數對相關陣列排序
函數asort()根據陣列的每個元素值進行排序。 ksort()函數是按關鍵字排序而不是按值排序。
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中,并没有设置数组维数的限制,但人们很难设想一个多于三维的数组。大多数的实际问题在逻辑上只需要使用三维或者更少维的数组结构就可以了。
多维数组的排序
对 多于一维的数组进行排序,或者不按字母和数字的顺序进行排,要复杂得多。PHP知道如何比较两个数字或字符串,但在多维数组中,每个元素都是一个数组。 PHP不知道如何比较两个数组,所以需要建立一个比较它们的方法。在大多数情况下,单词和数字的顺序是显而易见的——但对于复杂的对象,问题就会多一些。
1 用户定义排序
usort()中的“u”代表“user”,因为这个函数要求传入用户定义的比较函数。asort和ksort对应的版本uasort()和uksort()也要求传入用户定义的比较函数。
类似于asort(),当对非数字索引数组的值进行排序时,uasort()才会被使用。如果值是简单的数字或文本则可以使用asort。如果要比较的值像数组一样复杂,可以定义一个比较函数,然后使用uasort()。
类似于ksort(),当对非数字索引数组的关键字进行排序时才使用uksort()。如果值是简单的数字或文本就使用ksort。如果要比较的对象像数组一样复杂,可以定义一个比较函数,然后使用uksort()。
2 反向用户排序
函数sort()、asort()和ksort()都分别对应一个带字母“r”的反向排序函数。用户定义的排序没有反向变体,但可以对一个多维数组进行反向排序。
对数组进行重新排序
1 使用shuffle()函数
在PHP的早期版本中,shuffle()要求调用srand()函数时首先提供一个随机数生成器。如今,这个步骤已经不再需要了。
如果这个函数对你非常重要,可以在程序中应用该函数之前在服务器上测试它。
由于并不需要真正重新排序整个数组,使用array_rand()函数可以实现相同的功能。
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()函数的第三个可选调参数,以相反的顺序创建该数组。
从文件载入数组
使用file()函数将整个文件载入一个数组中。文件中的每行则成为数组中的一个元素。使用了count()函数来统计数组中的元素个数。
explode("\t", $orders[$i])
explode()函数可以将传入的字符串分割成一个个小块。每个制表符成为两个元素之间的断点。这个函数的可选参数limit可以用来限制被返回的最大块数。
可以使用许多方法从字符串中提取数字。在这里,我们使用了intval()函数。它可以将一个字符串转化成一个整数。这个转换是相当智能化的,它可以忽略某些部分,例如标签就不能转换成数字。
执行其他的数组操作
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()函数相反。它是将当前指针往回移一个位置然后再返回新的当前元素。
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 统计数组元素个数:count()、sizeof()和array_count_values()
count()函数和sizeof()函数具有同样的用途,都可以返回数组元素的个数。可以得到一个常规标量变量中的元素个数,如果传递给这个函数的数组是一个空数组,或者是一个没有经过设定的变量,返回的数组个数就是0。
如 果调用array_count_values($array),这个函数将会统计每个特定的值在数组$array中出现过的次数(这就是数组的基数集)。 这个函数将返回一个包含频率表的相关数组。这个数组包含数组$array中的所有值,并以这些值作为相关数组的关键字。每个关键字所对应的数值就是关键字 在数组$array中出现的次数。
4 将数组转换成标量变量:extract()
对于一个非数字索引数组,而该数组又有许多关键字-值对,可以使用函数extract()将它们转换成一系列的标量变量。
函数extract()的作用是通过一个数组创建一系列的标量变量,这些变量的名称必须是数组中关键字的名称,而变量值则是数组中的值。
extract()函数具有两个可选参数:extract_type和prefix。变量extract_type将告诉extract()函数如何处理冲突。有时可能已经存在一个和数组关键字同名的变量,该函数的默认操作是覆盖已有的变量。
两个最常用的选项是EXTR_OVERWRITE(默认值)和EXTR_PREFIX_ALL。当知道会发生特定的冲突并且希望跳过该关键字或要给它加上前缀时,可能会用到其他选项。
extract()可以提取出一个元素,该元素的关键字必须是一个有效的变量名称,这就意味着以数字开始或包含空格的关键字将被跳过。
以上是php數組的使用方式匯總的詳細內容。更多資訊請關注PHP中文網其他相關文章!