Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
06 - PHP & MySQL - OpenWebSchool
Search
openwebschool
August 15, 2012
Programming
1
270
06 - PHP & MySQL - OpenWebSchool
openwebschool
August 15, 2012
Tweet
Share
More Decks by openwebschool
See All by openwebschool
11 - CodeIgniter - OpenWebSchool
openwebschool
1
340
09 - Node.JS - OpenWebSchool
openwebschool
1
390
07 - Javascript - OpenWebSchool
openwebschool
3
340
08 - js frontend & jQuery - OpenWebSchool
openwebschool
3
280
05 - MySQL - OpenWebSchool
openwebschool
1
250
03 - PHP II - OpenWebSchool
openwebschool
2
390
04 - CSS - OpenWebSchool
openwebschool
4
360
01 - W3 intro - OpenWebSchool
openwebschool
3
250
02 - PHP I - OpenWebSchool
openwebschool
3
270
Other Decks in Programming
See All in Programming
『自分のデータだけ見せたい!』を叶える──Laravel × Casbin で複雑権限をスッキリ解きほぐす 25 分
akitotsukahara
1
580
すべてのコンテキストを、 ユーザー価値に変える
applism118
2
950
Kotlin エンジニアへ送る:Swift 案件に参加させられる日に備えて~似てるけど色々違う Swift の仕様 / from Kotlin to Swift
lovee
1
260
イベントストーミング図からコードへの変換手順 / Procedure for Converting Event Storming Diagrams to Code
nrslib
1
510
Node-RED を(HTTP で)つなげる MCP サーバーを作ってみた
highu
0
110
今ならAmazon ECSのサービス間通信をどう選ぶか / Selection of ECS Interservice Communication 2025
tkikuc
20
3.7k
エラーって何種類あるの?
kajitack
5
320
なぜ「共通化」を考え、失敗を繰り返すのか
rinchoku
1
590
GitHub Copilot and GitHub Codespaces Hands-on
ymd65536
1
130
なぜ適用するか、移行して理解するClean Architecture 〜構造を超えて設計を継承する〜 / Why Apply, Migrate and Understand Clean Architecture - Inherit Design Beyond Structure
seike460
PRO
1
710
Enterprise Web App. Development (2): Version Control Tool Training Ver. 5.1
knakagawa
1
120
Beyond Portability: Live Migration for Evolving WebAssembly Workloads
chikuwait
0
400
Featured
See All Featured
Adopting Sorbet at Scale
ufuk
77
9.4k
Side Projects
sachag
455
42k
Balancing Empowerment & Direction
lara
1
380
The Art of Programming - Codeland 2020
erikaheidi
54
13k
Fantastic passwords and where to find them - at NoRuKo
philnash
51
3.3k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
252
21k
Unsuck your backbone
ammeep
671
58k
Designing for humans not robots
tammielis
253
25k
Become a Pro
speakerdeck
PRO
28
5.4k
Building Applications with DynamoDB
mza
95
6.5k
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
17
950
Art, The Web, and Tiny UX
lynnandtonic
299
21k
Transcript
PHP + MySQL Ensky / 林宏昱
PHP & MySQL 以前你可能會這樣用 $link = mysql_connect($host, $id, $pw); mysql_select_db($link,
$db); $q = mysql_query($sql); mysql_close($link); … blablabla
Using MySQLi PHP 組織已經打算將mysql_connect, mysql_query這些 function 刪掉了。 why? http://www.php.net/manual/en/mysqlinfo.api.choosing.php 因為
mysql_ 相關函式推出已經有 10 年了,很 多功能沒有、而且很多功能容易讓使用者疏 忽,而寫出很容易被入侵的程式。
Using MySQLi 所以我這邊介紹的套件,叫做 MySQLi , 他是一套 OO 的 library 。
我們現在就來看看要怎麼用。
MySQLi connect 建立連線 <?php $host = 'localhost'; $ip = 'ensky';
$pw = 'ensky5566'; $db = 'ensky'; $link = new mysqli($host, $id, $pw, $db);
MySQLi connect & close 關閉連線 <?php $link = new mysqli($host,
$id, $pw, $db); $link->query('SET NAMES "UTF8"'); // do something … $link->close();
MySQLi Query • Mysqli 的 Query 比較特別, 他的 return 值是一個
object , 叫做 Mysqli_result , 你可以對那個 object 做一些操作。 • http://www.php.net/manual/en/class.mysqli-result.php
MySQLi Query $sql = 'SELECT * FROM `interest`'; $result =
$link->query($sql); $data = $result->fetch_all(MYSQLI_ASSOC); ref: http://www.php.net/manual/en/mysqli-result.fetch-array.php
Free Result • Query 完要記得把 result free 掉 $result =
$link->query($sql); // 使用 result $result->free(); 這很重要,因為 result 會暫存一些資訊在 database 那邊,而當人數一多的時候就會耗用 很多資源,所以要養成用完就 free 的好習慣。
Num Rows • 有時候你只是想知道有幾行而已,沒有真 的要把資料拿出來,此時要這樣用(當然, 你也可以用 COUNT(*) 語句,那樣更快): $sql =
'SELECT * FROM `interest`'; $result = $link->query($sql); $row_cnt = $result->num_rows; $result->free();
Code Demo - Query
SQL Injection SQL 好用歸好用,可是他有一些很容易疏忽的 地方 … MySQL 有個註解符號,叫做 「 --
」 例如我可以這樣寫 SELECT * FROM user -- read all things from user table 看起來一切都很好
SQL Injection 你在判斷登入的時候阿,可能會這樣寫 $sql = "SELECT * FROM `user`" .
" WHERE `id` = '{$_POST['id']}'" . " AND `pw` = '{$_POST['pw']}'"; 有人傳 ensky / ensky5566 就會變成 SELECT * FROM `user` WHERE `id` = 'ensky' AND `pw` = 'ensky5566' 看起來一切都還是很好
SQL Injection 但駭客們就開始玩你囉 他傳 ' OR 1 = 1 --
到你的 username 裡面 所以 SQL 會變成 SELECT * FROM `user` WHERE `id` = '' OR 1 = 1 -- AND `pw` = ' 隨便填 ' 而此時就悲劇了,後面的判斷密碼部分備註解掉 了,因此他有可能可以直接登入你的系統!
SQL Injection • 更多 sql injection: Google SQL Injection 而網頁設計師當然也發現了這個問題,
因此 MySQLi 有一些過濾字串的函式可以使用, 也有一些方法可以讓你不用再關心字串過濾 問題。
MySQLi escape string 你可以這樣做 $escape_id = $link->real_escape_string($_POST['id']); $escape_pw = $link->real_escape_string($_POST['pw']);
然後後面再開始用 $escape_id和 $escape_pw, MySQLi 會自動幫你轉成不會有問題的字串
MySQLi escape string problem 但是但是,每次都用$link->real_escape_string 不僅很麻煩,而且常常忘記,忘記之後又很 難找到錯誤,不小心就被別人入侵。 所以 MySQL 有提供一個叫做
Prepared statement 的方法幫助你,我這就來介紹一下。
MySQLi Prepared statement
MySQLi Prepared statement • bind_param 的參數 – s -> String
– d -> double – i -> integer – b -> bit stream 還有很多有趣的東西可以玩看看 ref: http://www.php.net/manual/en/class.mysqli-stmt.php
Active Record 不覺得每次這樣寫有點累嗎? $sql = "INSERT INTO `user` (`name`, `email`)"
. " VALUES ('{$name}', '{$email}')"; $link->query($sql);
Active Record 即使改成 prepared statement 還是有點累 $stmt = $link->prepare("INSERT INTO
`user`" . "(`name`, `email`) VALUES(?, ?)"); $stmt->bind_param("ss", $name, $email); $stmt->execute(); $stmt->close();
Active Record 架構魔人就提出了一個 DB 存取概念,叫做 Active record 。 可以讓你使用類似這種用法 $insert_data
= [ "name" => "ensky", "email" => "
[email protected]
" ]; $db->insert('user', $insert_data); 然後還會自動幫你 escape
Active Record update 也很快 $update_data = [ "name" => "ensky1"
]; $db->where("name", "ensky") ->update("user", $update_data); UPDATE `user` SET `name`="ensky1" WHERE `name` = "ensky"
Active Record Select 呢? $result = $db->select('*') ->from('user') ->where('name', 'ensky')
->get()->result_array(); SELECT * FROM `user` WHERE `name` = "ensky"
Active Record Join 也很方便 $db->select('*') ->from('user_interest AS UI') ->join('user AS
U', 'UI.user_id=U.id') ->get()->result_array();
Active Record 講那麼多,讓你心癢難騷很想用, 但我不打算教你怎麼寫出這個東西。
Active Record 因為身為 MySQL + PHP 初學者, 我們要先把基礎打紮實一點, 一開始先純用 MySQLi
來練功夫吧! 等你功夫練紮實之後, 我們再來寫屬於自己的 MySQL Library!
Password and Hash 昨天的作業你有沒有發現一件事? 我們的密碼是存「明碼」! 也就是你一打開 .csv 檔案, 就會直接看到使用者的密碼! 這已經是
15 年前的寫法了, 現在因為資安考量,早就不會這樣寫。
Password and Hash 有一種加密方法呢,叫做單向 hash function , 也就是這個 hash function
他沒有反函數, 只要加密就回不來了的意思。 但同樣的字,總是會加密成同樣的密文。 最常見的加密方法是 md5 和 sha1 了 md5:轉換成 32 位數英文數字 sha1:轉換成 40 位數英文數字
Password and Hash 最基本的加密呢,就是這樣 $hashed_pw = sha1($_POST['pw']); 然後我們就把加密過的密碼存到 db 裡面
可是你會想說,阿我就不知道他原本的密碼 啦,這樣要怎麼判斷他輸的是不是正確?
Password and Hash 很簡單!因為一樣的密碼,加密過的密文每 次都一樣,所以每次 user 傳過來他的密碼,我 就把它加密之後再和資料庫的密碼比對,就 好啦! if
( $dbpassword == sha1($_POST['pw']) ) { // 認證成功! }
Password and Hash 你有空的話其實可以 看看 md5 crack 你會發現有好多網站,都可以破解 md5 加密
過的密碼。 他們其實就只是用暴力法把所有 9 位數以內的 密碼組合的md5結果存起來而已。
Password and Hash 但注重使用者安全的你,可以這樣做 sha1( md5($pw) . sha1($pw) ); 如果還不放心,可以加上一些
salt (自定義字串) 例如說: sha1( md5($pw) . sha1($pw) . sha1('ensky') ); 這樣保證沒有網站破的了吧 XDD
PHP Coding style 其實這可以變成一堂課,只是在那堂課還沒 生出來之前我要稍微提醒一下各位一些細節。 LIVE DEMO 我懶得做投影片了,對不起 QQ
Homework • 把昨天的登入頁面改成 mysql 存 • mysql 可以試著自己包成 class ,或用
mysqli , 或自己拆成不同的檔案,用 require_once 啦進來。 我希望架構部分你可以自己想到比較好的方法。 • 密碼部分要記得使用單向加密函數 • coding style 部分要記得邏輯判斷放上面 • 既然學了 CSS ,你可以考慮將登入介面美化一下