Form

Form with PHP

2019/09/23 (更新內容)
2023/10/08 (將作業改為應用範例)

PHP的輸入

介紹PHP的時候,大家一定很納悶,怎麼沒有提到輸入? 原因是,PHP本來就是為了web,所以,輸入就是要搭配html form了。

這是一個html form,當按鈕被按下時,因為method為post,所以,會以http post的方式呼叫action所指定的程式(welcome.php)。

Input / Text

welcome.html (詳參: PHP 7 Form Handling)

<html>

<body>


<form action="welcome.php" method="post">

Name: <input type="text" name="name"><br>

E-mail: <input type="text" name="email"><br>

<input type="submit">

</form>


</body>

</html>

$_POST

php利用$_POST來處理form送過來的資料。

welcome.php

<html>

<body>


Welcome <?php echo $_POST["name"]; ?><br>

Your email address is: <?php echo $_POST["email"]; ?>


</body>

</html>

$_GET

PHP Global Variables - Superglobals / $_GET 

在URI後面還可以接一個查詢 (query),並以「?」隔開,如:「http://www.fju.edu.tw/sitemap.jsp?choice=0」,這個網頁利用查詢來決定不同角色看到的網站地圖,如:「http://www.fju.edu.tw/sitemap.jsp?choice=1」、「http://www.fju.edu.tw/sitemap.jsp?choice=2」。

例如:利用url傳遞變數subject

test_get.php?subject=PHP

如果查詢需要兩個以上的變數,可以使用「&」隔開,如:「http://www.fju.edu.tw/focusDetail.jsp?focusID=713&focusClassID=1」。

例如:傳遞兩個變數subject及web

test_get.php?subject=PHP&web=W3schools.com

test_get.html 

<html>

<body>


<a href="test_get.php?subject=PHP&web=W3schools.com">Test $GET</a>


</body>

</html>

test_get.php

<html>

<body>


<?php

echo "Study " . $_GET['subject'] . " at " . $_GET['web'];

?>


</body>

</html>

應用範例

試試看怎麼寫一個陽春的登入系統

上週利用javascript進行驗證,那樣的驗證其實是不好的,因為使用者是可以看到javascript的內容,就可以看到帳號及密碼,所以,安全作法是由後端php程式檢查,我們來試著利用php檢查,當帳號輸入root、密碼輸入password,就顯示登入成功,否則就顯示登入失敗。

login.php

<html>

<head>

    <meta charset="utf-8">

</head>

<body>


<form action="login_process.php" method="post">

帳號: <input type="text" name="account"><br>

密碼: <input type="password" name="password"><br>

<input type="submit" value="登入">

</form>


</body>

</html>

login_process.php 

if裡的條件會是?

<?php

if ( ) {

    echo "登入成功";

}

else {

    echo "登入失敗";

}

?>

跳轉頁面

<?php

//檢查是否取得POST內容

$account = $_POST['account'] ?? ["N/A"];

$password = $_POST['password'] ?? ["N/A"];


if ($account==="root" && $password==="password" ) {

  header("Location: success.php");

}

else {

  header("Location: login.php");

}

?>

success.php

<html>


<body>

  <h1>成功登入</h1>

</body>


</html>

login_process.php

<?php

//檢查是否取得POST內容

$account = $_POST['account'] ?? ["N/A"];

$password = $_POST['password'] ?? ["N/A"];


if ($account==="root" && $password==="password" ) {

  header("Location: success.php");

}

else {

  header("Location: login.php?msg=Error");

}

?>

login.php

<?php

$msg = $_GET["msg"]??"";

?>

<html>

<head>

    <meta charset="utf-8">

</head>

<body>


<form action="login_process.php" method="post">

帳號: <input type="text" name="account"><br>

密碼: <input type="password" name="password"><br>

<input type="submit" value="登入">

<?=$msg?>

</form>


</body>

</html>

為了讓大家容易理解,目前我們的寫法都是將畫面呈現跟處理邏輯分成兩個檔案,這樣的寫法雖然邏輯比較清楚,但是,當我們的系統越長越大,檔案數量就會太多,所以,一般比較熟練的開發者都會將兩個部分結合在一起,但也因為放在一起,就必須考慮到第一次呼叫這頁面時$_POST是不存在的。很多初學者會忘了這件事,導致第一次登入就出現錯誤訊息。

login.php

<?php

$msg = $_GET["msg"]??"";

//檢查是否取得POST內容

if ($_POST){ //如果POST有內容,進行以下的登入檢查

  if ($_POST['account']==="root" && $_POST['password']==="password" ) {

    header("Location: success.php");

  }

  else {

    header("Location: login.php?msg=Error");

  }

}

?>

<html>

<head>

    <meta charset="utf-8">

</head>

<body>


<form action="login.php" method="post">

  帳號: <input type="text" name="account"><br>

  密碼: <input type="password" name="password"><br>

  <input type="submit" value="登入">

  <?=$msg?>

</form>


</body>

</html>


Input / Checkbox

當輸入時,要讓使用者可以有多重狀態時,可以將多個checkbox都命名為status[],這樣就會把選擇內容當作陣列傳給php。

