php w3c

PHP 程式設計初探 - 上課教材

PHP 程式設計初探 > 課程內容 > 第 05 章 - 陣列的使用

第 05 章 - 陣列的使用

上次更新日期 2020/05/01

我們在前一章稍微談到一點點陣列,同時透過複選的表單來達到互動的效果。事實上,陣列真的很重要!陣列這東西除了一維陣列之外, 還有所謂的二維陣列,多維陣列等等,這些東西都可以影響到我們未來在資料庫的資料處理!因為,從資料庫將資料撈出來之後, 其實,大部分的資料就是一堆陣列!那如何將這些陣列做出有效的結果應用,就是我們應該要知道的事情啊!

學習目標:

  1. 理解陣列的索引以及陣列值的意義
  2. 使用 array() 設定陣列
  3. 學習 foreach 迴圈

5.1: 認識 PHP 陣列

上一章我們談到陣列這個玩意兒,也知道其實陣列很像底下的方程式:

數學方程式:
f(x) = y

f(): 陣列 (array)
x  : 索引 (index)
y  : 值   (value)

PHP 陣列
var[index] = value

上面那個 var 就是一個陣列的變數名稱,而 value 則是某個 index 所對應的值。第四章談到的陣列中, index 我們都是從 0 開始編號, 事實上, index 的變化是很多的!除了可以使數值之外,也能使用文字作為索引喔!相當有趣的!

  • 使用 array() 進行陣列設定

從上一章我們知道陣列的設定可以簡單的使用『 $array[] = 'value' 』來處理,事實上,如果你的資料數量不太大,也能夠簡單的使用底下的方式來處理陣列的設定:

$myarray = array ( 'value1', 'value2', 'value3'...);
例題 5.1-1: 使用 array() 功能建立陣列
  1. 先建立一個新檔案,檔名就稱為 /www/php/unit05-1-1.php,後續將程式碼寫入 body 當中 ;
  2. 檔案最上方需要載入 functions.php 喔!
  3. 建立名為 myweek 的陣列,內容為: Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday 共七個數值
  4. 以表格的方法,將星期以一橫列表格顯示出來!
  5. 最終將程式碼寫入到後面的 pre 當中,以備查驗
  6. 在 /www/php/index.php 加入這個程式的連結
完成的結果會有點像這樣: 使用 array() 設定陣列
  • 索引式 (indexed) 陣列與關聯式 (aoosciative) 陣列

上面的例題是相當單純的陣列設定後呼叫出來的結果,其實跟前一章的資料差不多,我們都是使用整數作為索引 (在中括號內的資料為整數), 然後可以透過簡單的方式來處理後續的迴圈資料。其實還有另外一種陣列的設定方式,那就是將索引值改為字串,那就是所謂的關聯式陣列。 設定的方式也很簡單,透過底下的方式來處理即可:

$myarray['Sunday'] = 'value';

將索引改為需要的關聯文字即可。我們來做個相當相當簡單的設定,將英文轉為中文的表格樣式處理:

例題 5.1-2:關聯式陣列的簡單應用
  1. 將 /www/php/unit05-1-1.php 另存新檔成為 unit05-1-2.php,然後進行修改
  2. 以 $tweek['Sunday'] = '星期一'; 之類的方式設定好 7 個中英文對照表
  3. 以清單的方式,最終列出『 Sunday ( 星期天 ) 』這種對照清單
    • 跟前一題一樣,使用迴圈的方式,準備列出一星期的每一天
    • 增加一個變數,名稱假定為 $mydate,變數內容為 $myweek[] 這樣的樣式
    • 使用 $tweek[$mydate] 這樣的樣式來呼叫出關聯式陣列內容
  4. 最終將程式碼寫入到後面的 pre 當中,以備查驗
  5. 在 /www/php/index.php 加入這個程式的連結
完成的結果會有點像這樣: 關聯式陣列
  • 關聯式陣列的 array() 設定方式

索引為整數類型的索引式陣列設定比較簡單,因為索引是連續的。但是對於關聯式陣列來說,由於索引值為字串,每個都不同! 所以使用 $tweek['Sunday'] = "星期天" 之類的設定方式好像比較簡單。事實上, array 的方式也挺簡單的!使用底下的方式來設定即可:

$tweek = array ( 'Sunday' => '星期天',
	'Monday' => '星期一',
	... );
