PHP Introduction
下載
XAMPP ,完成後打開XAMPP Control Panel,點選右上角config,將Editor換成Nodepad++。
點選XAMPP Control Panel中Apache之start,可在下方狀態列看到Status change detected:running。接下來到C:\xampp\htdocs建立一個新資料夾(e.g. WorkSpace),然後在NotePad++開啟新檔案,輸入程式碼。
hello.php
<?php
echo "Hello, World" ;
?>
儲存到C:\xampp\htdocs\WorkSpace,命名為hello.php。打開瀏覽器到http://localhost/WorkSpace/hello.php,看是否出現結果,顯示Hello, World表示安裝測試成功。
程式最終要放置在一個主機,我們也可以申請一個主機帳號來使用及測試。主機帳號大部分都要收費,不過還是有少部分免費的可以使用,例如:
Byethost 或是
InfinityFree ,嘗試申請了一個
Byethost的帳號 ,先在自己電腦使用XAMPP測試及練習,然後在上傳到主機看效果。
Syntax
從例子hello.php可以看出php的語法介於
<?php 及
?> 兩個符號之間。HTML的內容可以直接嵌入到php檔案之內。
php1_1.php
<head>
<title>php1_1.php</title>
</head>
<body>
<h1><?php
echo "Hello, php." ;
?> </h1>
</body>
使用//跟# 做單行註解,使用/*comment*/ 做多行註解。
Variables
在PHP中使用變數與JavaScript類似,屬於弱型別程式語言(Loosely Typed Language),亦即宣告變數時不需要宣告變數型態,宣告時使用$號代表變數。
php1_2_variable.php
<head>
<title>php1_2_variable.php</title>
</head>
<body>
<h1><?php
$rank = 100 ;
echo "獵人等級<span style='color:blue;'>" ;
echo $rank;
echo "</span>級" ;
?> </h1>
</body>
echo亦可使用print替代,原則上效果是一樣的,不過echo比較快一點因為它沒有傳回值,print會傳回1。
Constant
在PHP中常數的宣告使用define()函數,或是使用const。
php1_2_variable.php
<head>
<title>php1_2_constant.php</title>
</head>
<body>
<h1>
<?php
define("PI" ,"3.14159" );
const E = 2.72 ;
print "圓周率大約等於<span style='color:blue;'>" .PI."</span>......" ;
echo "自然底數E約等於<span style=\"color:red;\">" .E."</span>......" ;
?>
</h1>
</body>
Data Type
變數型態原則上可分:
Integer: 1, -1, 0, 0b111, 0xfff, ...
Float: 3.14, 1.2e5, 3e-5
String: 'Hi', "Hello"
Boolean: true, false
Array: array(1,2,3)
Object: class OX{}
NULL: NULL
Resources: fopen("abc.txt","r")
php1_3_datatype.php
<head>
<title>php1_3_datatype.php</title>
</head>
<body>
<?php
$i = 0b111 ;
var_dump($i);
echo "<br>" ;
$s = "批A去批" ;
var_dump($s);
echo "<br>" ;
$f = 3.3e3 ;
var_dump($f);
echo "<br>" ;
$b = true ;
var_dump($b);
echo "<br>" ;
$a = array (1 ,2 ,3 );
var_dump($a);
echo "<br>" ;
class Hunter {
public $level = 10 ;
}
$o = new Hunter;
var_dump($o);
echo "<br>" ;
$n = "hi" ;
$n = null ;
var_dump($n);
echo "<br>" ;
$r = fopen("hello.php" , "r" );
var_dump($r);
echo "<br>" ;
?>
</body>
傳值與傳址
跟其他語言(e.g. c)類似,指派變數可以有傳值與傳址兩個形式,傳址的時候,在PHP中,只要加上&符號即可。例如:
<?php
$s1 = "Hello<br>" ;
$s2 = & $s1;
echo $s2;
$s2 = "hi<br>" ;
echo $s1;
?>
函數傳址:
<?php
function fun (&$x) {
$x = $x*2 ;
}
$a = 10 ;
fun($a);
echo $a;
?>
物件變數用法也是傳值,不過實際上傳的是指位(pointer),並非本身資料。
<?php
class One {
public $v = 1 ;
public function __toString () {
return "value = {$this->v}<br>" ;
}
}
function Value ($obj) {
$obj->v = 2 ;
$obj = new One();
echo $obj;
}
$one = new One();
Value($one);
echo $one;
?>
若是傳入的是物件本身而非僅是pointer:
<?php
class One {
public $v = 0 ;
public function __construct ($v) {
$this ->v = $v;
}
public function __destruct () {
echo __CLASS__ ." was destroyed.<br>" ;
}
public function __toString () {
return "value = {$this->v}<br>" ;
}
}
function Value (&$obj) {
$obj->v = 2 ;
echo $obj;
$obj = new One(3 );
echo $obj;
}
$obj = new One(1 );
echo $obj;
Value($obj);
echo $obj;
?>
Flow Control
跟其他語言一樣可用
if...else
switch
loops: while, do...while, for, foreach
等作流程控制,此處先介紹計算子(Operators)。
Operators
Arithmetic Operators: +, -, *, /, %
Assignment Operators: =, +=, -=, *=, /=, %=
Comparison Operators: ==, ===(identical), !=, <>(not equal, same to !=), !==, <, >, >=, <=
Incrementing & Decrementing: ++, --
Logical Operators: and, or, xor, &&, ||, !
String Operators: ., .=
Spaceship Operator: x <=> y(return 0 if x==y, 1 if x > y, -1 if x < y)
php2_1_operator.php
<head>
<title>php2_1_operator.php</title>
</head>
<body>
<?php
$x = 0b1111 ;
$y = 0x2f ;
$z = 0 ;
$s1 = "abc" ;
$s2 = "xyz" ;
echo ($x+$y)."<br>" .($x-$y)."<br>" .($x*$y)."<br>" .($x/$y)."<br>" .($x%$y)."<br>" ;
$z = $x;
$z += $y;
echo "z = " .$z."<br>" ;
echo ("x==y returns " );var_dump($x==$y);
echo "<br>z++=" .$z++."\t,++z=" .++$z."<br>" ;
var_dump ($x<$y)xor ($x!=$y);
echo "<br>" .$s1.=$s2."<br>" ;
echo $s1<=>$s2;
?>
</body>
使用.連結字串與變數,使用var_dump顯示變數型態,使用<=>比較大小。
if...else...
php2_2_ifelse.php
<?php
$m = 0b1101011 ;
$n = 0xaa ;
if ($m > $n){
echo "<b>$m</b>大於<i>$n</i>" ;
}else if ($m < $n){
echo "<b>$m</b>小於<i>$n</i>" ;
}else {
echo "<b>$m</b>等於<i>$n</i>" ;
}
echo ($m > $n)?"<br><b>$m</b>大於$n" :"<br><b>$m</b>小於$n" ;
?>
在字串內使用變數,若是變數在字串的一開頭,會出現錯誤訊息,加上<b>使其不是字串開頭就沒有錯誤。
switch
php2_2_switch.php
<?php
$w = 55 ;
$h = 1.65 ;
$bmi = $w/$h/$h;
switch ($bmi){
case $bmi<18.5 :
echo "Too Thin" ;
break ;
case $bmi>=18.5 && $bmi <22.5 :
echo "Good shape" ;
break ;
case $bmi >=22.5 && $bmi <26.5 :
echo "Over-weighted" ;
break ;
default :
echo "Obese" ;
}
?>
while
php2_3_while.php
<?php
$i = 0 ;
$sum = 0 ;
while ($i <= 20 ){
$i++;
if ($i>10 )
break ;
if ($i%2 )
continue ;
echo $i."<br>" ;
$sum=$sum+$i;
}
echo "sum = $sum<br>" ;
do {
echo $i;
}while ($i<0 );
?>
可以在loop內使用break與continue。
for
php2_3_for.php
<?php
echo "<center>" ;
for ($i = 1 ; $i <= 50 ; $i++){
for ($j = 0 ; $j < $i; $j++){
echo "*" ;
}
echo "<br>" ;
}
echo "</center>" ;
?>
foreach
見
Array
Function
使用關鍵字function建立函數。
php2_4_function.php
<?php
function sayHello () {
echo "Hello" ;
}
function add ($x, $y) {
return $x+$y;
}
sayHello();
echo ("<br>" .add(10 , 20 ));
function sale ($size, $price = 100 ) {
echo "<p>T-shirt #$size is $$price dollars.</p>" ;
}
sale(10 );
sale(12 , 200 );
function square (&$x) {
$x *= $x;
return $x;
}
$a = 10 ;
square($a);
echo $a;
?>
若函數參數有初始值,呼叫時沒有給值則使用初始值(e.g. sale())。
若函數傳回輸入參數(e.g. square),且輸入參數使用&符號,則之後呼叫時輸入之參數之值也會變成傳回值(by value and by reference)。
Arrow Functions
Arrow function讓我們使用一行建立函數。
<?php
$y = 10 ;
$f1 = fn($x) => $x*$y;
var_export($f1(9 ));
echo PHP_EOL;
$sq1 = function ($x) use ($y) {
return $x*$y;
};
echo $sq1(5 )."<br>" ;
$z = 10 ;
$fn1 = fn($x) => fn($y) => $x*$y*$z;
echo $fn1(10 )(5 ), PHP_EOL;
?>
這類的函數可以讓我們方便將函數作為輸入值。例如原本要排序陣列使用如下方式:
<?php
function compare ($x, $y) {
return $x > $y;
}
$arr = array ("Tom" , "Mary" , "Jenny" , "John" , "Alex" , "Helen" );
usort($arr, 'compare' );
print_r ($arr);
?>
現在可以使用arrow function來完成。
<?php
$arr = array ("Tom" , "Mary" , "Jenny" , "John" , "Alex" , "Helen" , "Sam" , "Mia" );
usort($arr, fn($x, $y)=>$x>$y);
print_r ($arr);
?>
Variable Scope
<?php
$x = 100 ;
function scope () {
echo $x;
}
scope();
?>
這個函數是錯誤的因為$x的宣告不在函數範圍內。若要使變數成為global variable,需使用global關鍵字。
php2_4_scope.php
<?php
$x = 100 ;
function scope () {
global $x;
echo $x;
}
scope();
$x = 200 ;
scope();
?>
recursive function
php2_5_recursive.php
<?php
function fibonacci ($n) {
if ($n == 0 )
return 0 ;
if ($n == 1 )
return 1 ;
return fibonacci($n-1 ) + fibonacci($n-2 );
}
for ($i=1 ; $i<20 ; $i++){
echo fibonacci($i)."<br>" ;
}
?>
Type Declarations
自PHP 5開始加入argument type declarations,允許指定函數參數的型態。
若是無法符合需要的變數型態,將會回傳fatal error。例如:
<?php
function wee ($s) {
foreach ($s as $v){
echo $v, " " ;
}
};
wee(array (1 ,3 ,5 ,7 ,9 ,11 ,13 ,17 ,19 ,21 ,23 ,25 ));
wee("13579" )
?>
callable: 始於PHP5.4。輸入函數須為callable,或是物件。如下例,就是將callable函數作用到$data上。
<?php
function call (callable $callback, $data) {
$callback($data);
}
$wee = function ($s) {
$sum = 0 ;
foreach ($s as $v){
$sum += $v;
}
echo $sum;
};
call($wee, array (1 ,2 ,3 ,4 ,5 ));
?>
變數型態(bool, int, float, string):始於PHP 7,如下例。[]是空陣列,其餘可視為bool。
<?php
function isTrue (bool $b) {
if ($b){
echo 'true' ;
}else {
echo 'false' ;
}
}
isTrue(true );
isTrue(1 );
isTrue('false' );
isTrue([]);
?>
上例中輸入int(1)、string('false')都可正常運行,那是因為這兩者可轉換成bool,不過這不夠嚴謹,若是要嚴格執行型態檢查(strong type checking),可以加入declare(strict_types=1); 這行。如下:
<?php
declare (strict_types=1 );
function isTrue (bool $b) {
if ($b){
echo 'true' ;
}else {
echo 'false' ;
}
}
isTrue(true );
isTrue(1 );
isTrue('false' );
isTrue([]);
?>
除了輸入參數之外,也可以指定傳回值的型態。
指定傳回型態(使用:符號),如下例,若將結果cast成為array,傳回錯誤。(若是cast成為int, string, bool則都是可行的。)
<?php
function circle (float $r) : float {
return (pi()*$r*$r);
}
echo circle(10 );
?>
若將上例之傳回型態修改為void,也會造成錯誤,此時不需傳回,可使用echo來顯示結果。
PHP7.1後,可以handle當輸入參數為null的情況,只要在之前加上問號(?)即可。如下例:
<?php
declare (strict_types=1 );
function nullok (?int $num) {
echo $num === null ? 'null<br>' :$num;
}
nullok(null );
nullok(10 );
?>
PHP8之後還可以接受一個變數包含超過一個型態的參數。如下例,若是只有int型態,參數為float將傳回錯誤。
<?php
declare (strict_types=1 );
function circle (int|float $r) {
echo pi()*$r*$r, '<br>' ;
}
circle(10 );
circle(10.5 );
?>
現在class內的變數也可以直接指定變數型態。若是沒有給定型態以及初始值的變數,預設內容則為null。
<?php
declare (strict_types=1 );
class AClass {
public int $age;
public function __construct ($a) {
$this ->age = $a;
}
public function __destruct () {
echo __CLASS__ ." was destroyed.<br>" ;
}
}
$ac = new AClass(18 );
echo $ac->age.'<br>' ;
$ac->age = 20 ;
echo $ac->age.'<br>' ;
$ac->age = 20.5 ;
echo $ac->age.'<br>' ;
?>
使用settype()來cast或直接cast以改變變數型態。
<?php
$var = 3.14 ;
settype($var, 'int' );
echo $var."<br>" ;
$var = (bool)$var;
echo $var."<br>" ;
?>
使用gettype()來取得變數型態。
<?php
$var = 3.14 ;
echo gettype($var)."<br>" ;
var_dump($var);
echo "<br>" ;
var_export($var);
?>
判斷變數型態
可以使用以下方法來判斷變數是否為某型態。
is_array()
is_bool()
is_callable(): can it be called as a function?
is_float(), is_double(): is a float?
is_real, is_int(), is_integer(), is_long(): is an integer?
is_null()
is_numeric(): is a number or numeric string?
is_scalar(): is an int, float, stirng, or bool?
is_object()
is_resource()
is_string()
<?php
$var = 3.14 ;
echo is_float($var)? "yes<br>" :"no<br>" ;
echo is_bool($var)? "yes<br>" :"no<br>" ;
echo is_numeric($var)? "yes<br>" :"no<br>" ;
echo is_scalar($var)? "yes<br>" :"no<br>" ;
echo is_int($var)? "yes<br>" :"no<br>" ;
echo is_object($var)? "yes<br>" :"no<br>" ;
?>
BIF
內建函數(Built-in Functions)可讓我們直接使用。擇要介紹:
Math
Array
String
Date/Time
Math
詳細列表可見
這裡 。
php3_1_math.php
<?php
echo "絕對值:" .abs(-M_PI)."<br>" ;
echo "天花板:" .ceil(pi())."<br>" ;
echo "地板:" .floor(M_PI)."<br>" ;
echo "根號:" .sqrt(pi())."<br>" ;
echo "亂數:" .rand(1 ,100 )." max:" .getrandmax()."<br>" ;
echo "對數底e:" .log(exp(5 ))."<br>" ;
echo "對數底10:" .log10(1e5 )."<br>" ;
echo "次方:" .pow(2 ,10 )."<br>" ;
echo "10->2:" .decbin(100 )."<br>" ;
echo "2->10:" .bindec(11111 )."<br>" ;
echo "10->8:" .decoct(11111 )."<br>" ;
echo "8->10:" .octdec('11111' )."<br>" ;
echo "10->16:" .dechex(11111 )."<br>" ;
echo "16->10:" .hexdec('11111' )."<br>" ;
echo "任意進位轉換:" .base_convert('f' , 16 , 8 )."<br>" ;
?>
pi()與M_PI都可得到π,exp(n)可得e的n次方=>exp(1)=E。
getrandmax()會得到可能出現的最大亂數,跟電腦位元有關。
Array
Array的宣告方式可以使用array()函數,或是直接手動指派,index由0開始,index也可以不是指派的數字(類似python的dictionary)。
php3_2_array.php
<?php
$a1 = array (1 ,2 ,3 ,4 ,5 );
$a2[0 ] = "#ff0000" ;
$a2[1 ] = "#00ff00" ;
$a2[2 ] = "#0000ff" ;
$a3 = array ("one" =>1 , "two" =>2 , "three" =>3 );
$a4 = array (10 =>"ten" , 20 =>"twenty" , 30 =>"thirty" );
$a5 = array (
array ("one" =>1 ,"two" =>2 ,"three" =>3 ),
array ("four" =>4 ,"five" =>5 ,"six" =>6 ),
array ("seven" =>7 ,"eight" =>8 ,"nine" =>9 )
);
echo $a1[2 ]."<br>" .$a2[2 ]."<br>" .$a3["two" ]."<br>" .$a4[20 ]."<br>" .$a5[1 ]["five" ]."<br>" ;
var_dump($a4);
echo "<br>" ;
print_r($a4);
?>
使用=>符號來連結index與value。
$a5是Multidimensional,使用兩個變數描述。
var_dump()與print_r()皆可印出array內容,var_dump()資料多一些。
foreach
php3_2_foreach.php
<?php
$season = array ("spring" , "summer" , "autumn" , "winter" );
$weekday = array (1 =>"Mon" , 2 =>"Tue" , 3 =>"Wed" , 4 =>"Thur" , 5 =>"Fri" , 6 =>"Sat" , 7 =>"Sun" ,);
foreach ($season as $value){
echo $value . "<br>" ;
}
foreach ($weekday as $key=>$value){
echo $key."=>" .$value."<br>" ;
}
?>
除了使用foreach,尚可使用以下方式traverse array。
php3_2_traversal.php
<?php
list ($x,$y,$z)=array (1 ,2 ,3 );
echo $x." " .$y." " .$z."<br>" ;
$season = array ("spring" , "summer" , "autumn" , "winter" );
$weekday = array (1 =>"Mon" , 2 =>"Tue" , 3 =>"Wed" , 4 =>"Thur" , 5 =>"Fri" , 6 =>"Sat" , 7 =>"Sun" ,);
for ($i = 0 ; $i < count($season); $i++){
echo $season[$i]."<br>" ;
}
shuffle($weekday);
print_r($weekday);
echo ("<br>-------------------<br>" );
reset($weekday);
while (list ($key, $value)= each($weekday)){
echo "$key => $value<br>" ;
}
echo ("<br>-------------------<br>" );
reset($weekday);
while ($value = current($weekday)){
echo "$value<<=>>" .key($weekday)."<br>" ;
next($weekday);
}
?>
count()與sizeof()都是傳回array長度。
shuffle()是洗牌。
reset()是將pointer指向array的最初位置,這樣才能從頭開始traverse。若是end()則將pointer指向最後一個位置。
current()傳回目前指標指向的物件內容,也可使用pos()。
next()指將指標往後移一位,若是prev()則往前移一位,。
list()的意思是將array內的值對應指派給list內的變數,e.g. list($x, $y, $z)=array(1,2,3)。
each()的意思是逐一傳回array內的key跟value。
key()是傳回目前指標所指物件之key。
operators
可使用於兩個array間的operators:
php3_2_arrayOperators.php
<?php
$fruit = array ("a" =>"apple" , "b" =>"banana" , "p" =>"pear" );
$number = array (1 ,2 ,3 );
$season = array ("spring" , "summer" , "autumn" , "winter" );
$weekday = array (1 =>"Mon" , 2 =>"Tue" , 3 =>"Wed" , 4 =>"Thur" , 5 =>"Fri" , 6 =>"Sat" , 7 =>"Sun" ,);
$month = array (1 =>"Jan" , 2 =>"Feb" , 3 =>"Mar" );
$ns = $number + $season;
$fw = $fruit + $weekday;
$sw = $season + $weekday;
$wm = $weekday + $month;
foreach ($ns as $key=>$value){
echo $key."=>" .$value."<br>" ;
}
echo "<br>----------------------<br>" ;
foreach ($fw as $key=>$value){
echo $key."=>" .$value."<br>" ;
}
echo "<br>----------------------<br>" ;
foreach ($sw as $key=>$value){
echo $key."=>" .$value."<br>" ;
}
echo "<br>----------------------<br>" ;
foreach ($wm as $key=>$value){
echo $key."=>" .$value."<br>" ;
}
var_dump($number==$month);
var_dump($number===$month);
var_dump($number!=$month);
var_dump($number<>$month);
var_dump($number!==$month);
?>
+是聯集(union)而不是相加,以前一個為主,如果兩個array使用相同index,則先取前一個array的內容,若後一個array長度較長,才再加上後面的內容。
Sorting
php3_2_arraySorting.php
<?php
$fruit1 = array ("5" =>"waterlemon" , "2" =>"apple" , "1" =>"mango" , "4" =>"banana" , "3" =>"pear" );
$fruit2 = array ("5" =>"waterlemon" , "2" =>"apple" , "1" =>"mango" , "4" =>"banana" , "3" =>"pear" );
$fruit3 = array ("5" =>"waterlemon" , "2" =>"apple" , "1" =>"mango" , "4" =>"banana" , "3" =>"pear" );
for ($i = 0 ; $i<10 ; $i++){
$number[$i] = rand(1 ,100 );
}
print_r($number);
echo ("<br>----------------<br>" );
sort($number);
print_r($number);
echo ("<br>----------------<br>" );
sort($fruit1);
print_r($fruit1);
echo ("<br>----------------<br>" );
ksort($fruit2);
print_r($fruit2);
echo ("<br>----------------<br>" );
asort($fruit3);
print_r($fruit3);
echo ("<br>----------------<br>" );
arsort($fruit3);
print_r($fruit3);
?>
sort會針對值(value)排序,排序後重新指派index(從0開始)。
asort會針對值(value)排序,排序後index保持不變。
ksort會針對key(index)排序。
rsort、arsort、krsort排序後降冪排列(由大到小),sort、asort、ksort則為升冪排列(由小到大)。
php3_2_arraySortingFunction.php
<?php
$fruit = array ("5" =>"waterlemon" , "2" =>"apple" , "1" =>"mango" , "4" =>"banana" , "3" =>"pear" );
function cmp ($a, $b) {
return $a<=>$b;
}
uasort($fruit, 'cmp' );
print_r($fruit);
?>
usort, uasort, uksort三者是根據自定義函數進行排序,可以用在物件的排序。
Array_walk
將自訂函數逐一應用到Array內的元素。
php3_2_arrayWalk.php
<?php
foreach (range(1 ,10 ,1 ) as $n){
$numbers[$n] = $n;
}
function square (&$x) {
$x *= $x;
}
array_walk($numbers, 'square' );
print_r($numbers);
echo ("<br>" );
foreach (range('z' ,'a' ,-2 ) as $w){
echo $w."<br>" ;
}
?>
range(a,b,c)表示產生介於a<=x<=b每c間隔的x(也可以是字母)。
&的用法見Function 。
更多關於array的函數請見
官網 。
String
php3_3_string.php
<?php
$str = "The strlen() function is used to calculate the number of characters inside a string." ;
echo strlen($str)."<br>" ;
echo str_word_count($str)."<br>" ;
echo str_replace("strlen()" ,"str_replace()" ,$str, $count)."<br>" ;
echo "Replacements: " .$count."<br>" ;
echo strrev($str)."<br>" ;
$stra = explode(" " , $str);
$stra2 = str_split($str);
print_r($stra);
echo ("<br>---------------------<br>" );
print_r($stra2);
$str1 = implode("," , $stra);
echo "<br>" .$str1."<br>" ;
echo str_shuffle($str1);
echo ("<br>---------------------<br>" );
echo strtoupper(trim($str));
?>
使用explode()會根據某子字串分解成array,使用str_split則分解每一個character成為array。
implode是將array元素粘結,與join()同。
Date/Time
使用date(format)函數來得到目前日期時間,參數為日期格式。使用的符號如下:
d,j: day of the month(j沒有0開頭)
D,l,N: day of the week(D顯示縮寫,N為數字<<1~7>>)
m,n: month in numbers(n沒有0開頭)
M: month in text
y: year in two digits
Y: year in four digits
h,g: hour in 12-hour format(g沒有0開頭)
H,G: hour in 24-hour format(G沒有0開頭)
i: minutes
s: seconds
u,v: microseconds&milliseconds
a: am or pm
A: AM or PM
e,T: time zone(T為時區縮寫)
O,P: difference to Greenwich time(GMT) in hours(P有冒號)
F: 全名非縮寫
php3_4_date.php
<?php
date_default_timezone_set ( 'Asia/Taipei' ) ;
echo date ( "D/d/n/Y" ) . "<br>" ;
echo date ( "l/d-m-Y" ) . "<br>" ;
echo date ( "N.d.m.Y" ) . "<br>" ;
echo date ( "h:i:s e T" ) . "<br>" ;
echo date ( "F d, Y G:i:s A P" ) . "<br>" ;
echo date ( "g:i:s:v a" ) . "<br>" ;
?>
使用date_default_timezone_set()設定時區,參數可參考時區列表 。
timestamp
timestamp指自January 1 1970 00:00:00 GMT至特定時間的秒數,可使用time()取得目前之timestamp。
php3_4_time.php
<?php
date_default_timezone_set ( 'Asia/Taipei' ) ;
$timestamp = time ( ) ;
echo ( $timestamp . "<br>" ) ;
echo ( date ( "F d, Y G:i:s" , $timestamp ) . "<br>" ) ;
echo ( date ( "F d, Y G:i:s" , mktime ( 23 , 59 , 59 , 12 , 31 , 1999 ) ) ) ;
?>
date(format, timestamp)函數可將timestamp的時間轉換成日期時間,沒有timestamp則為目前日期時間。
使用mktime(hour, minute, second, month, day, year)函數來反推timestamp。
更多DateTime函數可見
官網 。
Data Transfer
在Server與Client之間需要資料傳遞,若要將資訊傳回伺服器,通常可使用get與post方式。get會將資料顯示在URL列(不安全且長度有限制),post會將資料整個包裹寄到伺服器再做後續處理。
GET
php4_1_get.php
<head>
<title>Get method</title>
</head>
<body>
<?php
if (isset ($_GET["name" ])){
echo 'Hi, there, <strong>' .$_GET["name" ].'</strong>' ;
}
?>
<form method="get" action="<?php echo $_SERVER[" PHP_SELF"]; ?>" >
<label for ="yourname" >Name:</label>
<input type="text" name="name" id="yourname" >
<input type="submit" >
</form>
</body>
$_SERVER["PHP_SELF"]用來取得目前之php檔案名。將""替換為"php4_1_get.php"結果會相同。
假設URL路徑為http://www.ooxx.com/WorkSpace/php4_1_get.php?name=Tom,那麼
$_SERVER['HTTP_HOST']傳回www.ooxx.com
$_SERVER['REQUEST_URI']傳回/WorkSpace/php4_1_get.php?name=Tom
$_SERVER['PHP_SELF']傳回/WorkSpace/php4_1_get.php
$_SERVER['QUERY_STRING']傳回name=Tom
$_SERVER
<?php
foreach ($_SERVER as $var => $value){
echo "$var => $value <br>" ;
}
?>
PHP包含數個是先定義好的全域變數稱為Superglobals,可在程式碼中隨時使用。
$GLOBALS
$_SERVER
$_GET
$_POST
$_FILES
$_COOKIE
$_SESSION
$_REQUEST
$_ENV
isset() 用來判斷變數是否存在且值不為NULL。e.g. $a=null;isset($a)傳回false。
$_GET["name"]是get表單傳回name="name"的值。
POST
php4_1_post.php
<head>
<title>Post method</title>
</head>
<body>
<?php
if (isset ($_POST["name" ])){
echo 'Hi, there, <strong>' .$_POST["name" ].'</strong>' ;
}
?>
<form method="post" action="<?php echo $_SERVER[" PHP_SELF"]; ?>" >
<label for ="yourname" >Name:</label>
<input type="text" name="name" id="yourname" >
<input type="submit" >
</form>
</body>
PHP & HTML
我們已知可以將HTML的語法寫在echo(or print)內來顯示,也可以使用print <<<EOT ...... EOT; 顯示多行。
<head>
<title>Post method</title>
</head>
<style>
p.bluep{
border:1 px solid blue;
}
</style>
<body>
<?php
$name = "" ;
$email = "" ;
if (isset ($_POST["name" ]) || isset ($_POST["email" ])){
$name = $_POST['name' ];
$email = $_POST['email' ];
}
if ($name != "" || $email != "" )
print <<<EOT
<p class="bluep">Name: $name </p>
<p class="bluep">Email: $email </p>
EOT;
?>
<form method="post" action="<?php echo $_SERVER[" PHP_SELF"]; ?>" >
<p>
<label for ="yourname" >Name:</label>
<input type="text" name="name" id="yourname" >
</p>
<p>
Email Address:
<input type="text" id="email" name="email" size="20" maxlength="40" >
</p>
<input type="submit" value="GO" >
</form>
</body>
這個例子將php與html寫在同一個檔案內,我們也可以將其分開為兩個不同檔案,假設我們將php寫到hello.php檔案,則html檔如下:
<head >
<title > Post method</title >
</head >
<body >
<form method ="post" action ="hello.php" >
<p >
<label for ="yourname" > Name:</label >
<input type ="text" name ="name" id ="yourname" >
</p >
<p >
Email Address:
<input type ="text" id ="email" name ="email" size ="20" maxlength ="40" >
</p >
<input type ="submit" value ="GO" >
</form >
</body >
而hello.php內容則如下:
<?php
if (isset ($_POST["name" ])){
$name = $_POST['name' ];
$email = $_POST['email' ];
}
echo '<h2><a href="test.html">Back to form</a></h2>' ;
print <<<EOT
<p>{$name} </p>
<p>Email: $email </p>
EOT;
?>
如此可以安排成兩個頁面。
FORM
使用各式表單(Form)來將資料傳遞到伺服器,還有哪些講究?
Required
php4_2_form.php
<head>
<title>FORM</title>
</head>
<body>
<?php
$name="" ;
$occupation="" ;
$side="" ;
$pets=array ();
if (isset ($_POST["name" ])){
$name = $_POST["name" ];
}
if (isset ($_POST["occupation" ])){
$occupation = $_POST["occupation" ];
}
if (isset ($_POST["side" ])){
$side = $_POST["side" ];
}
if (isset ($_POST["pets" ])){
$pets = $_POST["pets" ];
}
?>
<form method="post" action="<?php echo htmlspecialchars($_SERVER[" PHP_SELF"]); ?>" >
<label for ="yourname" >姓名:</label>
<input type="text" name="name" id="yourname" ><span style="color:red;" ><sup>*</sup></span><br><br>
<label for ="occupation" >職業:</label>
<input type="text" name="occupation" id="occupation" ><span style="color:red;" ><sup>*</sup></span><br><br>
<label>陣營:</label>
<input type="radio" name="side" value="聯盟" >聯盟
<input type="radio" name="side" value="部落" >部落<span style="color:red;" ><sup>*</sup></span><br><br>
<label>寵物:</label>
<input type="checkbox" name="pets[]" value="灰皮貓" >灰皮貓
<input type="checkbox" name="pets[]" value="小耕作機器人" >小耕作機器人
<input type="checkbox" name="pets[]" value="鸚鵡" >鸚鵡
<input type="checkbox" name="pets[]" value="小座狼" >小座狼
<input type="checkbox" name="pets[]" value="聯盟氣球" >聯盟氣球
<span style="color:red;" ><sup>*</sup></span><br><br>
<input type="submit" ><input type="reset" id="reset" >
</form>
<?php
echo "玩家資訊:<br>" ;
echo "姓名: " .$name."<br>" ;
echo "職業: " .$occupation."<br>" ;
echo "陣營: " .$side."<br>" ;
$allPets = "" ;
foreach ($pets as $key=>$value){
$allPets .= $value." " ;
}
echo "寵物: " .$allPets."<br>" ;
?>
</body>
因為checkbox可以複選,記得其name要使用pets[]代表為array,並宣告$pets為array。
若是每個欄位都是必填(不能空白)要如何設計?
php4_2_formRequired.php
<head>
<title>FORM</title>
</head>
<body>
<?php
$name = $occupation = $side = "" ;
$pets = array ();
$nameErr = $occupationErr = $sideErr = $petsErr = "" ;
if ($_SERVER["REQUEST_METHOD" ] == "POST" ) {
if (empty ($_POST["name" ])){
$nameErr = "必填" ;
}else {
$name = $_POST["name" ];
}
if (empty ($_POST["occupation" ])){
$occupationErr = "必填" ;
}else {
$occupation = $_POST["occupation" ];
}
if (empty ($_POST["side" ])){
$sideErr = "必填" ;
}else {
$side = $_POST["side" ];
}
if (empty ($_POST["pets" ])){
$petsErr = "必填" ;
}else {
$pets = $_POST["pets" ];
}
}
?>
<form method="post" action="<?php echo htmlspecialchars($_SERVER[" PHP_SELF"]); ?>" >
<label for ="yourname" >姓名:</label>
<input type="text" name="name" id="yourname" value="<?php echo $name; ?>" >
<span style="color:red;" ><sup>*</sup><?php echo $nameErr?> </span><br><br>
<label for ="youroccupation" >職業:</label>
<input type="text" name="occupation" id="youroccupation" value="<?php echo $occupation; ?>" >
<span style="color:red;" ><sup>*</sup><?php echo $occupationErr?> </span><br><br>
<label>陣營:</label>
<input type="radio" name="side" value="聯盟" <?php if (isset ($side)&& $side=="聯盟" ) echo "checked" ; ?> >聯盟
<input type="radio" name="side" value="部落" <?php if (isset ($side)&& $side=="部落" ) echo "checked" ; ?> >部落
<span style="color:red;" ><sup>*</sup><?php echo $sideErr?> </span><br><br>
<label>寵物:</label>
<input type="checkbox" name="pets[]" value="灰皮貓" <?php if (isset ($pets)&& in_array("灰皮貓" ,$pets)) echo "checked" ; ?> >灰皮貓
<input type="checkbox" name="pets[]" value="小耕作機器人" <?php if (isset ($pets)&& in_array("小耕作機器人" ,$pets)) echo "checked" ; ?> >小耕作機器人
<input type="checkbox" name="pets[]" value="鸚鵡" <?php if (isset ($pets)&& in_array("鸚鵡" ,$pets)) echo "checked" ; ?> >鸚鵡
<input type="checkbox" name="pets[]" value="小座狼" <?php if (isset ($pets)&& in_array("小座狼" ,$pets)) echo "checked" ; ?> >小座狼
<input type="checkbox" name="pets[]" value="聯盟氣球" <?php if (isset ($pets)&& in_array("聯盟氣球" ,$pets)) echo "checked" ; ?> >聯盟氣球
<span style="color:red;" ><sup>*</sup><?php echo $petsErr?> </span><br><br>
<input type="submit" ><input type="reset" id="reset" >
</form>
<?php
echo "玩家資訊:<br>" ;
echo "姓名: " .$name."<br>" ;
echo "職業: " .$occupation."<br>" ;
echo "陣營: " .$side."<br>" ;
$allPets = implode(", " , $pets);
echo "寵物: " .$allPets."<br>" ;
?>
</body>
使用empty() 方法來確認取得內容是否是empty。
empty()原則上等於!isset($var) || $var == false,以下幾項視為empty:
"" (an empty string)。
0,0.0,'0'(integer, float, string)。
null。
false。
array() (an empty array)。
因為只想要將$pets內容印出來,可以直接使用array方法implode 將內容鏈結印出,或是如之前array所說的使用print_r($pets)來印出。
每次按下傳送後,所有輸入欄便會自動清空,若是想要保留適才輸入資訊
文字輸入欄可以加上value="<?php echo $name; ?>"這一屬性。
radio box可以加上<?php if(isset($side)&& $side=="聯盟") echo "checked"; ?>這一段php程式碼。
check box可以加上<?php if(isset($pets)&& in_array("灰皮貓",$pets)) echo "checked"; ?>這一段php程式碼。
Move from one page to another
如何從某一網頁移動到另一網頁?
Validation
為了避免有人胡亂輸入,除了要求必填之外,尚須要確認輸入內容符合規範。
php4_3_validation.php
<head>
<title>FORM Validation</title>
</head>
<body>
<?php
$name = $email = "" ;
$nameErr = $emailErr = "" ;
if ($_SERVER["REQUEST_METHOD" ] == "POST" ) {
if (empty ($_POST["name" ])){
$nameErr = "必填" ;
}else {
$tempname = $_POST["name" ];
if (!preg_match("/^[a-zA-Z]+\d*/" ,$tempname)){
$nameErr = "Only letters, number and white space, cannot use number&white space as prefix." ;
}else {
$name = $tempname;
}
}
if (empty ($_POST["email" ])){
$emailErr = "必填" ;
}else {
$tempemail = $_POST["email" ];
$tempemail = filter_var($tempemail, FILTER_SANITIZE_EMAIL);
if (!filter_var($tempemail, FILTER_VALIDATE_EMAIL)){
$emailErr = "Invalid email format" ;
}else {
$email = $tempemail;
}
}
}
?>
<form method="post" action="<?php echo htmlspecialchars($_SERVER[" PHP_SELF"]); ?>" >
<label for ="yourname" >姓名:</label>
<input type="text" name="name" id="yourname" value="<?php echo $name; ?>" >
<span style="color:red;" ><sup>*</sup><?php echo $nameErr?> </span><br><br>
<label for ="email" >Email:</label>
<input type="text" name="email" id="email" value="<?php echo $email; ?>" >
<span style="color:red;" ><sup>*</sup><?php echo $emailErr?> </span><br><br>
<input type="submit" ><input type="reset" id="reset" >
</form>
<?php
echo "輸入資訊:<br>" ;
echo "姓名: " .$name."<br>" ;
echo "Email: " .$email."<br>" ;
?>
</body>
Include File
檔案可以傳輸更多資料,而且在檔案內的內容可以被多次使用。可以使用的語法為include與require。先寫幾個要被include的檔案。
php4_4_header.php
< header style= " background: gold; color: tomato;font-size:200%;font-weight:900;text-align:center; " >
PHP
< / header>
php4_4_nav.php
< style >
a:hover{
color: white;
}
nav{
text-align:center;
background:olive;
}
</ style >
< nav > < a href= " http://www2.nkfust.edu.tw/~shanhuen " > Home</ a > |< a href= " http://www2.nkfust.edu.tw/~shanhuen/ " > map</ a > |< a href= " http://www2.nkfust.edu.tw/~shanhuen/ " > about</ a > </ nav >
php4_4_js.php
<head>
<script>
document.body.style.background="#31a1ff" ;
document.body.style.color="white" ;
</script>
</head>
<body>
<?php
$name = $email = "" ;
$nameErr = $emailErr = "" ;
if ($_SERVER["REQUEST_METHOD" ] == "POST" ) {
if (empty ($_POST["name" ])){
$nameErr = "必填" ;
}else {
$tempname = $_POST["name" ];
if (!preg_match("/^[a-zA-Z]+\d*/" ,$tempname)){
$nameErr = "Only letters, number and white space, cannot use number&white space as prefix." ;
}else {
$name = $tempname;
}
}
if (empty ($_POST["email" ])){
$emailErr = "必填" ;
}else {
$tempemail = $_POST["email" ];
$tempemail = filter_var($tempemail, FILTER_SANITIZE_EMAIL);
if (!filter_var($tempemail, FILTER_VALIDATE_EMAIL)){
$emailErr = "Invalid email format" ;
}else {
$email = $tempemail;
}
}
}
?>
<form method="post" action="php4_4_include.php" >
<label for ="yourname" id="namelable" >姓名:</label>
<input type="text" name="name" id="yourname" >
<span style="color:red;" ><sup>*</sup></span><?php echo $nameErr?> <br><br>
<label for ="email" >Email:</label>
<input type="text" name="email" id="email" >
<span style="color:red;" ><sup>*</sup></span><?php echo $emailErr?> <br><br>
<input type="submit" ><input type="reset" id="reset" >
</form>
<?php
echo "輸入資訊:<br>" ;
echo "姓名: " .$name."<br>" ;
echo "Email: " .$email."<br>" ;
?>
</body>
php4_4_footer.php
<style>
footer{
text-align:center;
background:green;
}
</style>
<footer>©2018 Department of Logistics Management@NKUST<br>Last Updated: <span id="lastModifiedTime" >2018.5 .27 </span>
</footer>
<script>
var d = new Date(document.lastModified);
document.getElementById("lastModifiedTime" ).innerHTML = (d.getMonth()+1 )+"/" +d.getDate()+"/" +d.getFullYear();
</script>
在另一個檔案中使用include或是require指令納入以上幾個檔案。
php4_4_include.php
<head>
<title>FORM Validation</title>
<style>
body{
width:85 %;
margin:auto;
}
</style>
</head>
<body>
<?php require "php4_4_header.php" ; ?>
<?php require_once "php4_4_nav.php" ; ?>
<?php include "php4_4_js.php" ; ?>
<?php include_once "php4_4_footer.php" ; ?>
</body>
以上指令使用部分JavaScript 語法。
include與require的不同處是若是發生錯誤(例如找不到檔案),include()會產生警告,而require()會產生錯誤並停止執行。
include_once與require_once的作用與include跟require一樣,只是只會納入一次,如此可避免重複納入的錯誤。
File System
在PHP可以進行檔案操作,包含開啟關閉讀取寫入等。
Open&Close File
使用fopen($filename, $mode)函數來開啟檔案並使用fclose($handle)函數來關閉檔案。
php4_5_fopen.php
<head>
<title>Open&Close File</title>
</head>
<body>
<?php
$filename = "abc.txt" ;
if (!file_exists($filename)){
$file = fopen($filename,"r" );
fclose($file);
}else {
die ("Error: $filename does not exist." );
}
?>
</body>
使用file_exists(filename)函數來判斷該檔案是否存在。
使用die(errorMessage)函數來輸出錯誤訊息並離開(也可以使用exit(errorMessage),兩者是相同的)。
fopen(filename, mode)的mode參數用來確認如何操作檔案,可使用的值如下。
r: 讀取,file opinter指向檔案開頭。
r+: 讀寫,file opinter指向檔案開頭。
w: 寫入,若文件不存在則自動產生。file opinter指向檔案開頭並將檔案大小歸零。
w+: 讀寫,若文件不存在則自動產生。file opinter指向檔案開頭並將檔案大小歸零。
a: 寫入,若文件不存在則自動產生。file opinter指向檔案最後(append)。
x: 產生檔案以寫入。若是檔案已存在則fopen()會傳回false並產生錯誤。
x+: 產生檔案以讀寫。若是檔案已存在則fopen()會傳回false並產生錯誤。
c: 寫入,若文件不存在則自動產生。若檔案存在,file opinter指向檔案開頭。
c+: 讀寫,若文件不存在則自動產生。若檔案存在,file opinter指向檔案開頭。
flag: rb-read binary file(e.g. .gif)。
Directories
Parsing Directory Paths
basename(string path [, string suffix])->string: return filename component of a path。在路徑中取得檔案名。例如:
<?php
$path = '/nkust/www/departments/student.txt' ;
print ("Filename: " .basename($path)."<br>" );
echo "Filename without extension: " .basename($path, '.txt' )."<br>" ;
?>
dirname(string path)->string: providing the direcory component of a path.相對於basename(),dirname()傳回檔案名之前的路徑。
<?php
$path = '/nkust/www/departments/student.txt' ;
echo "Directory path: " .dirname($path)."<br>" ;
?>
pathinfo(string path [, options])->array: 拆解path相關資訊。
<?php
$path = '/nkust/www/departments/student.html' ;
$pathinfo = pathinfo($path);
echo "Dir name: " .$pathinfo['dirname' ]."<br>" ;
echo "Base name: " .$pathinfo['basename' ]."<br>" ;
echo "Extension: " .$pathinfo['extension' ]."<br>" ;
echo "File name: " .$pathinfo['filename' ]."<br>" ;
?>
options可以是PATHINFO_DIRNAME、PATHINFO_BASENAME、PATHINFO_EXTENSION、PATHINFO_FILENAME任一個來取得特定的資訊。
<?php
$path = '/nkust/www/departments/student.html' ;
$pathinfo = pathinfo($path, PATHINFO_BASENAME);
echo $pathinfo;
?>
realpath(string path)->string:取得檔案的絕對路徑。
<?php
$path = '../../nkfust/abc.txt' ;
$absolutePath = realpath($path);
echo $absolutePath;
?>
Calculate File and Disk Sizes
Calculate Sizes:
filesize(string filename)->int: returns the size in bytes of a specified file.
<?php
$file = '../../nkfust/Travel.exe' ;
$size = filesize($file);
$kilo = round($size/1024 , 2 );
echo "Size of file " .basename($file)." is " .$size." bytes or " .$kilo." KB.<br>" ;
?>
disk_free_space(string directory)->float:傳回可用空間。
<?php
$drive = '.' ;
$space = disk_free_space($drive);
$mb = round($space/1048576 , 2 );
$gb = round($mb/1024 , 2 );
echo "Free space of Drive " .$drive." is " .$mb." MB or " .$gb." GB.<br>" ;
?>
disk_total_space(string directory)->float:計算disk size。
<?php
$drive = '.' ;
$space = disk_total_space($drive);
$mb = round($space/1048576 , 2 );
$gb = round($mb/1024 , 2 );
echo "Total space of Drive " .$drive." is " .$mb." MB or " .$gb." GB.<br>" ;
?>
Read File
讀取檔案有多種方式,條列如下:
fread()
使用fread(resource $handle, int $length)->string 讀取文件。
<?php
$filename = "abc.txt" ;
if (file_exists($filename)){
$file = fopen($filename, 'r' );
$content = fread($file, filesize($filename));
echo $content;
fclose($file);
}else {
echo "File does not exist." ;
}
?>
fgets()
使用fgets(resource $handle, int $length = ?)-> string 從文件中讀取一行。
<head>
<title>Read a File</title>
</head>
<body>
<?php
$filename = "abc.txt" ;
if (file_exists($filename)){
$file = fopen($filename,"r" );
while (!feof($file)){
echo fgets($file)."<br>" ;
}
fclose($file);
}else {
exit ("Error: $filename does not exist." );
}
?>
</body>
若是直接讀取所有內容印出,會全部擠在一行(filesize($filename)可以得到檔案的大小)。因此使用while來一行一行讀取並換行。
feof()可判斷是否到達end of file,fgets可在file point讀取一行。
readfile()
使用readfile($filename) 函數讀取檔案內容連open都不需要,讀取後會直接將內容印出,若想顯示換行,可使用<pre>標籤。
php4_5_readfile.php
<head>
<title>Read a File</title>
</head>
<body>
<?php
$filename = "abc.txt" ;
if (file_exists($filename)){
echo ("<pre>" );
readfile($filename);
echo ("</pre>" );
}else {
exit ("Error: $filename does not exist." );
}
?>
</body>
file_get_contents()
使用file_get_contents($filename) 函數讀取檔案內容,傳回字串。可用nl2br()函數在每行之前插入<br>,或是使用字串函數str_replace()將\n換成<br>來換行。
php4_5_fileGetContents.php
<head>
<title>Read a File</title>
</head>
<body>
<?php
$filename = "abc.txt" ;
if (file_exists($filename)){
$content = nl2br(file_get_contents($filename));
echo $content;
}else {
exit ("Error: $filename does not exist." );
}
?>
</body>
file()
使用file($filename) 函數讀取檔案內容,傳回Array。可用foreach來換行。
php4_5_file.php
<head>
<title>Read a File</title>
</head>
<body>
<?php
$filename = "abc.txt" ;
if (file_exists($filename)){
$content = file($filename);
foreach ($content as $line){
echo $line."<br>" ;
}
}else {
exit ("Error: $filename does not exist." );
}
?>
</body>
fgetcsv()
使用fgetcsv(resource handle [, int length [, string delimiter [, string enclosure]]]) 函數讀取csv format檔案(通常資料用逗點(,)分隔),傳回Array。
php4_5_file.php
<?php
$filename = "test.csv" ;
$file = fopen($filename, 'r' );
while (list ($name, $email, $phone) = fgetcsv($file, 1024 , ',' )){
echo "<p>{$name}, {$email}, {$phone}</p>" ;
}
?>
另一個方式是先使用file()讀進資料,然後再使用explode()逐行parse資料,如下:
<?php
$filename = "test.csv" ;
$data = file($filename);
foreach ($data as $value){
list ($name, $email, $phone) = explode(',' , $value);
printf("<p>%s (%s) Tel. %s</p>" ,$name, $email, $phone);
}
?>
File's Time
我們可以取得檔案最後一次被使用、修改的時間。使用
access time: fileatime(string filename)、
change time: filectime(string filename)、
modify time: filemtime(string filename)。
<?php
$file = "..\\..\\nkfust\\abc.txt" ;
date_default_timezone_set('Asia/Taipei' );
$time = date("m-d-Y g:i:sa" , fileatime($file));
echo "Last accessed time of " .basename($file)." is " .$time.".<br>" ;
?>
Write to a File
使用fwrite($file, $string)函數將$string寫入$filename。
php4_5_fwrite.php
<head>
<title>Write to a File</title>
</head>
<body>
<?php
$filename = "abc.txt" ;
$openFile = fopen($filename, 'w' );
fwrite($openFile, 'Write something...' .PHP_EOL.'Write more...' .PHP_EOL.'And more' .PHP_EOL);
fwrite($openFile, 'Write something2...' .PHP_EOL.'Write more2...' .PHP_EOL.'And more2' );
fclose($openFile);
$file = fopen($filename,"r" );
while (!feof($file)){
echo fgets($file)."<br>" ;
}
fclose($file);
?>
</body>
使用PHP_EOL來換行。
讀取檔案可使用任意read file方法。
其他寫入檔案方法:
Rename&Remove File
使用rename($oldname, $newname)來將檔案改名,使用unlink($filename)來刪除檔案。
php4_5_fileRename.php
<head>
<title>Write to a File</title>
</head>
<body>
<?php
$filename = "abc.txt" ;
$newfilename = "zzz.txt" ;
if (file_exists($filename)){
if (rename($filename, $newfilename)){
echo ("Rename successfully.<br>" );
}else {
echo ("Rename failed." );
}
}else {
exit ("Error: File does not exist." );
}
$content = nl2br(file_get_contents($newfilename));
echo $content;
?>
</body>
若是$newname中包含路徑(path),那麼檔案會移至該路徑,而且可以跨device(drive C to drive E),如此方式可以複製檔案。
顯然讀取檔案也可以跨device。
php4_5_unlink.php
<head>
<title>Write to a File</title>
</head>
<body>
<?php
$filename = "E:\Temp\zzz.txt" ;
if (file_exists($filename)){
if (unlink($filename)){
echo ("delete file successfully.<br>" );
}else {
echo ("Delete file failed." );
}
}else {
exit ("Error: File does not exist." );
}
?>
</body>
file system相關函數:
fgetc(): 讀取一個字元。
fgets(): 讀取一行。
fgetcsv(): 讀取逗點(,)分隔的一行。
filetype(): 傳回檔案的型態。
feof(): 檢查是否到達檔案最後。
is_file(): 檢查是否是一般檔案。
is_dir(): 檢查是否為路徑。
is_executable(): 檢查是否是可執行檔案。
realpath(): 傳回絕對路徑。
rmdir(): 移除空路徑。
Upload & Download files
資料傳輸當然包含檔案的傳輸,可以上傳檔案到伺服器也可以自伺服器下載檔案。
Upload File
上傳檔案使用HTTP檔案上傳變數$_FILES,是一個內定的全域變數(Superglobals)。這是一個包含上傳檔案相關資料的array,包含的資料有:
$_FILES["userfile"]["name"]: 原始檔案名。
$_FILES["userfile"]["type"]: 檔案的MIME型態。
$_FILES["userfile"]["size"]: 檔案大小(bytes)。
$_FILES["userfile"]["tmp_name"]: 暫時檔名。
$_FILES["userfile"]["error"]: 錯誤碼。
0: 沒有錯誤。
1: 上傳檔案大小超過upload_max_filesize in php.ini。
2: 上傳檔案大小超過form中所限定的大小(MAX_FILE_SIZE)。
3: 上傳檔案只有部分上傳成功。
4: 沒有檔案上傳。
6: 缺少暫時資料夾。
7: 寫到磁碟失敗。
8: PHP延伸檔名阻止檔案上傳(使用phpinfo()方法可能幫助釐清延伸檔名)。
php4_6_fileUpload.php
<head>
<title>Upload a File</title>
</head>
<body>
<form action="fileupload.php" method="post" enctype="multipart/form-data" >
<label for ="fileSelect" >Filename:</label>
<input type="file" name="uploadfile" id="fileSelect" >
<input type="submit" name="submit" value="Upload" >
</form>
</body>
需先設計上傳表單(post),且將型態定為multipart/form-data。
接著設計對應的fileupload.php來處理上傳。
fileupload.php
<?php
if ($_FILES["uploadfile" ]["error" ] > 0 ){
echo "Error: " .$_FILES["uploadfile" ]["error" ]. "<br>" ;
}else {
echo "File name: " .$_FILES["uploadfile" ]["name" ]."<br>" ;
echo "File type: " .$_FILES["uploadfile" ]["type" ]."<br>" ;
echo "File size: " .$_FILES["uploadfile" ]["size" ]."<br>" ;
echo "File is in: " .$_FILES["uploadfile" ]["tmp_name" ]."<br>" ;
}
?>
當錯誤訊息大於0,傳回錯誤。
錯誤訊息
UPLOAD_ERR_OK:傳回(0)--無錯誤。
UPLOAD_ERR_INI_SIZE:傳回(1)--檔案大小超過upload_max_filesize directive。
UPLOAD_ERR_FORM_SIZE:傳回(2)--檔案大小超過max_file_size directive,此可嵌入HTML form(因為在HTML容易被修改,所以最好不要使用,使用上項的upload_max_filesize代替)。
UPLOAD_ERR_PARTIAL:傳回(3)--檔案沒有完全上傳。
UPLOAD_ERR_NO_FILE:傳回(4)--沒有選擇檔案。
UPLOAD_ERR_NO_TMP_DIR:傳回(6)--臨時路徑不存在。
UPLOAD_ERR_CANT_WRITE:傳回(7)--檔案無法寫到磁碟。
UPLOAD_ERR_EXTENSION:傳回(8)--PHP擴充套件導致上傳停止。
此時檔案於暫存位置,若要見到檔案,須使用move_uploaded_file($filename, $destination)將其移至目標資料夾,假設要移動至upload資料夾,先在WorkSpace下建立upload資料夾。
將fileupload.php檔案修改如下:
fileupload.php
<?php
if ($_SERVER["REQUEST_METHOD" ]=="POST" ){
if (isset ($_FILES["uploadfile" ]) && $_FILES["uploadfile" ]["error" ]==0 ){
$filename=$_FILES["uploadfile" ]["name" ];
$filetype=$_FILES["uploadfile" ]["type" ];
$filesize=$_FILES["uploadfile" ]["size" ];
$targetFile = "upload/" .basename($filename);
if (file_exists($targetFile))
die ("$targetFile already exists." );
$maxsize = 5 *1024 *1024 ;
if ($filesize > $maxsize)
exit ("Error: File size exceeds the max size." );
move_uploaded_file($_FILES["uploadfile" ]["tmp_name" ],"upload/" .$filename);
echo "Upload successfully." ;
}else {
echo "Error: Something wrong. Please try again." ;
}
}
?>
使用move_uploaded_file()函數來移動檔案,若要到其他特定位置可用絕對位置(e.g. E:/Temp/)替換upload/。
此例子可上傳任意型態檔案,亦可自訂檔案型態並使用$filetype來過濾,可用來限定上傳型態,例如僅接受圖檔上傳(.gif, .png, .jpg等)。例如if ($filetype!="jpg" && $filetype!="gif" && $filetype!="png") echo("wrong type.");
此例子限定上傳檔案大小不超過5M($maxsize)。
也可以使用file_exists()來避免重複上傳。
Download File
下載檔案只需要使用html的標籤a即可。
php3_4_time.php
<head>
<title>Download a File</title>
</head>
<body>
<a href="hello.php" >Download hello.php</a>
</body>
如果是PDF或是圖檔,按左鍵僅會開啟不會下載(按右鍵選擇下載),若是zip還是exe檔案會自動下載。
Cookies & Sessions
Cookies是一個文字檔,允許我們儲存小量資料(約莫4KB)在使用者的電腦。Sessions則是儲存在伺服器。
Cookies
欲使用cookie,需先使用setcookie($name[, $value[, $expire[, $path[, $domain[, $secure[, $httponly]]]]]])函數設定,否則無法送出cookie。
setcookie的參數涵義為:
$name: cookie名稱。
$value: cookie的值(不要儲存重要的資訊因為會存在使用者的電腦)。
$expires: expiry date in UNIX timestamp format(如果是0或是沒有設定,cookie會在瀏覽器關閉時失效)。
$path: the path on the server which the cookie will be available(如果是/則表示全部範圍都可得到)。
$domain: 可得到cookie的domain(e.g. www.OOXX.com)。
$secure: 如果是True表示cookie僅在存在安全連線時會送出。
$httponly: 如果是True表示cookie僅可經由HTTP協議得到。
php4_7_cookies.php
<head>
<title>Cookies</title>
</head>
<body>
<?php
setcookie("username" ,"多啦A夢" , time()+5 *60 );
if (isset ($_COOKIE["username" ])){
echo "Welcome " .$_COOKIE["username" ]."<br>" ;
}else {
echo "Hi, there.<br>" ;
}
print_r($_COOKIE);
?>
</body>
養成習慣使用isset()。
使用print_r()顯示array資訊。
使用一樣的setcookie資訊(將時間改為負的)來刪除cookie。
執行第二次才會得到cookie的值。
Sessions
Session會將資料儲存在伺服器,如此可以避免如cookie每次都要將資料先傳回,此外安全性也較高。要使用session需先使用session_start()函數來建立新的session,並同時為使用者產生一個唯一的id。
php3_4_time.php
<head>
<title>Cookies</title>
</head>
<body>
<?php
session_start();
$_SESSION["name" ] = "Tom" ;
$_SESSION["occupation" ] = "Warrior" ;
echo "Greeting...<span style='color:red;'>" .$_SESSION["occupation" ]."</span> " .$_SESSION["name" ]."<br>" ;
print_r($_SESSION);
?>
</body>
session_start()一開始會先偵測session是否已經存在,若不存在才會產生新的。
使用print_r()函數印出array內容。
使用session_destroy()來刪除session。若僅只要移除特定session資料,可以使用unset函數(e.g. unset($_SESSION['occupation']))。
Object
設計class來產生物件。
php5_1_class.php
<head>
<title>Create a class </title >
</head >
<body >
<?php
class Circle {
public $radius;
public function __construct ($r) {
$this ->radius = $r;
echo __CLASS__ ." was initiated.<br>" ;
}
public function __destruct () {
echo __CLASS__ ." was destroyed.<br>" ;
}
public function cArea () {
return ($this ->radius * $this ->radius * pi()."<br>" );
}
}
$cir = new Circle(10 );
echo ($cir->cArea());
$cir->radius = 20 ;
echo ($cir->cArea());
?>
</body>
class包含屬性(attributes)、建構子(constructor)與解構子(deconstructor)、方法(methods)三個部分。
解構子(__destruct())會在物件使用完後自動執行並清空所有之前配置的資源。
__CLASS__屬於Magic Constants,會傳回目前class的名字。
使用$this來指稱本class,使用->來指位變數或是方法。
使用$this->radius($在this之前 )取得$radius的值。
或使用$cir->radius(radius之前沒有$號 )取得$radius的值。
使用include(require)導入class可在其他檔案產生物件。
php5_1_includeClass.php
<head>
<title>Create a class </title >
</head >
<body >
<?php
include "php5_1_class .php ";
$cir1 = new Circle (100);
echo $cir1 ->cArea ();
$cir2 = new Circle (1000);
echo $cir2 ->cArea ();
?>
</body >
Cloning an object
已知若是使用instanceB = instanceA,原則上兩者指位至同一個位址,若是要複製成一個新的物件,可以使用clone。
<?php
class One {
public $v;
public $arr = [1 ,2 ,3 ,4 ,5 ];
public function __construct ($v) {
$this ->v = $v;
}
public function __destruct () {
echo __CLASS__ ." was destroyed.<br>" ;
}
public function __toString () {
print_r($this ->arr);
echo "<br>" ;
return "value = {$this->v}<br>" ;
}
}
$one = new One("one" );
echo $one;
$two = clone $one;
$two->v = "two" ;
$two->arr[0 ] = 100 ;
echo $one;
echo $two;
?>
我們可以在class內實作__clone()方法,當使用clone時,會直接執行此方法。
<?php
class One {
public $v;
public $arr = [1 ,2 ,3 ,4 ,5 ];
public function __construct ($v) {
$this ->v = $v;
}
public function __destruct () {
echo __CLASS__ ." was destroyed.<br>" ;
}
public function __clone () {
$this ->v = "no name" ;
$this ->arr = [0 ,0 ,0 ,0 ,0 ];
}
public function __toString () {
print_r($this ->arr);
echo "<br>" ;
return "value = {$this->v}<br>" ;
}
}
$one = new One("one" );
echo $one;
$two = clone $one;
$two->arr[0 ] = 100 ;
echo $one;
echo $two;
?>
static
當變數或方法使用static關鍵字修飾時,不需要產生(new)物件(instance)便可取得變數或使用方法。
php3_4_time.php
<head>
<title>Static variable & Method</title>
</head>
<body>
<?php
class Circle {
public static $radius;
public static function cArea () {
return (self ::$radius * self ::$radius * pi()."<br>" );
}
}
Circle::$radius = 100 ;
echo Circle::cArea();
$cir = new Circle(10 );
$cir->radius = 20 ;
echo ($cir->cArea());
?>
</body>
變數與方法使用static修飾後,不需要new一個新的instance便可直接取得,使用語法為classname::variablename或classname::methodname()。
若是堅持new一個instance再使用,會產生Warning。
self表示目前class,也是使用::來取得變數或使用方法。使用static不可使用$this。
static變數可以記憶其值即使函數結束,例如:
<?php
function staticVar () {
static $v = 0 ;
echo $v."<br>" ;
$v++;
}
staticVar();
staticVar();
staticVar();
?>
trait
trait是一組函數,可以用來加入到某物件內。
<?php
trait someFuns{
public function printSomething () {
echo 'something<br>' ;
}
public function circle ($r) {
return M_PI*$r*$r;
}
}
class AClass {
use someFuns ;
}
$ac = new AClass();
$ac->printSomething();
echo $ac->circle(10 );
?>
Inheritance
class可以繼承,使用關鍵字extends。
php5_2_inheritance.php
<head>
<title>Static variable & Method</title>
</head>
<body>
<?php
class Ellipse {
public $radiusA;
public $radiusB;
public function __construct ($a, $b) {
$this ->radiusA = $a;
$this ->radiusB = $b;
echo __CLASS__ ." was initiated.<br>" ;
}
public function __destruct () {
echo __CLASS__ ." was destroyed.<br>" ;
}
public function eArea () {
return ($this ->radiusA * $this ->radiusB * pi()."<br>" );
}
}
class Circle extends Ellipse {
public function isCircle () {
if ($this ->radiusA == $this ->radiusB)
return true ;
else
return false ;
}
}
$cir = new Circle(10 ,10 );
echo $cir->isCircle()?"圓形<br>" :"橢圓形<br>" ;
echo $cir->eArea();
?>
</body>
Inheritance of static variable
如果繼承時包含static變數或方法。
<?php
class Super {
static $value = "super" ;
public static function getValue () {
return self ::$value;
}
}
class Sub extends Super {
static $value = "sub" ;
}
echo Sub::getValue();
?>
self用於參照目前的class($this用於參照目前的物件(instance)),而self可用於static,$this則不行(因為沒有instance)。
上例中當呼叫getValue()時,得到的是super。若是要得到sub的value,則不可使用self,應使用關鍵字static,稱為late static bindings(PHP 5.3)。
<?php
class Super {
protected static $value = "super" ;
public static function getValue () {
return static ::$value;
}
}
class Sub extends Super {
protected static $value = "sub" ;
}
echo Sub::getValue();
?>
Visibility
使用public, protected, private來控制存取變數或方法的權限。
public: 在class內外皆可存取(預設值)。
protected: 在class或繼承該class的classes內可存取。
private: 僅可在該class內存取。
php5_3_visibility.php
<head>
<title>Visibility of variable & Method</title>
</head>
<body>
<?php
class Ellipse {
private $radiusA;
protected $radiusB;
public function __construct ($a = 1 , $b = 1 ) {
$this ->radiusA = $a;
$this ->radiusB = $b;
echo __CLASS__ ." was initiated.<br>" ;
}
public function __destruct () {
echo __CLASS__ ." was destroyed.<br>" ;
}
public function setA ($a) {
$this ->radiusA = $a;
}
public function getA () {
return $this ->radiusA;
}
public function setB ($b) {
$this ->radiusB = $b;
}
public function getB () {
return $this ->radiusB;
}
public function eArea () {
return ($this ->radiusA * $this ->radiusB * pi()."<br>" );
}
}
class Circle extends Ellipse {
public function isCircle () {
if ($this ->radiusA == $this ->radiusB){
echo "radiusA = " .$this ->radiusA."<br>" ;
echo "radiusB = " .$this ->radiusB."<br>" ;
return true ;
}else {
echo "radiusA = " .$this ->radiusA."<br>" ;
echo "radiusB = " .$this ->radiusB."<br>" ;
return false ;
}
}
}
$ell = new Ellipse();
$ell->setA(10 );
$ell->setB(10 );
echo $ell->eArea();
$cir = new Circle(100 ,100 );
echo $cir->isCircle()?"圓形<br>" :"橢圓形<br>" ;
echo $cir->eArea();
?>
</body>
僅能設計一個Constructor,所以建構時僅能使用constructor所設計的argument,但若是在內給初值,便可不給argument而直接使用預設值。
使用getters與setters來存取private修飾的變數。
在class外存取private或protected修飾的變數($ell->radiusB)會產生錯誤。
雖然原class內有private屬性參數,但是還是能夠繼承,只是無法存取private修飾之值,但是protected修飾的值可以取得。
因為無法取得$radiusA的值,所以傳回橢圓形(false)。
Magic Constants
Magic Constants是PHP內建的常數變數,會隨著出現位置有不同的值。其前後各有兩個底線。
Magic Constants:
__LINE__: 傳回檔案目前的行數。
__FILE__: 傳回目前檔案的路徑與名稱。
__DIR__: 傳回目前檔案的directory。
__FUNCTION__: 傳回目前函數的名稱。
__CLASS__: 傳回目前class的名稱。
__METHOD__: 傳回目前class method的名稱。
__NAMESPACE__: 傳回目前的namespace。
php5_4_magicConstants.php
<head>
<title>Magic Constants</title>
</head>
<body>
<?php
echo "Line number = " .__LINE__ ."<br>" ;
echo "File path = " .__FILE__ ."<br>" ;
echo "Directory = " .__DIR__ ."<br>" ;
function fun () {
echo "Function name = " .__FUNCTION__ ."<br>" ;
}
fun();
class Ellipse {
public $radiusA;
public $radiusB;
function __construct ($a = 1 , $b = 1 ) {
$this ->radiusA = $a;
$this ->radiusB = $b;
echo __CLASS__ ." was initiated.<br>" ;
}
function __destruct () {
echo __CLASS__ ." was destroyed.<br>" ;
}
function eArea () {
echo "Class name = " .__CLASS__ ."<br>" ;
echo "Method name = " .__METHOD__ ."<br>" ;
echo "Name Space = " .__NAMESPACE__ ."<br>" ;
return ("橢圓形面積 = " .$this ->radiusA * $this ->radiusB * pi()."<br>" );
}
}
$ell = new Ellipse(10 ,10 );
echo $ell->eArea();
?>
</body>
需使用namespace關鍵字定義Name Space才有__NAMESPACE__。
Namespace example
使用{}來區分namespace範圍。
<?php
namespace ns
{
class One {
public $var ;
public function __construct ($var) {
$this ->var = $var;
echo __CLASS__ ." was initiated.<br>" ;
}
public function __destruct () {
echo __CLASS__ ." was destroyed.<br>" ;
}
public function __toString () {
return "Value = {$this->var}<br>" ;
}
}
}
namespace we {
class One {
public $var ;
public function __construct ($var) {
$this ->var = $var;
echo __CLASS__ ." was initiated.<br>" ;
}
public function __destruct () {
echo __CLASS__ ." was destroyed.<br>" ;
}
public function __toString () {
return "Value = {$this->var}<br>" ;
}
}
}
namespace {
$nsone = new ns \One (1);
echo $nsone;
$weone = new we\One(2 );
echo $weone;
}
?>
如果定義在不同檔案,可以使用分號(;)代替大括號,這樣還是最好一個檔案定義一個namespace。
Magic Methods
相對於magic constants,PHP還提供數個Magic methods,如下:
Magic Methods:
__construct()
__destruct()
__call()
__callStatic()
__get()
__set()
__isset()
__unset()
__sleep()
__wakeup()
__serialize()()
__unserialize()
__toString()
__invoke()
__set_state()
__clone()
__debugInfo()
有些已介紹過,此處擇要介紹。
__call()表示在沒有得呼叫的情況下,呼叫__call()函數,可視為預設函數。如下例中呼叫了沒有定義的物件方法以及private method,此時都只好呼叫__call()。
<?php
class ToCall {
public function __call ($name, $arguments) {
echo "'{$name}' is not existed.<br>" ;
print_r($arguments);
echo "<br>" ;
}
private function pri () {
echo "A private function" ;
}
}
$tc = new ToCall();
$tc->onemethod(1 ,2 ,3 );
$tc->pri(123 );
?>
如果有些程式碼是每一個函數都需要執行的,那麼可以如此應用:
<?php
class ToCall {
public function __call ($method, $arguments) {
echo "Hello<br>" ;
call_user_func_array(array ($this , $method), $arguments);
echo "See ya.<br>" ;
}
private function pri () {
echo "A private function<br>" ;
}
private function pri2 () {
echo "A private function 2<br>" ;
}
}
$tc = new ToCall();
$tc->pri();
$tc->pri2();
?>
call_user_func_array(callable, arguments)用來呼叫callable並使用arguments作為輸入參數。
此處的callable因為需要兩個參數來表示(一為物件名二為方法名),因此需使用array(obj, method)來表示callable。
Overloading 讓我們可以在執行時(run-time)增加物件成員,需要實現overloading方法,包含__get, __set, __call, 以及__callStatic等。下例中同時測試isset()、unset()、empty()等方法。
<?php
class One {
private $data = array ();
public $var = 1 ;
public function __call ($name, $args) {
$ar = "" ;
if ($args <> array ()){
for ($i=0 ; $i<count($args); $i++){
if ($i==0 ){
$ar = "{$args[$i]}" ;
}else {
$ar = "{$ar}, {$args[$i]}" ;
}
}
}
echo "Warning: calling $name($ar)" ;
}
public static function __callStatic ($name, $args) {
$ar = "" ;
if ($args <> array ()){
for ($i=0 ; $i<count($args); $i++){
if ($i==0 ){
$ar = "{$args[$i]}" ;
}else {
$ar = "{$ar}, {$args[$i]}" ;
}
}
}
echo "Warning: calling static $name($ar)" ;
}
public function __set ($name, $value) {
$this ->data[$name] = $value;
}
public function __get ($name) {
if (array_key_exists($name, $this ->data)){
return $this ->data[$name];
}
}
}
$one = new One();
$one->a = 1 ;
echo $one->a;
$one->two(1 , 2 , 3 );
One::three('x' , 'y' , 'z' );
echo isset ($one->var)? "Set" :"Not set" ;
echo empty ($one->var)? "Empty" :"Not empty" ;
unset ($one->var);
echo isset ($one->var)? "Set" :"Not set" ;
?>
MySQL Introduction
MySQL是一種relational資料庫,當安裝XAMPP時也同時安裝,可以直接使用。使用前先打開XAMPP Control Panel並點選MySQL的Start。
php6_1_mysqlConnection.php
<head>
<title>MySQL Connection</title>
</head>
<body>
<?php
$link = mysqli_connect("localhost" , "root" , "" );
if ($link === false ){
die ("Error: Could not connect." .mysqli_connect_error());
}
echo "Connect successfully." .mysqli_get_host_info($link);
mysqli_close($link);
?>
</body>
使用mysqli_connect("hostname","username", "password", "database")函數連結至資料庫,第一個參數指連結至localhost(也可以使用127.0.0.1),因為使用預設的設定,所以後續參數使用root且沒有password。
使用mysqli_connect_error()顯示錯誤訊息,mysqli_get_host_info($link)顯示host的資訊。
連結至資料庫可使用以下方式:
mysqli_connect()。
new mysqli()。
使用PDO。
php6_1_PDO.php
<head>
<title>MySQL PDO Connection</title>
</head>
<body>
<?php
$link = new PDO("mysql:host=127.0.0.1;" , "root" , "" );
if (!$link){
die ("Error: Could not connect." .mysqli_connect_error());
}
echo "Connect successfully.<br>" ;
$link = null ;
echo "Disconnected."
?>
</body>
Database
連結資料庫後可以建立一個database,使用sql的
CREATE DATABASE 語法。
php3_4_time.php
<head>
<title>MySQL Create Database</title>
</head>
<body>
<?php
$link = mysqli_connect("127.0.0.1" , "root" , "" );
if ($link === false ){
die ("Error: Could not connect." .mysqli_connect_error());
}
$sql = "CREATE DATABASE test" ;
if (mysqli_query($link, $sql)){
echo "Database created successfully." ;
}else {
echo ("Error: Could not execute $sql." .mysqli_error($link));
}
mysqli_close($link);
?>
</body>
使用mysqli_query()方法查詢資料庫,mysqli_error($link)傳回錯誤。
如果連續執行兩次,第二次會出現錯誤,因為database已存在。
若要刪除database,使用DROP DATABASE test。
Create Table
建立了database之後,可以在其內建立table,用以儲存資料,可使用sql的
CREATE TABLE 語法。
php6_2_createTable.php
<head>
<title>MySQL Create Table</title>
</head>
<body>
<?php
$link = mysqli_connect("127.0.0.1" , "root" , "" , "test" );
if ($link === false ){
die ("Error: Could not connect." .mysqli_connect_error());
}
$sql = "CREATE TABLE characters(
id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50) NOT NULL UNIQUE,
race VARCHAR(50) NOT NULL,
occupation VARCHAR(50) NOT NULL,
level INT NOT NULL
)" ;
if (mysqli_query($link, $sql)){
echo "Table created successfully." ;
}else {
echo ("Error: Could not execute $sql." .mysqli_error($link));
}
mysqli_close($link);
?>
</body>
因為要建立的table位於test(已建立)這個database內,所以在connect的時候參數要加上database(test)的名稱。
sql CREATE TABLE語法:
在CREATE TABLE後加上table的名稱(charaters)。
id為整數(int),不能為空,為primary key且會自動增加。
name, race為字元,括號內數字為長度,name為唯一(unique)。
若要刪除table,使用DROP TABLE characters語法。
Insert
有了table之後便可以開始加入資料,使用sql的
INSERT INTO 語法。
php6_3_insert.php
<head>
<title>MySQL Create Database</title>
</head>
<body>
<?php
$link = mysqli_connect("127.0.0.1" , "root" , "" , "test" );
if ($link === false ){
die ("Error: Could not connect." .mysqli_connect_error());
}
$sql = "INSERT INTO characters(name, race, occupation, level) VALUES ('Tom', 'Human', 'Warrior', 1)" ;
if (mysqli_query($link, $sql)){
echo "Database created successfully." ;
}else {
echo ("Error: Could not execute $sql." .mysqli_error($link));
}
$sql = "INSERT INTO characters(name, race, occupation, level) VALUES ('John', 'Dwarf', 'Hunter', 2),('Mary', 'Elf', 'Mage', 5),('Lance', 'Human', 'Priest', 7)" ;
if (mysqli_query($link, $sql)){
echo "Database created successfully." ;
}else {
echo ("Error: Could not execute $sql." .mysqli_error($link));
}
$sql = "SELECT * FROM characters" ;
if ($result = mysqli_query($link, $sql)){
if (mysqli_num_rows($result) > 0 ){
echo "<table><tr>" ;
echo "<th>Id</th><th>Name</th><th>Race</th><th>Occupation</th><th>Level</th>" ;
echo "</tr>" ;
while ($row = mysqli_fetch_array($result)){
echo "<tr>" ;
echo "<td>" .$row['id' ]."</td>" ;
echo "<td>" .$row['name' ]."</td>" ;
echo "<td>" .$row['race' ]."</td>" ;
echo "<td>" .$row['occupation' ]."</td>" ;
echo "<td>" .$row['level' ]."</td>" ;
echo "</tr>" ;
}
echo "</table>" ;
mysqli_free_result($result);
}else {
echo "No records matched." ;
}
}else {
echo "Error: Could not execute $sql." .mysqli_error($link);
}
mysqli_close($link);
?>
</body>
使用INSERT INTO tablename(attributes) VALUES(values)來加入一筆資料,若是VALUES(values),(values),(values)可加入多筆資料。
因為id設定為AUTO_INCREMENT,所以不需要寫入,會自動產生。
為了顯示內容資料,使用SELECT * FROM characters語法來選擇所有資料。
mysqli_num_rows($result)可取得行數。
mysqli_fetch_array($result)可取得一筆資料,且該資料儲存為array,並將pointer移往下一筆資料。亦可使用$row[0],$row[1],$row[2]等來取得資料。
mysqli_free_result($result)可釋放$result的記憶體。
INSERT FORM
當然希望可以從網頁讓使用者輸入資料然後儲存到資料庫,所以需要設計輸入表單。
php6_3_insertForm.php
<head>
<title>MySQL Insert Form</title>
</head>
<body>
<form action="php6_3_formInsertion.php" method = "post" >
<p>
<label for ="name" >Name:</label>
<input type="text" name="name" id="name" >
</p>
<p>
<label for ="race" >Race:</label>
<input type="text" name="race" id="race" >
</p>
<p>
<label for ="name" >Occupation:</label>
<input type="text" name="occupation" id="occupation" >
</p>
<p>
<label for ="name" >Level:</label>
<input type="text" name="level" id="level" >
</p>
<input type="submit" value="Add" >
</form>
</body>
然後設計對應的php檔案來處理輸入。
php6_3_formInsertion.php
<?php
$link = mysqli_connect("127.0.0.1" , "root" , "" , "test" );
if ($link === false ){
die ("Error: Could not connect." .mysqli_connect_error());
}
$name = mysqli_real_escape_string($link, $_REQUEST['name' ]);
$race = mysqli_real_escape_string($link, $_REQUEST['race' ]);
$occupation = mysqli_real_escape_string($link, $_REQUEST['occupation' ]);
$level = mysqli_real_escape_string($link, $_REQUEST['level' ]);
$sql = "INSERT INTO characters(name, race, occupation, level) VALUES ('$name', '$race', '$occupation', '$level')" ;
if (mysqli_query($link, $sql)){
$last_id = mysqli_insert_id($link);
echo "Record inserted successfully and inserted ID is " .$last_id;
}else {
echo ("Error: Could not execute $sql." .mysqli_error($link));
}
$sql = "SELECT * FROM characters" ;
if ($result = mysqli_query($link, $sql)){
if (mysqli_num_rows($result) > 0 ){
echo "<table style='border:1px solid gold;'><tr>" ;
echo "<th style='border:1px solid red;'>Id</th><th style='border:1px solid red;'>Name</th><th style='border:1px solid red;'>Race</th><th style='border:1px solid red;'>Occupation</th><th style='border:1px solid red;'>Level</th>" ;
echo "</tr>" ;
while ($row = mysqli_fetch_array($result)){
echo "<tr style='border:1px solid red;'>" ;
echo "<td style='border:1px solid blue;'>" .$row['id' ]."</td>" ;
echo "<td style='border:1px solid blue;'>" .$row['name' ]."</td>" ;
echo "<td style='border:1px solid blue;'>" .$row['race' ]."</td>" ;
echo "<td style='border:1px solid blue;'>" .$row['occupation' ]."</td>" ;
echo "<td style='border:1px solid blue;'>" .$row['level' ]."</td>" ;
echo "</tr>" ;
}
echo "</table>" ;
mysqli_free_result($result);
}else {
echo "No records matched." ;
}
}else {
echo "Error: Could not execute $sql." .mysqli_error($link);
}
mysqli_close($link);
?>
mysqli_real_escape_string()函數可產生可使用於sql語法的合法sql字串,儘管如此,在VALUES中還是需要使用引號('$name', '$race', '$occupation', '$level')。
使用mysqli_insert_id($link)方法取得輸入資料的ID,可協助我們追蹤資訊或做後續用途。
Prepared Statement
Prepared Statement是先將要輸入的資料格式準備好,然後再根據格式加入資料的方式。
php6_3_prepared.php
<?php
$link = mysqli_connect("127.0.0.1" , "root" , "" , "test" );
if ($link === false ){
die ("Error: Could not connect." .mysqli_connect_error());
}
$sql = "INSERT INTO characters(name, race, occupation, level) VALUES (?, ?, ?, ?)" ;
if ($stmt = mysqli_prepare($link, $sql)){
mysqli_stmt_bind_param($stmt, "sssi" , $name, $race, $occupation, $level);
$name = $_REQUEST['name' ];
$race = $_REQUEST['race' ];
$occupation = $_REQUEST['occupation' ];
$level = $_REQUEST['level' ];
if (mysqli_stmt_execute($stmt)){
echo "Insert successfully" ;
}else {
echo "Error: Could not execute query: $sql. " . mysqli_error($link);
}
}else {
echo ("Error: Could not prepare query: $sql. " .mysqli_error($link));
}
$sql = "SELECT * FROM characters" ;
if ($result = mysqli_query($link, $sql)){
if (mysqli_num_rows($result) > 0 ){
echo "<table style='border:1px solid gold;'><tr>" ;
echo "<th style='border:1px solid red;'>Id</th><th style='border:1px solid red;'>Name</th><th style='border:1px solid red;'>Race</th><th style='border:1px solid red;'>Occupation</th><th style='border:1px solid red;'>Level</th>" ;
echo "</tr>" ;
while ($row = mysqli_fetch_array($result)){
echo "<tr style='border:1px solid red;'>" ;
echo "<td style='border:1px solid blue;'>" .$row['id' ]."</td>" ;
echo "<td style='border:1px solid blue;'>" .$row['name' ]."</td>" ;
echo "<td style='border:1px solid blue;'>" .$row['race' ]."</td>" ;
echo "<td style='border:1px solid blue;'>" .$row['occupation' ]."</td>" ;
echo "<td style='border:1px solid blue;'>" .$row['level' ]."</td>" ;
echo "</tr>" ;
}
echo "</table>" ;
mysqli_free_result($result);
}else {
echo "No records matched." ;
}
}else {
echo "Error: Could not execute $sql." .mysqli_error($link);
}
mysqli_close($link);
?>
一樣使用php6_3_insertForm.php所產生的表格來輸入要增加的資料,要記得修改action="php6_3_prepared.php",因為此次要使用另一個方式來insert輸入的資料。
Prepared Statment的sql語法中,VALUES的值皆設為?,再在之後加入。
使用mysqli_prepare($link, $query)來準備SQL語法並等著被執行。
使用mysqli_stmt_bind_param($stmt, $type, $var)來連結變數與一個prepared statement。
$type字串用來指稱每個變數的型態。
i: integer。
d: double。
s: string。
b: binary(image, PDF file, etc.)。
所以"sssi"的意思便是前三個輸入為字串,最後一個為整數。
使用mysqli_stmt_execute($stmt)來執行準備好的query($stmt),成功時會將資料insert到資料庫。
Select, Where, Limit & Order by
之前已經使用過SELECT * FROM characters的sql語法來選擇table characters內的所有資料,使用關鍵字
SELECT 選擇,
*號 表示所有。若是要使用其他條件來篩選資料,可使用關鍵字
WHERE ,若是要限制產生數量,則使用關鍵字
LIMIT 。
php6_5_select.php
<?php
$link = mysqli_connect("127.0.0.1" , "root" , "" , "test" );
if ($link === false ){
die ("Error: Could not connect." .mysqli_connect_error());
}
$sql = "SELECT * FROM characters WHERE race='Human' ORDER BY level DESC LIMIT 1, 3 " ;
if ($result = mysqli_query($link, $sql)){
if (mysqli_num_rows($result) > 0 ){
echo "<table style='border:1px solid gold;'><tr>" ;
echo "<th style='border:1px solid red;'>Id</th><th style='border:1px solid red;'>Name</th><th style='border:1px solid red;'>Race</th><th style='border:1px solid red;'>Occupation</th><th style='border:1px solid red;'>Level</th>" ;
echo "</tr>" ;
while ($row = mysqli_fetch_array($result)){
echo "<tr style='border:1px solid red;'>" ;
echo "<td style='border:1px solid blue;'>" .$row['id' ]."</td>" ;
echo "<td style='border:1px solid blue;'>" .$row['name' ]."</td>" ;
echo "<td style='border:1px solid blue;'>" .$row['race' ]."</td>" ;
echo "<td style='border:1px solid blue;'>" .$row['occupation' ]."</td>" ;
echo "<td style='border:1px solid blue;'>" .$row['level' ]."</td>" ;
echo "</tr>" ;
}
echo "</table>" ;
mysqli_free_result($result);
}else {
echo "No records matched." ;
}
}else {
echo "Error: Could not execute $sql." .mysqli_error($link);
}
mysqli_close($link);
?>
WHERE, ORDER BY跟LIMIT不需同時出現,但出現順序須為WHERE, ORDER BY, LIMIT。
ORDER BY可使用ASC(升冪)或DESC(降冪)修飾。
LIMIT 1, 3表示1,2,3三筆資料,從0開始算起,若是僅有一個數字(e.g. LIMIT 3),表示限定前3筆資料。
And & Or
php6_5_selectAndOr.php
<?php
$link = mysqli_connect("127.0.0.1" , "root" , "" , "test" );
if ($link === false ){
die ("Error: Could not connect." .mysqli_connect_error());
}
$sql = "SELECT * FROM characters WHERE occupation IN ('Warrior','Mage','Priest') AND level BETWEEN 6 AND 10" ;
if ($result = mysqli_query($link, $sql)){
if (mysqli_num_rows($result) > 0 ){
echo "<table style='border:1px solid gold;'>" ;
echo "<tr>" ;
echo "<th style='border:1px solid red;'>Id</th>" ;
echo "<th style='border:1px solid red;'>Name</th>" ;
echo "<th style='border:1px solid red;'>Race</th>" ;
echo "<th style='border:1px solid red;'>Occupation</th>" ;
echo "<th style='border:1px solid red;'>Level</th>" ;
echo "</tr>" ;
while ($row = mysqli_fetch_array($result)){
echo "<tr style='border:1px solid red;'>" ;
echo "<td style='border:1px solid blue;'>" .$row['id' ]."</td>" ;
echo "<td style='border:1px solid blue;'>" .$row['name' ]."</td>" ;
echo "<td style='border:1px solid blue;'>" .$row['race' ]."</td>" ;
echo "<td style='border:1px solid blue;'>" .$row['occupation' ]."</td>" ;
echo "<td style='border:1px solid blue;'>" .$row['level' ]."</td>" ;
echo "</tr>" ;
}
echo "</table>" ;
mysqli_free_result($result);
}else {
echo "No records matched." ;
}
}else {
echo "Error: Could not execute $sql." .mysqli_error($link);
}
mysqli_close($link);
?>
使用AND與OR關鍵字來產生邏輯性選擇。
使用IN關鍵字來選擇某些特定數值,使用BETWEEN關鍵字來選擇某範圍內的值。
Update & Delete
使用
UPDATE 關鍵字來更新資料,使用
DELETE 關鍵字來刪除資料。
UPDATE
php6_6_update.php
<?php
$link = mysqli_connect("127.0.0.1" , "root" , "" , "test" );
if ($link === false ){
die ("Error: Could not connect." .mysqli_connect_error());
}
$sql = "UPDATE characters SET occupation='Priest' WHERE name='Alex'" ;
if (mysqli_query($link, $sql)){
echo "Updated successfully" ;
}else {
echo "Error: Could not execute $sql. " .mysqli_error($link);
}
$sql = "SELECT * FROM characters ORDER BY occupation" ;
if ($result = mysqli_query($link, $sql)){
if (mysqli_num_rows($result) > 0 ){
echo "<table style='border:1px solid gold;'>" ;
echo "<tr>" ;
echo "<th style='border:1px solid red;'>Id</th>" ;
echo "<th style='border:1px solid red;'>Name</th>" ;
echo "<th style='border:1px solid red;'>Race</th>" ;
echo "<th style='border:1px solid red;'>Occupation</th>" ;
echo "<th style='border:1px solid red;'>Level</th>" ;
echo "</tr>" ;
while ($row = mysqli_fetch_array($result)){
echo "<tr style='border:1px solid red;'>" ;
echo "<td style='border:1px solid blue;'>" .$row['id' ]."</td>" ;
echo "<td style='border:1px solid blue;'>" .$row['name' ]."</td>" ;
echo "<td style='border:1px solid blue;'>" .$row['race' ]."</td>" ;
echo "<td style='border:1px solid blue;'>" .$row['occupation' ]."</td>" ;
echo "<td style='border:1px solid blue;'>" .$row['level' ]."</td>" ;
echo "</tr>" ;
}
echo "</table>" ;
mysqli_free_result($result);
}else {
echo "No records matched." ;
}
}else {
echo "Error: Could not execute $sql." .mysqli_error($link);
}
mysqli_close($link);
?>
使用SET關鍵字設定某欄位的值,使用WHERE來選擇被修改的資料。
DELETE
php6_6_delete.php
<?php
$link = mysqli_connect("127.0.0.1" , "root" , "" , "test" );
if ($link === false ){
die ("Error: Could not connect." .mysqli_connect_error());
}
$sql = "DELETE FROM characters WHERE id=11" ;
if (mysqli_query($link, $sql)){
echo "Delete data successfully" ;
}else {
echo "Error: Could not execute $sql. " .mysqli_error($link);
}
$sql = "SELECT * FROM characters" ;
if ($result = mysqli_query($link, $sql)){
if (mysqli_num_rows($result) > 0 ){
echo "<table style='border:1px solid gold;'>" ;
echo "<tr>" ;
echo "<th style='border:1px solid red;'>Id</th>" ;
echo "<th style='border:1px solid red;'>Name</th>" ;
echo "<th style='border:1px solid red;'>Race</th>" ;
echo "<th style='border:1px solid red;'>Occupation</th>" ;
echo "<th style='border:1px solid red;'>Level</th>" ;
echo "</tr>" ;
while ($row = mysqli_fetch_array($result)){
echo "<tr style='border:1px solid red;'>" ;
echo "<td style='border:1px solid blue;'>" .$row['id' ]."</td>" ;
echo "<td style='border:1px solid blue;'>" .$row['name' ]."</td>" ;
echo "<td style='border:1px solid blue;'>" .$row['race' ]."</td>" ;
echo "<td style='border:1px solid blue;'>" .$row['occupation' ]."</td>" ;
echo "<td style='border:1px solid blue;'>" .$row['level' ]."</td>" ;
echo "</tr>" ;
}
echo "</table>" ;
mysqli_free_result($result);
}else {
echo "No records matched." ;
}
}else {
echo "Error: Could not execute $sql." .mysqli_error($link);
}
mysqli_close($link);
?>
使用DELETE FROM characters WHERE id=11語法來刪除,其中WHERE用來選擇欲刪除之資料。
再次提醒若要刪除整個TABLE或是DATABASE,使用DROP 關鍵字。
Alter
若是要改變欄位,可以使用關鍵字
ALTER 。
php6_6_alter.php
<?php
$link = mysqli_connect("127.0.0.1" , "root" , "" , "test" );
if ($link === false ){
die ("Error: Could not connect." .mysqli_connect_error());
}
$sql = "ALTER TABLE characters ADD camp VARCHAR(30) DEFAULT 'Alliance'" ;
if (mysqli_query($link, $sql)){
echo "Alter successfully" ;
}else {
echo "Could not alter." ;
}
$sql = "SELECT * FROM characters" ;
if ($result = mysqli_query($link, $sql)){
if (mysqli_num_rows($result) > 0 ){
echo "<table style='border:1px solid gold;'>" ;
echo "<tr>" ;
echo "<th style='border:1px solid red;'>Id</th>" ;
echo "<th style='border:1px solid red;'>Name</th>" ;
echo "<th style='border:1px solid red;'>Race</th>" ;
echo "<th style='border:1px solid red;'>Occupation</th>" ;
echo "<th style='border:1px solid red;'>Level</th>" ;
echo "<th style='border:1px solid red;'>Camp</th>" ;
echo "</tr>" ;
while ($row = mysqli_fetch_array($result)){
echo "<tr style='border:1px solid red;'>" ;
echo "<td style='border:1px solid blue;'>" .$row['id' ]."</td>" ;
echo "<td style='border:1px solid blue;'>" .$row['name' ]."</td>" ;
echo "<td style='border:1px solid blue;'>" .$row['race' ]."</td>" ;
echo "<td style='border:1px solid blue;'>" .$row['occupation' ]."</td>" ;
echo "<td style='border:1px solid blue;'>" .$row['level' ]."</td>" ;
echo "<td style='border:1px solid blue;'>" .$row['camp' ]."</td>" ;
echo "</tr>" ;
}
echo "</table>" ;
mysqli_free_result($result);
}else {
echo "No records matched." ;
}
}else {
echo "Error: Could not execute $sql." .mysqli_error($link);
}
mysqli_close($link);
?>
使用ADD關鍵字來增加欄位。
使用DEFAULT關鍵字來給初始值。
其他語法
假設我們已經建立了一個名為test的資料庫(Database),在hello.php其中建立一個名為players的table,並接受來自index.php中表格的數值,將資料加入到資料庫內。
hello.php
<?php
$link = mysqli_connect("localhost" , "root" , "" , "test" );
if ($link === false ){
die ("Error: Could not connect." .mysqli_connect_error());
}
$sql = "CREATE TABLE IF NOT EXISTS players(
id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50) NOT NULL UNIQUE,
race VARCHAR(50) NOT NULL,
occupation VARCHAR(50) NOT NULL,
level INT NOT NULL DEFAULT 1,
gold INT NOT NULL DEFAULT 0
)" ;
if (mysqli_query($link, $sql)){
echo "Table created successfully.<br>" ;
}else {
echo ("Error: Could not execute $sql." .mysqli_error($link));
}
$name = mysqli_real_escape_string($link, $_REQUEST['name' ]);
$race = mysqli_real_escape_string($link, $_REQUEST['race' ]);
$occupation = mysqli_real_escape_string($link, $_REQUEST['occupation' ]);
$level = mysqli_real_escape_string($link, $_REQUEST['level' ]);
$gold = mysqli_real_escape_string($link, $_REQUEST['gold' ]);
$sql = "INSERT INTO players(name, race, occupation, level, gold) VALUES ('$name', '$race', '$occupation', '$level', '$gold')" ;
if (mysqli_query($link, $sql)){
echo "Record inserted successfully.<br>" ;
}else {
echo ("Error: Could not execute $sql." .mysqli_error($link));
}
echo "<a href='index.php'>Login</a>" ;
?>
index.php
<head>
<title>MySQL Connection</title>
</head>
<body>
<form method="post" action="hello.php" >
<p>
<label for ="name" >Name:</label>
<input type="text" name="name" id="name" >
</p>
<p>
<label for ="race" >Race:</label>
<input type="text" name="race" id="race" >
</p>
<p>
<label for ="occupation" >Occupation:</label>
<input type="text" name="occupation" id="occupation" >
</p>
<p>
<label for ="level" >Level:</label>
<input type="text" name="level" id="level" >
</p>
<p>
<label for ="gold" >Gold:</label>
<input type="text" name="gold" id="gold" >
</p>
<input type="submit" value="Add" >
</form>
</body>
刪除table
用來刪除某特定的table。
<?php
$link = mysqli_connect("127.0.0.1" , "root" , "" , "test" );
if ($link === false ){
die ("Error: Could not connect." .mysqli_connect_error());
}
$tablename = "players" ;
$sql = "DROP TABLE " .$tablename;
if (mysqli_query($link, $sql)){
echo "Table " .$tablename." removed successfully." ;
}else {
echo ("Error: Could not execute $sql." .mysqli_error($link));
}
mysqli_close($link);
?>
其他connect語法
連結資料庫,除了使用mysqli_connect()方法外,也可以使用如下方式:
<?php
$link = new mysqli();
$link->connect("localhost" , "root" , "" , "test" );
if ($link === false ){
die ("Error: Could not connect." .mysqli_connect_error());
}else {
echo ("Connect to database successfully." );
}
$link->close();
?>
取得資料
fetch_row()
也可以使用以下方法取得資料庫中資料:
<head>
<style>
table.tabley{
border: 5 px double lime;
outline: 3 px solid blue;
margin: 20 px 0 px;
width: 100 %;
}
table.tabley th{
border: 1 px solid Chocolate ;
padding: 0 px 0 px 0 px 10 px;
color: darkblue;
font-weight: 300 %;
}
table.tabley td{
border: 1 px solid Chocolate ;
padding: 0 px 10 px 0 px 10 px;
color:
text-align: center;
}
</style>
</head>
<body>
<?php
$link = new mysqli();
$link->connect("localhost" , "root" , "" , "test" );
if ($link === false ){
die ("Error: Could not connect." .mysqli_connect_error());
}else {
echo ("Connect to database successfully.<br>" );
}
$query = 'SELECT id, name, race, occupation, level, gold FROM players ORDER by id' ;
$result = $link->query($query, MYSQLI_STORE_RESULT);
echo "<table class='tabley'><tr><th>ID</th><th>Name</th><th>Race</th><th>Occupation</th><th>Level</th><th>Gold</th></tr>" ;
while (list ($id, $name, $race, $occupation, $level, $gold) = $result->fetch_row()) {
printf("<tr><td>%d</td> <td>%s</td> <td>%s</td> <td>%s</td> <td>%d</td> <td>%d</td></tr>" ,
$id, $name, $race, $occupation, $level, $gold);
}
echo "</table>" ;
echo "Total " .$result->num_rows." records fetched." ;
$link->close();
?>
</body>
MYSQLI_STORE_RESULT:傳回查詢結果於buffer,可以讓使用者使用一次。容易決定總共得到多少筆資料或是跳至某一筆特定資料。此為預設值 。
MYSQLI_USE_RESULT:傳回查詢結果,不是buffered set,表示當需要時可以自server取得資料。無法立即取得資料筆數或是跳至某特定筆資料。當會取得大量資料時,應考慮使用此選項,因為會使用較少記憶體且反應時間較快。
使用$result->num_rows來取得被擷取的資料數。這只用於SELECT,若要決定被INSERT,UPDATE,或DELETE影響的資料數,使用affected_rows() 。
fetch_object()
<head>
<style>
table.tabley{
border: 5 px double lime;
outline: 3 px solid blue;
margin: 20 px 0 px;
width: 100 %;
}
table.tabley th{
border: 1 px solid Chocolate ;
padding: 0 px 0 px 0 px 10 px;
color: darkblue;
font-weight: 300 %;
}
table.tabley td{
border: 1 px solid Chocolate ;
padding: 0 px 10 px 0 px 10 px;
color:
text-align: center;
}
</style>
</head>
<body>
<?php
$link = new mysqli();
$link->connect("localhost" , "root" , "" , "test" );
if ($link === false ){
die ("Error: Could not connect." .mysqli_connect_error());
}else {
echo ("Connect to database successfully.<br>" );
}
$query = 'SELECT id, name, race, occupation, level, gold FROM players ORDER by id' ;
$result = $link->query($query, MYSQLI_STORE_RESULT);
echo "<table class='tabley'><tr><th>ID</th><th>Name</th><th>Race</th><th>Occupation</th><th>Level</th><th>Gold</th></tr>" ;
while ($row = $result->fetch_object()) {
printf("<tr><td>%d</td> <td>%s</td> <td>%s</td> <td>%s</td> <td>%d</td> <td>%d</td></tr>" , $row->id, $row->name, $row->race, $row->occupation, $row->level, $row->gold);
}
echo "</table>" ;
$link->close();
?>
</body>
fetch_array()
<head>
<style>
table.tabley{
border: 5 px double lime;
outline: 3 px solid blue;
margin: 20 px 0 px;
width: 100 %;
}
table.tabley th{
border: 1 px solid Chocolate ;
padding: 0 px 0 px 0 px 10 px;
color: darkblue;
font-weight: 300 %;
}
table.tabley td{
border: 1 px solid Chocolate ;
padding: 0 px 10 px 0 px 10 px;
color:
text-align: center;
}
</style>
</head>
<body>
<?php
$link = new mysqli();
$link->connect("localhost" , "root" , "" , "test" );
if ($link === false ){
die ("Error: Could not connect." .mysqli_connect_error());
}else {
echo ("Connect to database successfully.<br>" );
}
$query = 'SELECT id, name, race, occupation, level, gold FROM players ORDER by name' ;
$result = $link->query($query, MYSQLI_STORE_RESULT);
echo "<table class='tabley'><tr><th>ID</th><th>Name</th><th>Race</th><th>Occupation</th><th>Level</th><th>Gold</th></tr>" ;
while ($row = $result->fetch_assoc()) {
printf("<tr><td>%d</td> <td>%s</td> <td>%s</td> <td>%s</td> <td>%d</td> <td>%d</td></tr>" , $row['id' ], $row['name' ], $row['race' ], $row['occupation' ], $row['level' ], $row['gold' ]);
}
echo "</table>" ;
$link->close();
?>
</body>
fetch_array()可以有輸入參數,分別為MYSQLI_ASSOC、MYSQLI_NUM、MYSQLI_BOTH。使用MYSQLI_ASSOC時,僅能使用名稱來擷取array內的值(i.e. 使用$row['id'],不能使用$row[0]),很明顯MYSQLI_NUM與之相反,而MYSQLI_BOTH則都可以(或是不給輸入參數,因為MYSQLI_BOTH為預設值)。
也可以使用fetch_assoc()代替fetch_array(MYSQLI_ASSOC),效果相同。相當於fetch_row() 。
刪除資料
<head>
<style>
table.tabley{
border: 5 px double lime;
outline: 3 px solid blue;
margin: 20 px 0 px;
width: 100 %;
}
table.tabley th{
border: 1 px solid Chocolate ;
padding: 0 px 0 px 0 px 10 px;
color: darkblue;
font-weight: 300 %;
}
table.tabley td{
border: 1 px solid Chocolate ;
padding: 0 px 10 px 0 px 10 px;
color:
text-align: center;
}
</style>
</head>
<body>
<?php
$link = new mysqli();
$link->connect("localhost" , "root" , "" , "test" );
if ($link === false ){
die ("Error: Could not connect." .mysqli_connect_error());
}else {
echo ("Connect to database successfully.<br>" );
}
$query = 'SELECT id, name, race, occupation, level, gold FROM players ORDER by id' ;
$result = $link->query($query);
echo "<table class='tabley'><tr><th>ID</th><th>Name</th><th>Race</th><th>Occupation</th><th>Level</th><th>Gold</th></tr>" ;
while (list ($id, $name, $race, $occupation, $level, $gold) = $result->fetch_row()) {
printf("<tr><td>%d</td> <td>%s</td> <td>%s</td> <td>%s</td> <td>%d</td> <td>%d</td></tr>" ,
$id, $name, $race, $occupation, $level, $gold);
}
echo "</table>" ;
echo "A total of " .$result->num_rows." records fetched.<br>" ;
$result->free();
$query = 'DELETE FROM players where level = "0"' ;
$result = $link->query($query);
echo "A total of " .$link->affected_rows." records is deleted.<br>" ;
$query = 'SELECT id, name, race, occupation, level, gold FROM players ORDER by name' ;
$result = $link->query($query);
echo "<table class='tabley'><tr><th>ID</th><th>Name</th><th>Race</th><th>Occupation</th><th>Level</th><th>Gold</th></tr>" ;
while ($row = $result->fetch_row()) {
printf("<tr><td>%d</td> <td>%s</td> <td>%s</td> <td>%s</td> <td>%d</td> <td>%d</td></tr>" ,
$row[0 ], $row[1 ], $row[2 ], $row[3 ], $row[4 ], $row[5 ]);
}
echo "</table>" ;
echo "A total of " .$result->num_rows." records fetched.<br>" ;
$result->free();
$link->close();
?>
</body>
更新資料
<head>
<style>
table.tabley{
border: 5 px double lime;
outline: 3 px solid blue;
margin: 20 px 0 px;
width: 100 %;
}
table.tabley th{
border: 1 px solid Chocolate ;
padding: 0 px 0 px 0 px 10 px;
color: darkblue;
font-weight: 300 %;
}
table.tabley td{
border: 1 px solid Chocolate ;
padding: 0 px 10 px 0 px 10 px;
color:
text-align: center;
}
</style>
</head>
<body>
<?php
$link = new mysqli();
$link->connect("localhost" , "root" , "" , "test" );
if ($link === false ){
die ("Error: Could not connect." .mysqli_connect_error());
}else {
echo ("Connect to database successfully.<br>" );
}
$query = 'SELECT id, name, race, occupation, level, gold FROM players ORDER by id' ;
$result = $link->query($query);
echo "<table class='tabley'><tr><th>ID</th><th>Name</th><th>Race</th><th>Occupation</th><th>Level</th><th>Gold</th></tr>" ;
while (list ($id, $name, $race, $occupation, $level, $gold) = $result->fetch_row()) {
printf("<tr><td>%d</td> <td>%s</td> <td>%s</td> <td>%s</td> <td>%d</td> <td>%d</td></tr>" ,
$id, $name, $race, $occupation, $level, $gold);
}
echo "</table>" ;
echo "A total of " .$result->num_rows." records fetched.<br>" ;
$result->free();
$query = 'UPDATE players SET level=level+2 WHERE level < 6' ;
$result = $link->query($query);
echo "A total of " .$link->affected_rows." records is updated.<br>" ;
$query = 'SELECT id, name, race, occupation, level, gold FROM players ORDER by name' ;
$result = $link->query($query);
echo "<table class='tabley'><tr><th>ID</th><th>Name</th><th>Race</th><th>Occupation</th><th>Level</th><th>Gold</th></tr>" ;
while ($row = $result->fetch_row()) {
printf("<tr><td>%d</td> <td>%s</td> <td>%s</td> <td>%s</td> <td>%d</td> <td>%d</td></tr>" ,
$row[0 ], $row[1 ], $row[2 ], $row[3 ], $row[4 ], $row[5 ]);
}
echo "</table>" ;
echo "A total of " .$result->num_rows." records fetched.<br>" ;
$result->free();
$link->close();
?>
</body>
Prepared Statement
<style>
table.tabley{
border: 5 px double lime;
outline: 3 px solid blue;
margin: 20 px 0 px;
width: 100 %;
}
table.tabley th{
border: 1 px solid Chocolate ;
padding: 0 px 0 px 0 px 10 px;
color: darkblue;
font-weight: 300 %;
}
table.tabley td{
border: 1 px solid Chocolate ;
padding: 0 px 10 px 0 px 10 px;
color:
text-align: center;
}
</style>
<?php
$link = mysqli_connect("localhost" , "root" , "" , "test" );
if ($link === false ){
die ("Error: Could not connect." .mysqli_connect_error());
}
$name = mysqli_real_escape_string($link, $_REQUEST['name' ]);
$race = mysqli_real_escape_string($link, $_REQUEST['race' ]);
$occupation = mysqli_real_escape_string($link, $_REQUEST['occupation' ]);
$level = mysqli_real_escape_string($link, $_REQUEST['level' ]);
$gold = mysqli_real_escape_string($link, $_REQUEST['gold' ]);
$query = "INSERT INTO players SET name=?, race=?, occupation=?, level=?, gold=?" ;
$stmt = $link->stmt_init();
$stmt->prepare($query);
$stmt->bind_param('sssii' , $name, $race, $occupation, $level, $gold);
$stmt->execute();
$query = "SELECT id, name, race, occupation, level, gold FROM players ORDER BY id" ;
$stmt->prepare($query);
$stmt->execute();
$stmt->bind_result($id, $name, $race, $occupation, $level, $gold);
echo "<table class='tabley'><tr><th>ID</th><th>Name</th><th>Race</th><th>Occupation</th><th>Level</th><th>Gold</th></tr>" ;
while ($stmt->fetch()){
printf("<tr><td>%d</td> <td>%s</td> <td>%s</td> <td>%s</td> <td>%d</td> <td>%d</td></tr>" ,
$id, $name, $race, $occupation, $level, $gold);
}
echo "</table>" ;
$stmt->close();
$link->close();
echo "<a href='index.php'>Login</a>" ;
?>