php.ini裡儲存了關於php設定的資訊
有些設定可以考慮做些改變
另外這篇文章也會提到避免網站受到script攻擊
用文字編輯器打開php.ini
safe_mode
假如設定成on,會使得php網頁不能夠被相同伺服器上其他使用者的php網頁呼叫
open_basedir = directory[:...]
限制了PHP對目錄的存取能力,也影響了他能夠執行的檔案
display_errors
假如網站錯誤而不想讓網站參觀者知道,把這選項設定成off
log_errors
將錯誤送到錯誤記錄,是個檢查錯誤的好地方
如果display_errors設定成off,這個選項設定成on
可以讓自己知道問題原因而不會洩露給網站參觀者
error_log
這裡會儲存錯誤記錄的存放位置, log_errors設定成on時可以關注這個選項
script攻擊是應用injection attack
將script碼輸入到沒有防範的填寫格中
可以做到重新導引瀏覽器到別的網站,例如類似的假網站來盜取資料
又或者是盜取cookie等手法
防範的手法包括盡量做驗證或者是使用PHP函式
PHP函式中的strip_tags()可以幫助去除script攻擊
另外,以正規表示法防範不該出現的字元或符號也是一種方法
2010年5月31日 星期一
PHP筆記(4)
這篇會提到
1.xml相關處理
2.錯誤與例外處理
3.善用print_r()函式
1.xml相關處理
範例:
$xml = simplexml_load_file($URL);
$entry = $xml->entry;
$attrs = $xml->entry->video->duration->attributes();
$media = $entry->children($URL);
使用simplexml_load_file()可以簡單取得XML的資訊
使用時加入XML提供方的link當參數即可
存取XML資料時會以階層性質來使用,指定標籤名稱可存取階層資訊
->符號以物件形式來看,會是從xml物件裡面取得子元素
然後利用 attributes()取得資訊
第三個程式碼擷取duration標籤,並用attributes()以陣列形式取得值
children這個方法可以回傳一個內含特定名稱空間內所有子元素的陣列
也可以跟 attributes()做很好的搭配
2.錯誤與例外處理
分別從MySQL與PHP來看錯誤處理
通常SQL碼的處理方式是
mysqli_connect(localhost, $account, $pw) or die('Couldn't connect !');
die()這個函式會在錯誤發生時被呼叫
但假如想知道詳細發生的訊息可用 or die(mysqli_error($db_link)) 來得知
PHP部分的例外處理則類似Java的例外處理,如下範例
function checkBalance($balance){
if($balance < 1000) {
throw new Exception("Balance is less than 1000");
}
return true;
}
try{
checkBalance(1);
echo 'Balance is above 1000';
}catch(Exception $e){
echo 'Error:'.$e->getMessage();
}
執行結果是Balance is less than 1000
3.善用print_r()函式
print_r()函式可以用來輸出變數的值或是字串
debug時最需要的就是確認變數的值有沒有如想像中的傳入或改變
善用這點就可以確認變數的狀態
1.xml相關處理
2.錯誤與例外處理
3.善用print_r()函式
1.xml相關處理
範例:
$xml = simplexml_load_file($URL);
$entry = $xml->entry;
$attrs = $xml->entry->video->duration->attributes();
$media = $entry->children($URL);
使用simplexml_load_file()可以簡單取得XML的資訊
使用時加入XML提供方的link當參數即可
存取XML資料時會以階層性質來使用,指定標籤名稱可存取階層資訊
->符號以物件形式來看,會是從xml物件裡面取得子元素
然後利用 attributes()取得資訊
第三個程式碼擷取duration標籤,並用attributes()以陣列形式取得值
children這個方法可以回傳一個內含特定名稱空間內所有子元素的陣列
也可以跟 attributes()做很好的搭配
2.錯誤與例外處理
分別從MySQL與PHP來看錯誤處理
通常SQL碼的處理方式是
mysqli_connect(localhost, $account, $pw) or die('Couldn't connect !');
die()這個函式會在錯誤發生時被呼叫
但假如想知道詳細發生的訊息可用 or die(mysqli_error($db_link)) 來得知
PHP部分的例外處理則類似Java的例外處理,如下範例
function checkBalance($balance){
if($balance < 1000) {
throw new Exception("Balance is less than 1000");
}
return true;
}
try{
checkBalance(1);
echo 'Balance is above 1000';
}catch(Exception $e){
echo 'Error:'.$e->getMessage();
}
執行結果是Balance is less than 1000
3.善用print_r()函式
print_r()函式可以用來輸出變數的值或是字串
debug時最需要的就是確認變數的值有沒有如想像中的傳入或改變
善用這點就可以確認變數的狀態
2010年5月30日 星期日
PHP繪圖處理
這篇會寫到PHP實作圖像的部分
會寫一個 CAPTCHA的範例
提到的函式還有轉換數字到ASCII字元的chr()函式、rand()函式等
CAPTCHA是指確認使用者端是否為人類使用,而非機器人程式的測試
一般常見的圖像認證碼即是一例
CAPTCHA範例:
首先實作一個隨機產生文字字串的程式
define('CAPTCHA_NUMBER', 5);
//generate the random pass-phrase
$pass_phrase = "";
for($i = 0; $i < CAPTCHA_NUMBER; i++){
$pass_phrase .= chr(rand(97, 122));
}
chr()函式將數字轉換成相對應的ASCII字元,數字97會被轉換成'a'
rand()函式當然就是回傳隨機整數
回傳範圍可以設定在指定範圍,或者是o與內建常數RAND_MAX(server設定)內
接著就是要產生圖像
define('CAPTCHA_WIDTH', 100);
define('CAPTCHA_HEIGHT', 25);
//create the image, make black background
$img = imagecreatetruecolor(CAPTCHA_WIDTH, CAPTCHA_HEIGHT);
//set a white background with black text and gray graphics
$bg_color = imagecolorallocate($img, 255, 255, 255); //white
$text_color = imagecolorallocate($img, 0, 0, 0); //black
$graphic_color = imagecolorallocate($img, 64, 64, 64); //dark gray
//fill the background
imagefilledrectangle($img, 0, 0, CAPTCHA_WIDTH, CAPTCHA_HEIGHT, $bg_color);
//draw some random lines
for($i = 0, $i < 5, $i++){
imageline($img, 0, rand() % CAPTCHA_HEIGHT, CAPTCHA_WIDTH,
rand() % CAPTCHA_HEIGHT, $graphic_color);
}
//sprinkle in some random dots
for($i = 0, $i < 50, $i++){
imagesetpixel($img, rand() % CAPTCHA_WIDTH, rand() % CAPTCHA_HEIGHT, $graphic_color);
}
//draw the pass-phrase string
imagettftext($img, 18, 0, 5,CAPTCHA_HEIGHT - 5, $text_color,
'Courier New Bold.ttf', $pass_phrase);
//output the image as a PNG using a header
header("Content-type: image/phg");
imagepng($img);
//release the image from memory
imagedestroy($img);
imagecreatetruecolor()函式在記憶體裡準備繪製用的空白圖像
imagefilledrectangle()可用來填滿它的顏色
回傳值是一個image identifier,通常是大多數GD繪圖函式需要的第一個參數
imagecolorallocate()是用來配色用的
第一個參數是image identifier,後面三個參數是RGB數值
imageline()函式的第2、3參數是線段起點
imagerectangle()會填滿顏色在參數裡所涵蓋的範圍
imagegettftext()可以用特定字體來繪製文字
使用時必須先將字體放置於伺服器上
字體檔通常具有.ttf副檔名
函式的座標位置是第一個字元的左下角
第2個參數是大小,第3個參數是字體角度,以逆時針方向計算
第4、5參數則是作標位置
imagepng()函式會將圖像輸出到client端的browser上
假如選擇直接創造圖象到記憶體中,而不是採取賦予檔名的方式
要呼叫header()函式幫助傳送到瀏覽器
如果要儲存圖像則在imagepng()函式裡面多加入參數
imagepng($img, $filename, 5);
$filename要輸入完整的路徑名稱,參數5代表壓縮程度中等
這樣就能夠寫入檔案到png檔
imagedestroy() 函式可以釋放記憶體空間
使用完畢之後就用imagedestroy($img);
成功清除會回傳true
沒提到的函式還有
imageellipse()是在這例子裡面沒有的畫圓函式
他的參數是中心點位置和寬度、高度,顏色用最後一個參數填入
imagefilledellipse()可以用來填滿它,接受的參數和圓函式相同
imagestring()函式則是用PHP的內建字體來繪製字串圖像
使用範例為 imagestring($img, 3, 75, 75, 'Sample', $color);
第2個參數是字體大小,範圍是1~5
第3、4函數是座標
imagestringup()類似imagestring(),參數也一樣
但顯示效果則是逆時針旋轉90度的直立輸出
接著寫一段html碼
<label for="verify">Verification:</label>
<input type="text" id="verify" name="verify" value="Enter the phrase" />
<img src="source.php" alt="Verification pass-phrase" />
圖片來源就修改下本篇的程式碼來接上即可
會寫一個 CAPTCHA的範例
提到的函式還有轉換數字到ASCII字元的chr()函式、rand()函式等
CAPTCHA是指確認使用者端是否為人類使用,而非機器人程式的測試
一般常見的圖像認證碼即是一例
CAPTCHA範例:
首先實作一個隨機產生文字字串的程式
define('CAPTCHA_NUMBER', 5);
//generate the random pass-phrase
$pass_phrase = "";
for($i = 0; $i < CAPTCHA_NUMBER; i++){
$pass_phrase .= chr(rand(97, 122));
}
chr()函式將數字轉換成相對應的ASCII字元,數字97會被轉換成'a'
rand()函式當然就是回傳隨機整數
回傳範圍可以設定在指定範圍,或者是o與內建常數RAND_MAX(server設定)內
接著就是要產生圖像
define('CAPTCHA_WIDTH', 100);
define('CAPTCHA_HEIGHT', 25);
//create the image, make black background
$img = imagecreatetruecolor(CAPTCHA_WIDTH, CAPTCHA_HEIGHT);
//set a white background with black text and gray graphics
$bg_color = imagecolorallocate($img, 255, 255, 255); //white
$text_color = imagecolorallocate($img, 0, 0, 0); //black
$graphic_color = imagecolorallocate($img, 64, 64, 64); //dark gray
//fill the background
imagefilledrectangle($img, 0, 0, CAPTCHA_WIDTH, CAPTCHA_HEIGHT, $bg_color);
//draw some random lines
for($i = 0, $i < 5, $i++){
imageline($img, 0, rand() % CAPTCHA_HEIGHT, CAPTCHA_WIDTH,
rand() % CAPTCHA_HEIGHT, $graphic_color);
}
//sprinkle in some random dots
for($i = 0, $i < 50, $i++){
imagesetpixel($img, rand() % CAPTCHA_WIDTH, rand() % CAPTCHA_HEIGHT, $graphic_color);
}
//draw the pass-phrase string
imagettftext($img, 18, 0, 5,CAPTCHA_HEIGHT - 5, $text_color,
'Courier New Bold.ttf', $pass_phrase);
//output the image as a PNG using a header
header("Content-type: image/phg");
imagepng($img);
//release the image from memory
imagedestroy($img);
imagecreatetruecolor()函式在記憶體裡準備繪製用的空白圖像
imagefilledrectangle()可用來填滿它的顏色
回傳值是一個image identifier,通常是大多數GD繪圖函式需要的第一個參數
imagecolorallocate()是用來配色用的
第一個參數是image identifier,後面三個參數是RGB數值
imageline()函式的第2、3參數是線段起點
imagerectangle()會填滿顏色在參數裡所涵蓋的範圍
imagegettftext()可以用特定字體來繪製文字
使用時必須先將字體放置於伺服器上
字體檔通常具有.ttf副檔名
函式的座標位置是第一個字元的左下角
第2個參數是大小,第3個參數是字體角度,以逆時針方向計算
第4、5參數則是作標位置
imagepng()函式會將圖像輸出到client端的browser上
假如選擇直接創造圖象到記憶體中,而不是採取賦予檔名的方式
要呼叫header()函式幫助傳送到瀏覽器
如果要儲存圖像則在imagepng()函式裡面多加入參數
imagepng($img, $filename, 5);
$filename要輸入完整的路徑名稱,參數5代表壓縮程度中等
這樣就能夠寫入檔案到png檔
imagedestroy() 函式可以釋放記憶體空間
使用完畢之後就用imagedestroy($img);
成功清除會回傳true
沒提到的函式還有
imageellipse()是在這例子裡面沒有的畫圓函式
他的參數是中心點位置和寬度、高度,顏色用最後一個參數填入
imagefilledellipse()可以用來填滿它,接受的參數和圓函式相同
imagestring()函式則是用PHP的內建字體來繪製字串圖像
使用範例為 imagestring($img, 3, 75, 75, 'Sample', $color);
第2個參數是字體大小,範圍是1~5
第3、4函數是座標
imagestringup()類似imagestring(),參數也一樣
但顯示效果則是逆時針旋轉90度的直立輸出
接著寫一段html碼
<label for="verify">Verification:</label>
<input type="text" id="verify" name="verify" value="Enter the phrase" />
<img src="source.php" alt="Verification pass-phrase" />
圖片來源就修改下本篇的程式碼來接上即可
PHP與正規表示法
正規表示法是用來比對使用者所輸入的字串規格
例如今天需要使用者輸入一筆電話號碼
要求的格式假如是 000 - 11111111
使用者假如輸入00 - 11111111,就會被事先設定的正規表示法排除
本篇介紹PHP使用正規表示法的方式
ps.提醒:正規表示法在不同語言裡有些微不同
正規表示法範例:
/^\(?[2-9]\d{2}\)?[-\s]\d{3}-\d{4}$/
每一段正規表示法都必需要包含在 / / 裡面
若要比對確實的數字如1234,那就用/1234/
^ 代表以所要的字串規則開頭,ex. ^abc = 比對abc開頭的字串
$則代表以所要的字串規則結束
如果不加$的話,^abc 的比對也會判定abcd是對的
所以如果要做嚴格的判斷一定要加上頭尾的符號
\d 比對 0 - 9的數字的一個字元
\w 比對 a - z & A -Z & 0 - 9的一個字元
\s可以比對一個空白字元,包含Tab的跳格字元或是換行字元等
. 比對出換行字元以外的任何字元
{ }裡面可以放進最多兩個參數,作用是設定前面字元或中介符號應有的數目
例如\d{2, 4} ,表示可比對出連續2到4個數字的資料,00、111、1234都對
[]可對比出設定範圍的字元,[0-2]對比出0、1、2,[A-C]對比出A、B、C
在[]中使用^的意思表示不要符合,[^3-9]可比對出0、1、2
+表示前面的字元或中介符號應該出現一次或多次
*表示前面的字元或中介符號應該出現一次或多次或是都不要出現
?表示前面的字元或中介符號應該出現一次或是都不要出現
注意若只是想使用這類符號就必須脫逸,例如\?就可比對出?
至於PHP裡面用來做比對的函式有preg_match()
它的使用方式是preg_match($regex, $my_string)
第一個參數是正規表示法,第二個參數是要比對的目標字串
因為傳進來的類別都必須是字串,正規表示法要記得加上引號
成功就回傳true
另外一個跟正規表示法有關的函式是preg_replace()
它的使用方法是preg_replace($pattern, $replacement, $my_string)
他的功用是找出不想要的字元並將他替換成我們需要的字元
例如:
$test = preg_replace('/100[0-9]/', '100', 'I have 1000 dollars');
修正後的結果會存到$test裡,成為I have 100 dollars
PHP裡提供一個checkdnsrr()函式
他可以檢查網域名稱的正確性
在裡面以字串的方式輸入@以後的網址,例如'yahoo.com.tw'
假使網域存在時會回傳1,否則就回傳0
注意一點是這個函式在Linux上沒有問題
在windows若發生問題的話則使用以下程式碼
function win_checkdnsrr($domain, $recType = ''){
if(!empty($domain)){
if($recType == '') $recType = "MX";
exec(nslookup -type=$recType $domain", $output);
//exe呼叫執行在伺服器上的外部程式
foreach($output as $line){
if(preg_match("/^$domain/", $line)){
return true;
}
}
return false;
}
return false;
}
結合起來的驗證用戶e-mail網址的程式如下
if (!preg_match('/^[a-zA-Z0-9][a-zA-Z0-9\._\-&!?=#]*@/', $email)) {
// $email is invalid because LocalName is bad
echo '<p class="error">Your email address is invalid.</p>';
$output_form = 'yes';
}
else {
// Strip out everything but the domain from the email
$domain = preg_replace('/^[a-zA-Z0-9][a-zA-Z0-9\._\-&!?=#]*@/', '', $email);
// Now check if $domain is registered
if (!checkdnsrr($domain)) {
echo '<p class="error">Your email address is invalid.</p>';
$output_form = 'yes';
}
}
例如今天需要使用者輸入一筆電話號碼
要求的格式假如是 000 - 11111111
使用者假如輸入00 - 11111111,就會被事先設定的正規表示法排除
本篇介紹PHP使用正規表示法的方式
ps.提醒:正規表示法在不同語言裡有些微不同
正規表示法範例:
/^\(?[2-9]\d{2}\)?[-\s]\d{3}-\d{4}$/
每一段正規表示法都必需要包含在 / / 裡面
若要比對確實的數字如1234,那就用/1234/
^ 代表以所要的字串規則開頭,ex. ^abc = 比對abc開頭的字串
$則代表以所要的字串規則結束
如果不加$的話,^abc 的比對也會判定abcd是對的
所以如果要做嚴格的判斷一定要加上頭尾的符號
\d 比對 0 - 9的數字的一個字元
\w 比對 a - z & A -Z & 0 - 9的一個字元
\s可以比對一個空白字元,包含Tab的跳格字元或是換行字元等
. 比對出換行字元以外的任何字元
{ }裡面可以放進最多兩個參數,作用是設定前面字元或中介符號應有的數目
例如\d{2, 4} ,表示可比對出連續2到4個數字的資料,00、111、1234都對
[]可對比出設定範圍的字元,[0-2]對比出0、1、2,[A-C]對比出A、B、C
在[]中使用^的意思表示不要符合,[^3-9]可比對出0、1、2
+表示前面的字元或中介符號應該出現一次或多次
*表示前面的字元或中介符號應該出現一次或多次或是都不要出現
?表示前面的字元或中介符號應該出現一次或是都不要出現
注意若只是想使用這類符號就必須脫逸,例如\?就可比對出?
至於PHP裡面用來做比對的函式有preg_match()
它的使用方式是preg_match($regex, $my_string)
第一個參數是正規表示法,第二個參數是要比對的目標字串
因為傳進來的類別都必須是字串,正規表示法要記得加上引號
成功就回傳true
另外一個跟正規表示法有關的函式是preg_replace()
它的使用方法是preg_replace($pattern, $replacement, $my_string)
他的功用是找出不想要的字元並將他替換成我們需要的字元
例如:
$test = preg_replace('/100[0-9]/', '100', 'I have 1000 dollars');
修正後的結果會存到$test裡,成為I have 100 dollars
PHP裡提供一個checkdnsrr()函式
他可以檢查網域名稱的正確性
在裡面以字串的方式輸入@以後的網址,例如'yahoo.com.tw'
假使網域存在時會回傳1,否則就回傳0
注意一點是這個函式在Linux上沒有問題
在windows若發生問題的話則使用以下程式碼
function win_checkdnsrr($domain, $recType = ''){
if(!empty($domain)){
if($recType == '') $recType = "MX";
exec(nslookup -type=$recType $domain", $output);
//exe呼叫執行在伺服器上的外部程式
foreach($output as $line){
if(preg_match("/^$domain/", $line)){
return true;
}
}
return false;
}
return false;
}
結合起來的驗證用戶e-mail網址的程式如下
if (!preg_match('/^[a-zA-Z0-9][a-zA-Z0-9\._\-&!?=#]*@/', $email)) {
// $email is invalid because LocalName is bad
echo '<p class="error">Your email address is invalid.</p>';
$output_form = 'yes';
}
else {
// Strip out everything but the domain from the email
$domain = preg_replace('/^[a-zA-Z0-9][a-zA-Z0-9\._\-&!?=#]*@/', '', $email);
// Now check if $domain is registered
if (!checkdnsrr($domain)) {
echo '<p class="error">Your email address is invalid.</p>';
$output_form = 'yes';
}
}
2010年5月29日 星期六
PHP筆記(3)
這篇提到
1.SQL碼整理
2.拆解字串函式 explode() 與結合字串函式 implode()
3.字元替換函式str_replace()
4.擷取字元函式 substr()
5.自訂函式寫法
1.SQL碼整理
$query = "SELECT mr.response_id, mr.topic_id, mr.response, mt.name AS topic_name " .
"FROM mismatch_response AS mr " .
"INNER JOIN mismatch_topic AS mt USING (topic_id) " .
"WHERE mr.user_id = '" . $_SESSION['user_id'] . "'";
SQL的AS關鍵字建立別名,如例子中的mismatch_topic被命名為mt
INNER JOIN是內聯結的陳述,會從FROM與JOIN提到的表作查詢
只有都符合條件的查詢才回被回傳
USING是簡化SQL碼的陳述
例子中可改成ON( mismatch_topic.topic_id = mismatch_response.topic_id)
兩張表裡都有相同的欄位名稱才可以這樣使用
SELECT xx FROM table WHERE xx LIKE '%world%'
Like的關鍵字可以尋找跟引號裡的字眼不完全相同的模糊比對
萬用字元%可以替代單字前後的任何字元
MySQL預設的搜尋是不分大小
所以可以找到 HelloWorld、 hello world 、wOrld這些資料
SELECT xx FROM table WHERE xx LIKE '____world%'
搜尋到的資料就必須是任意四字元後接world的資料,例如aaaaworldd
前面的字元數端視 _ 符號的數量
SELECT * FROM table ORDER BY title LIMIT 5
ORDER BY這個關鍵詞用在句尾,可以針對查詢做排列
針對title作降冪排列
當然排列的依據是數值或字元的大小順位
LIMIT 5 讓不管查詢到多少資料都只回傳前五筆
如果是 LIMIT 10, 5
第一個引數是要跳過多少筆資料,第二個引數是要擷取多少資料
善用的話可以做出將查詢結果分頁的效果
搭配PHP函式使用時有一些地方要注意
使用mysqli_query()時,若查詢的變數型別並不符合該欄位的型別
會回傳一個false值
而若查詢到的是空值(null)
則必須要進一步使用mysqli_fetch_array()函式
這函式會在查詢到空值時回傳false
2.拆解字串函式 explode() 與結合字串函式 implode()
explode()使用範例
$sarray = explode(' ', 'Tyler Clippard is awsome !');
第二個參數是想分解的字串,依照第一個參數代表的分隔符號來分割
之後在將分割後的字串重送到字串陣列裡面
$sarray[0] = Tyler
implode()使用範例
$clause = implode(' ', $sarray);
第二個參數是要結合的字串陣列,第一個參數是分隔符號
3.字元替換函式str_replace()
使用範例
$replace_string = str_replace('thousands', 'hundreds', 'It worths two thousands ');
第一個參數是要被替換的字元,第二個參數是取代前者的自元,第三個參數是是目標字串
4.擷取字元函式 substr()
使用範例
substr('Yes, we can !', 5, 2)
上式可取得字串 - we
第一個參數是原始字串,第二個參數是擷取位置
字元在原始字串中被給予從0開始的編號,在5這個位置上的字元就是w
第三個參數是截取的字元數
如果在第二個參數輸入負數表是從字串尾巴開始取字元
第三個參數假如不輸入則代表要擷取剩下所有的字元
假如要取得的字元數比剩下字元數還多也是如此,不會在字串尾補上空值
假如要做出常見的"繼續閱讀"之類的功能可以考慮用這個做
5.自訂函式寫法
function funcname($param){
...........
return $var;
}
寫自訂函式時的寫法很寬鬆,宣告不用宣告函式回傳型態
缺點是若有疏忽會比較難以察覺
1.SQL碼整理
2.拆解字串函式 explode() 與結合字串函式 implode()
3.字元替換函式str_replace()
4.擷取字元函式 substr()
5.自訂函式寫法
1.SQL碼整理
$query = "SELECT mr.response_id, mr.topic_id, mr.response, mt.name AS topic_name " .
"FROM mismatch_response AS mr " .
"INNER JOIN mismatch_topic AS mt USING (topic_id) " .
"WHERE mr.user_id = '" . $_SESSION['user_id'] . "'";
SQL的AS關鍵字建立別名,如例子中的mismatch_topic被命名為mt
INNER JOIN是內聯結的陳述,會從FROM與JOIN提到的表作查詢
只有都符合條件的查詢才回被回傳
USING是簡化SQL碼的陳述
例子中可改成ON( mismatch_topic.topic_id = mismatch_response.topic_id)
兩張表裡都有相同的欄位名稱才可以這樣使用
SELECT xx FROM table WHERE xx LIKE '%world%'
Like的關鍵字可以尋找跟引號裡的字眼不完全相同的模糊比對
萬用字元%可以替代單字前後的任何字元
MySQL預設的搜尋是不分大小
所以可以找到 HelloWorld、 hello world 、wOrld這些資料
SELECT xx FROM table WHERE xx LIKE '____world%'
搜尋到的資料就必須是任意四字元後接world的資料,例如aaaaworldd
前面的字元數端視 _ 符號的數量
SELECT * FROM table ORDER BY title LIMIT 5
ORDER BY這個關鍵詞用在句尾,可以針對查詢做排列
針對title作降冪排列
當然排列的依據是數值或字元的大小順位
LIMIT 5 讓不管查詢到多少資料都只回傳前五筆
如果是 LIMIT 10, 5
第一個引數是要跳過多少筆資料,第二個引數是要擷取多少資料
善用的話可以做出將查詢結果分頁的效果
搭配PHP函式使用時有一些地方要注意
使用mysqli_query()時,若查詢的變數型別並不符合該欄位的型別
會回傳一個false值
而若查詢到的是空值(null)
則必須要進一步使用mysqli_fetch_array()函式
這函式會在查詢到空值時回傳false
2.拆解字串函式 explode() 與結合字串函式 implode()
explode()使用範例
$sarray = explode(' ', 'Tyler Clippard is awsome !');
第二個參數是想分解的字串,依照第一個參數代表的分隔符號來分割
之後在將分割後的字串重送到字串陣列裡面
$sarray[0] = Tyler
implode()使用範例
$clause = implode(' ', $sarray);
第二個參數是要結合的字串陣列,第一個參數是分隔符號
3.字元替換函式str_replace()
使用範例
$replace_string = str_replace('thousands', 'hundreds', 'It worths two thousands ');
第一個參數是要被替換的字元,第二個參數是取代前者的自元,第三個參數是是目標字串
4.擷取字元函式 substr()
使用範例
substr('Yes, we can !', 5, 2)
上式可取得字串 - we
第一個參數是原始字串,第二個參數是擷取位置
字元在原始字串中被給予從0開始的編號,在5這個位置上的字元就是w
第三個參數是截取的字元數
如果在第二個參數輸入負數表是從字串尾巴開始取字元
第三個參數假如不輸入則代表要擷取剩下所有的字元
假如要取得的字元數比剩下字元數還多也是如此,不會在字串尾補上空值
假如要做出常見的"繼續閱讀"之類的功能可以考慮用這個做
5.自訂函式寫法
function funcname($param){
...........
return $var;
}
寫自訂函式時的寫法很寬鬆,宣告不用宣告函式回傳型態
缺點是若有疏忽會比較難以察覺
2010年5月26日 星期三
PHP樣板概念
程式碼的重複利用相當重要
它可以幫助減少程式碼的量以及撰寫時花的力氣
最大的好處是提供了維護的方便性
樣板就是將程式分成功能性元件
以下將提供範例:
原件成員:
startsession.php==========
<?php
session_start();
// If the session vars aren't set, try to set them with a cookie
if (!isset($_SESSION['user_id'])) {
if (isset($_COOKIE['user_id']) && isset($_COOKIE['username'])) {
$_SESSION['user_id'] = $_COOKIE['user_id'];
$_SESSION['username'] = $_COOKIE['username'];
}
}
?>
header.php======
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<?php
echo '<title>Mismatch - ' . $page_title . '</title>';
?>
<link rel="stylesheet" type="text/css" href="style.css" />
</head>
<body>
<?php
echo '<h3>Mismatch - ' . $page_title . '</h3>';
?>
navmenu.php==========
<?php
// Generate the navigation menu
echo '<hr />';
if (isset($_SESSION['username'])) {
echo '<a href="index.php">Home</a> ❤ ';
echo '<a href="viewprofile.php">View Profile</a> ❤ ';
echo '<a href="editprofile.php">Edit Profile</a> ❤ ';
echo '<a href="logout.php">Log Out (' . $_SESSION['username'] . ')</a>';
}
else {
echo '<a href="login.php">Log In</a> ❤ ';
echo '<a href="signup.php">Sign Up</a>';
}
echo '<hr />';
?>
footer.php==========
<hr />
<p class="footer">Copyright ©2008 Mismatch Enterprises, Inc.</p>
</body>
</html>
完成品:
index.php============
<?php
// Start the session
require_once('startsession.php');
// Insert the page header
$page_title = 'Where opposites attract!';
require_once('header.php');
require_once('appvars.php');
require_once('connectvars.php');
// Show the navigation menu
require_once('navmenu.php');
// Connect to the database
$dbc = mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME);
// Retrieve the user data from MySQL
$query = "SELECT user_id, first_name, picture FROM mismatch_user WHERE first_name IS NOT NULL ORDER BY join_date DESC LIMIT 5";
$data = mysqli_query($dbc, $query);
// Loop through the array of user data, formatting it as HTML
echo '<h4>Latest members:</h4>';
echo '<table>';
while ($row = mysqli_fetch_array($data)) {
if (is_file(MM_UPLOADPATH . $row['picture']) && filesize(MM_UPLOADPATH . $row['picture']) > 0) {
echo '<tr><td><img src="' . MM_UPLOADPATH . $row['picture'] . '" alt="' . $row['first_name'] . '" /></td>';
}
else {
echo '<tr><td><img src="' . MM_UPLOADPATH . 'nopic.jpg' . '" alt="' . $row['first_name'] . '" /></td>';
}
if (isset($_SESSION['user_id'])) {
echo '<td><a href="viewprofile.php?user_id=' . $row['user_id'] . '">' . $row['first_name'] . '</a></td></tr>';
}
else {
echo '<td>' . $row['first_name'] . '</td></tr>';
}
}
echo '</table>';
mysqli_close($dbc);
?>
<?php
// Insert the page footer
require_once('footer.php');
?>
它可以幫助減少程式碼的量以及撰寫時花的力氣
最大的好處是提供了維護的方便性
樣板就是將程式分成功能性元件
以下將提供範例:
原件成員:
startsession.php==========
<?php
session_start();
// If the session vars aren't set, try to set them with a cookie
if (!isset($_SESSION['user_id'])) {
if (isset($_COOKIE['user_id']) && isset($_COOKIE['username'])) {
$_SESSION['user_id'] = $_COOKIE['user_id'];
$_SESSION['username'] = $_COOKIE['username'];
}
}
?>
header.php======
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<?php
echo '<title>Mismatch - ' . $page_title . '</title>';
?>
<link rel="stylesheet" type="text/css" href="style.css" />
</head>
<body>
<?php
echo '<h3>Mismatch - ' . $page_title . '</h3>';
?>
navmenu.php==========
<?php
// Generate the navigation menu
echo '<hr />';
if (isset($_SESSION['username'])) {
echo '<a href="index.php">Home</a> ❤ ';
echo '<a href="viewprofile.php">View Profile</a> ❤ ';
echo '<a href="editprofile.php">Edit Profile</a> ❤ ';
echo '<a href="logout.php">Log Out (' . $_SESSION['username'] . ')</a>';
}
else {
echo '<a href="login.php">Log In</a> ❤ ';
echo '<a href="signup.php">Sign Up</a>';
}
echo '<hr />';
?>
footer.php==========
<hr />
<p class="footer">Copyright ©2008 Mismatch Enterprises, Inc.</p>
</body>
</html>
完成品:
index.php============
<?php
// Start the session
require_once('startsession.php');
// Insert the page header
$page_title = 'Where opposites attract!';
require_once('header.php');
require_once('appvars.php');
require_once('connectvars.php');
// Show the navigation menu
require_once('navmenu.php');
// Connect to the database
$dbc = mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME);
// Retrieve the user data from MySQL
$query = "SELECT user_id, first_name, picture FROM mismatch_user WHERE first_name IS NOT NULL ORDER BY join_date DESC LIMIT 5";
$data = mysqli_query($dbc, $query);
// Loop through the array of user data, formatting it as HTML
echo '<h4>Latest members:</h4>';
echo '<table>';
while ($row = mysqli_fetch_array($data)) {
if (is_file(MM_UPLOADPATH . $row['picture']) && filesize(MM_UPLOADPATH . $row['picture']) > 0) {
echo '<tr><td><img src="' . MM_UPLOADPATH . $row['picture'] . '" alt="' . $row['first_name'] . '" /></td>';
}
else {
echo '<tr><td><img src="' . MM_UPLOADPATH . 'nopic.jpg' . '" alt="' . $row['first_name'] . '" /></td>';
}
if (isset($_SESSION['user_id'])) {
echo '<td><a href="viewprofile.php?user_id=' . $row['user_id'] . '">' . $row['first_name'] . '</a></td></tr>';
}
else {
echo '<td>' . $row['first_name'] . '</td></tr>';
}
}
echo '</table>';
mysqli_close($dbc);
?>
<?php
// Insert the page footer
require_once('footer.php');
?>
PHP筆記(2)
這篇寫比較多關於註冊、登入相關的項目
1.使用MySQL函式做密碼加密
2.Cookie使用方法
3.session設置
1.使用MySQL函式做密碼加密
當在寫註冊、登入功能時
密碼的加密是一個要點
他可以在即使資料庫不幸被盜取後,損失也能降低
駭客即使取得加密之後的密碼也無能為力
加密的方法是使用資料庫的SHA()函式,例如:
INSERT INTO table (account, pw) VALUES ('John', SHA('password'))
上式使用的SHA()函式會將password這個字轉換成40個字元的16進位制字串
注意一點是SHA()函式是不可逆的過程,這是它防止被盜取的機制
假如要進行密碼驗證
只要再輸入一樣的字串,經過SHA()函式變換之後能得到相同的字串,例如:
SELECT * FROM table WHERE pw = SHA('password')
上式的password是使用者輸入的密碼
這樣一來就可以做好驗證的工作了
當然還有非常重要的一點一定要提醒
因為轉換的字串長度問題
一開始在建造密碼欄位時要改成40個字元長度
其他類似的函式有
MySQL的MD5() //安全性較差
PHP的sha1()及md5()
2.Cookie使用方法
當有必要持續記錄使用者登入狀態時,Cookie是一個選擇
他會將資料記錄並儲存在使用者端電腦裡
使用方法例如:
setcookie('index', 'value', time() + (60 * 60 * 1));
第三個變數會是cookie的存活時間值,沒有設置就是關掉瀏覽器即失效
範例中的例子是存活時間點會是現在過後的一個小時(3600s)內
讀取時使用$_COOKIE['index']來存取變數
假如要登出的話只要使存活時間成為過去時間即可
例如改成:
setcookie('index', 'value', time() - (60 * 60 * 1));
需要注意一點是Cookie設置仰賴瀏覽器協助
假使使用者關掉Cookie功能的話也不能成功
3.session設置
session可以視作另一種的Cookie
只不過資料儲存的地點是伺服器端,另外只要瀏覽器關閉即失效
這樣也可以避免瀏覽器關閉Cookie功能帶來的影響
假使cookie真的被停用時
server上的php.ini裡的session.use_trans_id 設定成1
這樣就可以克服問題了
使用session的範例:
logout.php======
<?php
//if the user is logged in, delete the session vars to log them out
session_start();
if(isset($_SESSION['id'])){
//delete the session vars by clearing the $_SESSION array
$_SESSION = array();
//delete the session cookie by setting its expiration to an hour ago
if(isset($_COOKIE[session_name()])){
setcookie(session_name(), "", time()-3600);
}
//Destroy the session
session_destroy();
}
?>
session_start()函式會啟動session功能,然後伺服器會發一組辨識ID
即使在登出也要使用這個函式才能存取session
尾部的session_destroy()結束session,瀏覽器關閉時也會自動呼叫這個函式
使用session的方法一樣是用全域函數 ,如$_SESSION['id'] = 'john'
要清除session的方法除了關掉瀏覽器外
$_SESSION = array()這樣,指定session為空陣列也可以
實際在運作時,session也很有可能在私底下會用到cookie
畢竟cookie是最佳化的資料儲存方式
session_name()可以幫助我們找到該cookie,這樣一來就可以握到完整的清除
1.使用MySQL函式做密碼加密
2.Cookie使用方法
3.session設置
1.使用MySQL函式做密碼加密
當在寫註冊、登入功能時
密碼的加密是一個要點
他可以在即使資料庫不幸被盜取後,損失也能降低
駭客即使取得加密之後的密碼也無能為力
加密的方法是使用資料庫的SHA()函式,例如:
INSERT INTO table (account, pw) VALUES ('John', SHA('password'))
上式使用的SHA()函式會將password這個字轉換成40個字元的16進位制字串
注意一點是SHA()函式是不可逆的過程,這是它防止被盜取的機制
假如要進行密碼驗證
只要再輸入一樣的字串,經過SHA()函式變換之後能得到相同的字串,例如:
SELECT * FROM table WHERE pw = SHA('password')
上式的password是使用者輸入的密碼
這樣一來就可以做好驗證的工作了
當然還有非常重要的一點一定要提醒
因為轉換的字串長度問題
一開始在建造密碼欄位時要改成40個字元長度
其他類似的函式有
MySQL的MD5() //安全性較差
PHP的sha1()及md5()
2.Cookie使用方法
當有必要持續記錄使用者登入狀態時,Cookie是一個選擇
他會將資料記錄並儲存在使用者端電腦裡
使用方法例如:
setcookie('index', 'value', time() + (60 * 60 * 1));
第三個變數會是cookie的存活時間值,沒有設置就是關掉瀏覽器即失效
範例中的例子是存活時間點會是現在過後的一個小時(3600s)內
讀取時使用$_COOKIE['index']來存取變數
假如要登出的話只要使存活時間成為過去時間即可
例如改成:
setcookie('index', 'value', time() - (60 * 60 * 1));
需要注意一點是Cookie設置仰賴瀏覽器協助
假使使用者關掉Cookie功能的話也不能成功
3.session設置
session可以視作另一種的Cookie
只不過資料儲存的地點是伺服器端,另外只要瀏覽器關閉即失效
這樣也可以避免瀏覽器關閉Cookie功能帶來的影響
假使cookie真的被停用時
server上的php.ini裡的session.use_trans_id 設定成1
這樣就可以克服問題了
使用session的範例:
logout.php======
<?php
//if the user is logged in, delete the session vars to log them out
session_start();
if(isset($_SESSION['id'])){
//delete the session vars by clearing the $_SESSION array
$_SESSION = array();
//delete the session cookie by setting its expiration to an hour ago
if(isset($_COOKIE[session_name()])){
setcookie(session_name(), "", time()-3600);
}
//Destroy the session
session_destroy();
}
?>
session_start()函式會啟動session功能,然後伺服器會發一組辨識ID
即使在登出也要使用這個函式才能存取session
尾部的session_destroy()結束session,瀏覽器關閉時也會自動呼叫這個函式
使用session的方法一樣是用全域函數 ,如$_SESSION['id'] = 'john'
要清除session的方法除了關掉瀏覽器外
$_SESSION = array()這樣,指定session為空陣列也可以
實際在運作時,session也很有可能在私底下會用到cookie
畢竟cookie是最佳化的資料儲存方式
session_name()可以幫助我們找到該cookie,這樣一來就可以握到完整的清除
訂閱:
文章 (Atom)