例題 5.1-3:使用 array 設定關聯式陣列
  1. 將 /www/php/unit05-1-2.php 另存新檔成為 unit05-1-3.php,然後進行修改
  2. 將剛剛的關聯式陣列設定,以 array 的方式取代,然後同樣使用清單的方式直接顯示
  3. 最終將程式碼寫入到後面的 pre 當中,以備查驗
  4. 在 /www/php/index.php 加入這個程式的連結
完成的結果會有點像這樣: 關聯式陣列 array 設定方法
  • foreach 迴圈的應用

你可能會覺得例題 5.1-2 的範例中,能不能有比較簡化的方式來處理,而不要再次透過下一個變數來帶入另一個陣列? 因為, $tweek 裡面就含有中、英文資料啦!那能不能直接將索引值與陣列值直接拿出來展示即可?不需要透過 $i 變數! 是可以的!我們可以透過一個簡易的 foreach 迴圈來處理!這個 foreach 的語法有點像這樣:

foreach ( $array as $varname ) {
	利用 $varname 處理;
	...
}

上面是第一種語法,沒有使用到索引值,只有利用到陣列值,例如底下的簡單範例:

例題 5.1-4:使用 foreach 迴圈
  1. 將 /www/php/unit05-1-3.php 另存新檔成為 unit05-1-4.php,然後進行修改
  2. 在 body 的內容中,將原本的 for 迴圈以 foreach 迴圈取代,且設定一個名為 $weekname 的變數來作為每次迴圈的陣列值內容
  3. 最終將程式碼寫入到後面的 pre 當中,以備查驗
  4. 在 /www/php/index.php 加入這個程式的連結
完成的結果會有點像這樣: 利用 foreach 迴圈

上面的作法是完全不考慮索引值的情況,如果需要有索引值,那就得要使用類似 array() 設定時的樣式,亦即類似如下的語法:

foreach ( $array as $indexname => $varname ) {
	利用 $indexname 與 $varname 處理;
	...
}

現在,讓我們來處理一下相關的任務了!

例題 5.1-5:使用 foreach 迴圈
  1. 將 /www/php/unit05-1-4.php 另存新檔成為 unit05-1-5.php,然後進行修改
  2. 將 foreach 迴圈改成有使用索引值的樣式,增加名為 $myindex 的變數作為索引值。
  3. 最終將程式碼寫入到後面的 pre 當中,以備查驗
  4. 在 /www/php/index.php 加入這個程式的連結
完成的結果會有點像這樣: 利用 foreach 迴圈

透過這個簡單的案例,你就會知道,在不考慮到索引值與陣列資料的相依性,單純只是要列出資訊時,透過 foreach 應該是最好的解決方案! 還不需要考慮陣列的個數呢!相當簡單易用!

  • 計算生日的方式

某些時刻,我們可能會透過網頁網站的資料來取得客戶的生日,並且經由客戶的生日來提供相對的訊息! 比如說成年禮、每個 10 年大關等等。PHP 有個簡單的方式來取得與計算生日喔!簡單的方式如下:

// 設定生日與取得生日的 PHP 日期
$birday = '2011/03/03';
$bday = new DateTime($birday);

// 取得目前時間的 PHP 日期
$nday = new DateTime();

// 計算時間差
$yday = $nday -> diff($bday);

// 取得年、月、日
$yy = $yday -> y;
$mm = $yday -> m;
$dd = $yday -> d;

你得特別注意的是, DateTime() 以及 diff() 都是 PHP 的內建函數,都有特別的呼叫方式,不要惡搞! 其他的變數則你可以自行指定~不過,最後面三行指向年、月、日的用法也需要特別注意一下才好!來做做看底下的案例吧!

例題 5.1-6:計算你輸入的歲數資料
  1. 先建立一個新檔案,檔名就稱為 /www/php/unit05-1-6.php,後續將程式碼寫入 body 當中 ;
  2. 檔案最上方需要載入 functions.php 喔!
  3. 先在 body 裡面設計一個表單,表單的 action 顯示自己 ($_SERVER[xxx]),方法為 post,名稱就為 myform
    1. 先以 date('Y-m-d') 的方法取得目前的時間,並直接顯示到表單內
    2. 建立一個 text 類型的輸入方框,提示使用者以 YYYY-MM-DD 的方式輸入生日,變數名取為 birday
    3. 增加一個送出的按鈕。
  4. 在檔案前面 functions.php 後面新增一個判別式,如果存在 $_REQUEST['birday'] 時,才給予後續的動作
    1. 取得 $birday 的上傳內容
    2. 設定 $bday 為 DateTime($birday) 的內容
    3. 設定 $nday 為目前時間的內容
    4. 設定 $yday 為上面兩個時間的比較 (diff()) 值
  5. 在表單後面新增一串程式,判斷是否存在 $ydate,若存在這個變數,才開始底下的動作:
    1. 以計算年月日的方法,將歲數顯示到網頁上
  6. 最終將程式碼寫入到後面的 pre 當中,以備查驗
  7. 在 /www/php/index.php 加入這個程式的連結
