[書摘] 深入淺出 PHP 與 MySQL
PHP 和 MySQL 一直是製作動態網頁熱門的組合,本書透過詼諧有趣的介紹,讓閱讀者可以快速的進入 PHP 和 MySQL 世界當中,製作屬於自己的網頁應用程式。大綱:
1. 序:為靜態網頁增添趣味
2. 連結 MySQL
3. 建立並填寫資料庫
4. Web App
5. 操作檔案資料
6. 資訊安全
7/1. 建立個人化網路應用程式
7/2. 消除重複程式碼
8. 管控好資料
9. 函式
10. 正規表達式
11. 資訊視覺化
12. RSS / Web Service
i. 遺珠之憾
ii. 建置開發環境
iii. 擴充 PHP
一、序:為靜態網頁增添趣味
使用純HTML伺服器只能提供靜態內容(只有當網頁設計師更新網頁內容才會更新),若是使用PHP,則伺服器也可以結合資料庫(新增、擷取、更新、刪除資料)動態產生HTML網頁。事實上,當伺服器執行 PHP 指令稿時,最後產生的結果總是純 HTML / CSS,因此,一旦在伺服器執行完畢,每一篇 PHP 指令稿最後都會被轉換成 HTML / CSS。
待補:使用 PHP 存取表單資料
PHP 指令稿必須存在伺服器,使用 phpinfo() 觀察伺服器是否有安裝 PHP
撰碼規則:
(1) PHP 程式碼多半被包含在 <?php 與 ?> 中
(2) 每個 PHP 陳述式必須以 ; 作結
(3) 如果網頁裡面有任何 PHP 程式碼,最好將其命名為 .php
(4) PHP 變數必須從 $ 開始
變數命名規則:
(1) 變數第一個字元必須是 $
(2) 除了 $ 外變數至少需含一個字元
(3) $ 之後第一字元可以是英文字母或 _ ,後續字母可以是英文字母、_ 或是數字
(4) 空格以及 $ 與 _ 以外的特殊字元不可以使用
(5) 變數名稱習慣用小寫
(6) 若有多個單字習慣用 _ 來分隔
賦值 (assign) 給變數
// assign.php
$name = 'KD';
$_POST 是存放表單資料的超全域特殊變數(關聯式陣列),可以存取到由HTML 中 form 和 input 所 submit 的值(由 name 決定其名稱)
\n 只有在 "" 中才會被脫逸,單引號原始為加工,雙引號會尋找變數
術語:
MySQL 一種讓你利用 SQL 語言將資料儲存到資料庫與資料表,並且從中擷取資料的應用程式。資料庫通常被儲存成硬碟上的檔案。其中 phpMyAdmin 為圖型化工具
(資料存在資料表中,資料表存在資料庫中。資料表 table : 由 row 和 column 組成)
SQL 一種與資料庫應用程式(像是 MySQL)溝通互動的結構化查詢語言
二、連結 MySQL
使用 terminal 來建立 MySQL 資料庫與資料表
(1) 建立 table
待補:CREATE TABLE aliens (
);
(2) 插入值
INSERT INTO table_name () VALUES ()
插入順序和值必須相同
(3) 擷取值
SELECT columns FROM table_name
SELECT * FROM table_name
mysqli_connect() 設定帳戶資訊並連結資料庫
mysqli_query() 使用 SQL 查詢
mysqli_close() 關閉與資料庫連結
die() 會退出指令稿傳回資訊
三、建立並填寫資料庫
(1) 建立資料庫 CREATE DATABASE database_name
(2) 建立資料表,資料表是由 column 和 row 組成
CREATE TABLE table_name (
column_name1 column_type1,
column_name2 column_type2
)
(3) 設定 MySQL 資料類型
-1 CHAR (確切知道字元數)
-2 DEC
-3 DATETIME / TIMESTAMP
-4 VARCHAR(當文字長度會變動)
-5 DATE
-6 BLOB
-7 TEXT
-8 INT
(4) USE database_name
(5) DESCRIBE table_name
(6) DROP TABLE table_name
(7) SELECT * FROM table_name WHERE email='xd@gmail.com'
(8) mysqli_fetch_array() 從資料庫擷取一列資料
(9) DELETE FROM table_name
可以透過結合 WHERE 找出要移除哪些資料列
(10) ALTER TABLE table_name ADD column_name column_type
* PHP 中 SQL 不用使用 ; ,但在 terminal 中要
* 善用 while 迴圈
四、Web App
驗證變數的 PHP 函式
使用 == 可以有效地檢查空字串,但是內建的函式更適合處理這個問題。
(1) isset() 測試變數是否存在,檢驗某資料片段是否存在
(2) empty() 函式進一步判斷變數是否包含空值,PHP 將 0、空字串('', "")、flase 或 NULL 皆視為空值
(3) 善用 if else, ||, &&
(4) $_SERVER[''PHP_SELF] 存放當前指令稿名稱(自我參照)
(5) 使用 foreach 繞行陣列,foreach ( $customers as $customer )
主鍵五個原則:
(1) 主鍵資料不能重複
(2) 主鍵必須有值
(3) 當新資料列被插入時,主鍵必須被設定
(4) 主鍵必須盡可能有效率
(5) 主鍵值不能被改變
五、操作檔案資料
在資料庫裡處理二位元檔案,存檔名(路徑)
改變資料庫內容:
ALTER TABLE table_name DROP COLUMN column_name
ADD COLUM 為資料表增添新欄位(位置不定)
DROP COLUM 從資料表丟棄資料欄
CHANGE COLUMN 改變資料欄的名稱和資料類型
MODIFY COLUMN 改變資料欄的資料類型以及資料表裡的位置
上傳檔案時必須注意 form 的 enctype 屬性值:
form enctype 屬性值 | 內容 |
---|---|
application/x-www-form-urlencoded | 在發送前編碼所有字串(預設值) |
multipart/form-data |
不對字串編碼
在使用表單上傳檔案時必須使用
|
text/plain | 空格轉換成 "+" 加號,但不對特殊字元編碼 |
將檔案名插入資料庫:
INSERT INFO guitarwars VALUES (0, NOW(), '$name', '$score', $screenshot)
使用超全域變數
// file.php
$_FILES['form_name']['name'];
$_FILES['form_name']['type'];
$_FILES['form_name']['size'];
$_FILES['form_name']['tmp_name'];
$_FILES['form_name']['error];
* 上傳檔案會被上傳到伺服器暫時性目錄,暫時性目錄在伺服器上自動被建立,而且通常會有個怪異名稱,裡頭包含一堆字母和數字。不過你不能使用 PHP 控制上傳檔案的初始位置(可以透過改PHP初始話檔案 php.ini 來改初始儲存位置),但是可以在上傳檔案後將檔案移到另一個位置(通常為 images 資料夾)。PHP 函式 move_uploaded_file() 接受檔案的來源和目的位置,然後處理移動檔案相關工作
move_uploaded_file($_FILES['form_name']['tmp_name'], [$target]);
兩者最大的差異在於使用方式、使用彈性和效能的不同,once 則是引入過後就不會在引入了
require() 通常放在 PHP 程式的最前面,文件內容直接替換,效能較佳,腳本停止產生 fatal error
require_once()
include() 使用到才讀取,效能較不佳,產生 warning
include_once()
define() 定義常數
ASC 上升
DESC 下降
MIME gif / jpeg / pjpeg / png
@unlink($FILES[''form_name]['tmp_name']) 抑制錯誤,刪除檔案
$_POST / $_GET
POST 請求只能透過表單被啟動
用來將資料傳送給伺服器,會以某種方式改變伺服器的狀態,像是將資料插入資料庫。資料可以在回應中被傳回,透過POST 資料會隱藏起來。
GET 請求可以被包成 URL
通常用來向資料庫要求資料,但不會改變伺服器狀態。對小量資料來說,GET 可用來將它們直接透過 URL 傳送給伺服器,一般傳送小量資料。
DELETE FROM table_name
WHERE name = '' AND score = ''
LIMIT 1
ORDER BY column
六、資訊安全
(1) 用密碼保護 admin 頁面(例如:HTTP 認證)
$_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']
HTTP 認證需要標頭(不能登出)
GET /index.php HTTP/1
Host: www.123.com
Connection: close
User-Agent: Mozilla/ 5.0
Accept-Charset: ISO-8859-1
Cache-Control: no
Accept-Language: de, en; q=0.7
HTTTP/ 1.1 200 ok
Date: Thu, 01 May 2008
Server: Apache/2.0.54
X-Powered-By: PHP/5.2.5
Transfer-Encoding: chunked
Content-Type: text/html
HTML 內容
* header('Content-Type: text/html')
header函式讓你從 PHP 指令稿建立及傳送標頭
(1) header('Location: http://google.com');
(2) header('Refresh: 5, url: http://www.123.com');
(3) header('Content-Type: text/plain');
(4) header('HTTP/1.1 401Unauthorized');
(5) header('WWW-Authenticate: Basic realm=""');
***** 在 PHP 世界裡 header() 會最先傳送,所以連一個空格都不能出現在其之前
(2) 檢查試圖存取 admin 頁面之電腦 IP 位置,只允許特定電腦存取管理頁面
(3) 建立使用者註冊系統,只提供某些使用者管理權限
(4) 乾脆拿掉修改功能
(5) 密碼加密,加 salt
** SQL injection
利用某種方式調整 SQL 查詢,已不正當手法存取資料庫資料
在 SQL 中,(-- ) 被用來將 SQL 註解
(還有 # 單行,/**/ 多行註解)
INSERT INTO guitarwars
VALUES(0, NOW(), 'KD', '1000', 'XD.gif') -- 前面空格後的忽略掉,強制核可為 1
表單驗證是一種解法,在查詢前,先用 trim() 處理空格,並用mysqli_real_escape_string($dbc, trim($_POST[''name])) 脫逸字元
*盡量指定預設值和自動遞增 DEFAULT
empty()
is_numeric()
exit() 強制停止
七、建立個人化網路應用程式
建立註冊登入系統
ALTER TABLE user ADD username VARCHAR(32) NOT NULL AFTER user_id, ADD password VARCHAR(16) NOT NULL AFTER username
密碼必須加密,使用SHA()為密碼進行編碼,因為SHA()是MySQL函式,而不是PHP函式,你是在把密碼插入資料表的查詢中呼叫它(一般認為 SHA 比 MD5 安全)
Cookie
名稱 / 值 / 可設定逾期時間
可以跨多個指令稿和期程
setcookie('username', 'KD');
echo $_COOKIE['username'];
Session
和 cookie 不同,存在伺服器端,比較安全些。在期程結束後自動銷燬(通常為關掉瀏覽器)
session_start();
session_destroy();
資料大小比較大
登出:
(1) 刪除期程變數
$_SESSION =array();
(2) 看cookie 是否存在,有就刪除
setcookie(session_name(), '', time()-3600)
(3) 銷燬期程
session_destroy();
(4) 把使用者導回主頁面
header('Location: http://123.com')
期程 + cookie = 良好的登入永續性
樣板是一組包含檔的集合,但這個集合被特別設計來將應用程式分解成多個功能元件,目標讓頁面本身單純化,機它簡化成只包含真正獨特內容,因此頁頭、頁腳、瀏覽選單,獨立出來,讓其他程式參照
八、管控好資料
資料分類、主題、回應
Schema
資料庫裡的資料表和資料欄,加上任何其他關連物件以及它們被聯繫起來的方式被稱為Schema
Diagram 是資料庫的視覺化表法,包含有關負責聯繫不同資料表之特定資料欄的細節資訊
主鍵 / 外鍵
主鍵必需與各自外鍵相配,為參考完整性
(1) 一對一
(2) 一對多
(3) 多對多 多個資料列對應多個資料列
三元運算子 ? :
消除資料庫重複資料,以合理一致的方式拆解合併資料表為正規化過程(不可以切個資料,原子性)
減少空間,效率較快
(1) 確保資料欄不可分割
(2) 每個資料表都有自己的主鍵
(3) 確保非鍵欄不彼此依賴
* 使用USING 代替 ON ,讓比對共通資料欄的內聯結查詢更簡明
AS name 建立別名 / USING / ON
Inner join
九、函式
LIKE '%物理治療%'
SQL查詢不分大小寫
explode() 提供分隔符變成陣列
implode() 子字串陣列建立單一字串
substr() 抓取字串
str_replace()
自定函數
switch
LIMIT
十、正規表達式
正規表達式
preg_match()
preg_replace()
checkdnserr() 確認DNS
字元類 [A-Z]
\d, \w, \s, ^, $
十一、資訊視覺化
CAPTCHA
GD 程式庫
imageline()
imagerectangle()
imageong()
imagecreatetruecolor()
imagestring()
imagestringup()
imagegettftext()
imagedestroy()
十二、RSS / Web Service
XML
RSS
REST
simplexml_load_file()
SimpleXMLElement
名稱空間
i. 遺珠之憾
(1) 針對PHP 4 MySQL函式調整
mysql_connect ...
(2) MySQL 的用戶許可
(3) 錯誤報告
(4) 例外處理
(5) 物件導向
(6) 保護應用程式
(7) 跨網站指令稿攻擊
(8) 運算子優先順序
(9) PHP 5 / PHP 6
(10) 重複運用 PHP
ii. 建置開發環境
iii. 擴充 PHP
參考文件:
1. 深入淺出 PHP 與 MySQL (Head First PHP & MySQL)
2. 書籍官方參考代碼
3. HTML <form> 标签的 enctype 属性
4. PHP include()和require()方法的区别