<!DOCTYPE html>

<html>


<body>


  <form action="status.php" method="post">


  name:<input type="text" name="name" />

  <input type="checkbox" name="status[]" value="faculty" checked="checked" /> Faculty

  <input type="checkbox" name="status[]" value="student" /> Student<br/>

  <input type="checkbox" name="dinner" value="dinner" checked="checked" /> Dinner needed

  

  <input type="submit" value="Submit" />


 </form>


</body>


</html>

當使用者選擇任何一個選項或兩個選項,勾選的內容就會儲存在status陣列,可以利用foreach去檢查使用勾選的項目,為了避免使用者未勾選任何項目,要在php裡檢查並且給個空值。

status.php

<?php

echo $_POST["name"],"<br/>";

echo "Status:<br/>";


//new syntax in php 7

$statuslist = $_POST["status"]?? ["N/A"];


foreach( $statuslist as $status ) {

  echo "$status <br/>";

}


$dinner = $_POST["dinner"]?? "";

echo "$dinner <br/>";


?>

Array

如果我們會根據參加者的需求去計算費用

<!DOCTYPE html>

<html>


<head>

  <meta charset="utf-8">

</head>


<body>


 <form action="conference_process.php" method="post">


  name:<input type="text" name="name" /><br/>

  <input type="checkbox" name="program[]" value="1" checked="checked" /> 上午場 ($150)

  <input type="checkbox" name="program[]" value="2" /> 下午場 ($100) <br />

  <input type="checkbox" name="program[]" value="3" checked="checked" /> 午餐 ($60)

  <input type="submit" value="Submit" />


 </form>


</body>


</html>

利用array

conference_process.php

<?php


$program_price = array(0, 150, 100, 60);


//new syntax in php 7

$programlist = $_POST["program"]?? [0];

$price = 0;

foreach( $programlist as $program ) {

  

 $price += $program_price[$program];


}


  echo $_POST["name"].",您要繳交".$price." 元 <br/>";

?>

同樣效果,但利用php的associative array

<!DOCTYPE html>

<html>


<head>

  <meta charset="utf-8">

</head>


<body>


 <form action="conference_process.php" method="post">


  name:<input type="text" name="name" /><br/>

  <input type="checkbox" name="program[]" value="am" checked="checked" /> 上午場 ($150)

  <input type="checkbox" name="program[]" value="pm" /> 下午場 ($100) <br />

  <input type="checkbox" name="program[]" value="lunch" checked="checked" /> 午餐 ($60)

  <input type="submit" value="Submit" />


 </form>


</body>


</html>

conference_process.php

<?php


$program_price = array( "am"=>150, "pm"=>100, "lunch"=>60, "N/A"=>0);



//new syntax in php 7

$programlist = $_POST["program"]?? ["N/A"];

$price = 0;

foreach( $programlist as $program ) {

  $price += $program_price[$program];


}


  echo $_POST["name"].",您要繳交".$price." 元 <br/>";

?>

應用範例

login.php

<?php

$accountList = array( "student1"=>"1", "student2"=>"2", "student3"=>"3");

$msg = $_GET["msg"]??"";

//檢查是否取得POST內容

if ($_POST){ //如果POST有內容,進行以下的登入檢查

  $account = $_POST["account"]??"";

  $password = $_POST["password"]??"";

  if (isset($accountList[$account]) && $password == $accountList[$account] ) {

    header("Location: success.php");

  }

  else {

    header("Location: login.php?msg=Error");

  }

}

?>

<html>


<head>

  <meta charset="utf-8">

</head>


<body>


  <form action="login.php" method="post">

    帳號: <input type="text" name="account"><br>

    密碼: <input type="password" name="password"><br>

    <input type="submit" value="登入">

    <?=$msg?>

  </form>

</body>


</html>

$program_price = array(

  array(2000, 0, 0, 3000),

  array(0, 300, 150, 5500)

);

取得資料的方式:

$price = $program_price[0][3];

fee.php

<html>


<body>

  <form action="fee_process.php" method="post">

    <div>

      會費:

      <input type="radio" name="membershipFee" value=0 /> 繳交

      <input type="radio" name="membershipFee" value=1 /> 不繳交

    </div>

    <div>

      活動:

      <input type="checkbox" name="program[]" value=0 /> 一日資管營

      <input type="checkbox" name="program[]" value=1 /> 迎新茶會

      <input type="checkbox" name="program[]" value=2 /> 迎新宿營

    </div>

    <input type="submit" value="確定" />


  </form>

</body>


</html>

fee_process.php

<?php

$program_price = array(

  array(2000, 0, 0, 3000),

  array(0, 300, 150, 5500)

);

$price = 0;

//檢查是否取得POST內容

if ($_POST){ //如果POST有內容,進行以下的登入檢查

  $membershipFee = $_POST["membershipFee"]??1;

  $programs = $_POST["program"]??[];

  $price += $program_price[$membershipFee][0];

  foreach ($programs as $program){

    $price += $program_price[$membershipFee][$program+1];

  }

}

?>

<html>


<body>

  費用:<?=$price?>

  <a href="fee.php"><button>重新計算</button></a>

</body>


</html>

參考資料