完成的結果會有點像這樣: 顯示生日的年紀

如上所示,就可以得到年紀了!這個資料還挺有用的喔!如果是會員資料,可以每天找出生日者以及依據歲數來推薦商品喔!

5.2: 小小挑戰題

  • 簡單陣列設定

有一個 foreach 的迴圈,迴圈的運作情形有點像底下的圖示,請依據底下的圖示提示,建置出這個網頁的陣列資訊。 需要包含訊息有:

  • 檔名為 unit05-2-1.php
  • 建立名為 $userinfo 的陣列
  • 上述陣列至少擁有 5 個索引值與陣列值
  • 索引值與陣列值依據下圖來建立對應的關係
  • 最終使用下列的方式顯示出來這個網頁。
  • ps. 你可以用簡單的『 $userinfo[...] = 'xxx' 』或者是 array() 的方式來建立,都可以!
利用 foreach 迴圈
  • 由陣列內容顯示會員資料效果

根據上述的設定值資料,再依據 (1)性別的判斷、 (2)生日的判斷等等,設計如下的應答資料:

  • 假設性別設定只有 girl 與 boy 兩種,依據資料判定回應『先生』或『女士』
  • 顯示用戶的生日以及歲數
  • 由 date("m",strtotime(生日的變數)) 取得月份,然後與本月 (date("m")) 比較,若相同,就顯示『歡迎本月壽星!』

完成的資料會有點像底下這樣,當然,內部的訊息需要你自行修改與測試才行。

根據會員資料回應相關訊息

5.3: 多維陣列的設定與使用

上面挑戰題的設計中,大家可能會覺得很蠢~因為只有一個客戶啊~現實社會怎麼可能只有一個客戶!如果只有一個客戶, 那...就無法營運了啊~呵呵!好,所以現在來想一想,如果有很多客戶的話,那麼你該如何設計陣列資料?一般來說, 可能就得要有二維陣列的概念了!

所謂的二維陣列,想起來也是很簡單,就像『 Excel 』電子試算表一樣,有 X 與 Y 軸,兩者有相關的資料~ 以在學校較為常見的成績來說,如下圖所示,就是每個學生的個別成績的意思。

二維陣列的簡單示意圖

這時,如果以第一橫列的學生資料來說, 最簡單的設定方法就是:

$student[0]['u1'] = 0;
$student[0]['u2'] = 0;
$student[0]['u3'] = 0;
$student[0]['u4'] = 67;
....
$student[1]['u1'] = 0;
$student[1]['u2'] = 0;
$student[1]['u3'] = 32;
$student[1]['u4'] = 94;
....

現在你就知道了,二維陣列事實上就是兩個中括號,列出 X 與 Y 軸的內容這樣而已。如果使用 array 的方法來處理,也是可以的! 就是 array 裡面加 array 就是了!也是很有趣的!

$student = array ( array ( 'u1' => 0, 'u2' => 0, 'u3' => 0, 'u4' => 67, ... ),
	array ( 'u1' => 0, 'u2' => 0, 'u3' => 32, 'u4' => 94, ... ),
	....
	)
例題 5.3-1:建立二維陣列與輸出
  1. 先建立一個新檔案,檔名就稱為 /www/php/unit05-3-1.php,後續將程式碼寫入 body 當中 ;
  2. 檔案最上方需要載入 functions.php 喔!
  3. 這個檔案的內容,建立好所需要的陣列資料,假設陣列變數名稱為 $res。
  4. 建立 $stdall 這個變數,內容為針對 $res 進行計數
  5. 建立 $resall 這個變數,內容為針對第一個學生 ($res[0]) 進行計數
  6. 在 body 的地方,以清單的方式,列出陣列 (1)有幾個學生與 (2)每個學生的成績數
  7. 使用雙重迴圈,第一個迴圈以 $i=0 到 $i<$stdall 學生數的方式進行固定迴圈處理
  8. 第二個迴圈則使用簡單的 foreach 功能,將成績依序輸出,且使用 td 的方式將資料包裝起來
  9. 重新處理一下 table 的 style 顯示樣式,讓成績輸出的結果可以比較好看些。
  10. 最終將程式碼寫入到後面的 pre 當中,以備查驗
  11. 在 /www/php/index.php 加入這個程式的連結
完成的結果會有點像這樣: 設定二維陣列與將陣列資料輸出成為表格

這種陣列很常應用在資料庫裡面,PHP 根據資料庫的內容,就可以處理很多顯示的功能!舉例來說,如果用陣列來展示會員資料, 那可以用底下的這個範本處理看看:

例題 5.3-2:建立會員資料的二維陣列
  1. 先建立一個新檔案,檔名就稱為 /www/php/unit05-3-2.php,後續將程式碼寫入 body 當中 ;
  2. 檔案最上方需要載入 functions.php 喔!
  3. 這個檔案的內容,建立好所需要的陣列資料,假設陣列變數名稱為 $userinfo。
  4. 建立 $userall 這個變數,內容為針對 $userinfo 進行計數
  5. 在 body 的地方,以清單的方式列出會員總數
  6. 使用雙重迴圈,第一個迴圈以 $i=0 到 $i<$userall 學生數的方式進行固定迴圈處理
  7. 第二個迴圈則使用簡單的 foreach 功能,將成績依序輸出,且使用 td 的方式將資料包裝起來
  8. 重新處理一下 table 的 style 顯示樣式,讓成績輸出的結果可以比較好看些。
  9. 最終將程式碼寫入到後面的 pre 當中,以備查驗
  10. 在 /www/php/index.php 加入這個程式的連結
完成的結果會有點像這樣: 設定二維陣列與將陣列資料輸出成為表格

如果資料量太大,當然就不可能全部個人資訊都列出來!通常你在網站上面看到的,一開始大概就是會員名稱,然後如果點選會員名稱, 會再進一步處理後續任務。那如何只列出會員名稱 (nick name) 呢?也很簡單,參考底下的範本:

例題 5.3-3:以清單只列出某一個資訊而已
  1. 將 /www/php/unit05-3-2.php 另存新檔成為 /www/php/unit05-3-3.php,後續將程式碼寫入 body 當中 ;
  2. 檔案最上方需要載入 functions.php 喔!
  3. 建立 $userall 這個變數,內容為針對 $userinfo 進行計數
  4. 在 body 的地方,只保留外層迴圈,而且設定一個變數名為 $username,該名稱為 $userinfo[$i]['nick'] 的結果。
  5. 輸出時,將 $i 的變數帶入成為超連結資料,預計會讓使用者點選 (下題作法)
  6. 最終將程式碼寫入到後面的 pre 當中,以備查驗
  7. 在 /www/php/index.php 加入這個程式的連結
完成的結果會有點像這樣: 設定二維陣列與將陣列資料輸出成為表格

此時系統準備要可以處理用戶的資訊了。接下來,以 form 的方式,將使用者的資訊填入到 input 的表單中,有點模仿修改的方式, 不過我們這裡只做外型,不做修改!畢竟還沒有真的資料庫系統。接下來就來玩一玩:

例題 5.3-4:以使用者上傳的變數,去處理會員資訊的更新
  1. 將 /www/php/unit05-3-3.php 另存新檔成為 /www/php/unit05-3-4.php,後續將程式碼寫入 body 當中 ;
  2. 檔案最上方需要載入 functions.php 喔!
  3. 在陣列的設定之後,判斷是否有 $_REQUEST['user'] 的存在,若有,就進行底下的資料:
    • 設定 $user 變數,內容為 $_REQUEST['user']
    • 分別設定 $account, $username, $birthday, $gender, $tel, $addr 等變數,內容分別對應到 $userinfo[$user]['這裡']
  4. 在 body 的地方,在使用者列表的上方,處理底下的功能:
    • 如果存在 $user 時,就進行所有的 echo 功能
    • 顯示 form、顯示『會員帳號』,顯示『會員名稱』,且將會員名稱放置到 input 當中!依序處理各項變數!
  5. 最終將程式碼寫入到後面的 pre 當中,以備查驗
  6. 在 /www/php/index.php 加入這個程式的連結
完成的結果會有點像這樣: 設定二維陣列與將陣列資料輸出成為表格