2007-11-26

利用 Trigger 做出 CHECK()

最近才發現 MySQL5 並沒有支援 CHECK 指令,但為了部分欄位的定義域檢查只好使用 Trigger 來代替了,改寫了之前用 CHECK 寫的規則。

CREATE TRIGGER `觸發器名稱` -- 命名原則與資料表一樣
{ BEFORE | AFTER } -- 設置事件發生為前或後
{ INSERT | UPDATE | DELETE } -- 設定觸發的事件
ON `資料表名稱` -- 設定引起觸發的資料表
FOR EACH ROW -- 針對行為觸發單位
{觸發的SQL指令} -- 這裡可以是任何合法的指令與複合句(BEGIN/END)


範例:

DELIMITER $$ -- 變更結束符號為 $$

CREATE TABLE t25(
s1 INT,
s2 CHAR(5),
PRIMARY KEY (s1)
)ENGINE = INNODB $$

CREATE TRIGGER t25_bi BEFORE INSERT ON t25
FOR EACH ROW
IF LEFT(NEW.s2,1)<>'A' THEN
SET NEW.s1=0;
END IF;
$$

CREATE TRIGGER t25_bu BEFORE UPDATE ON t25
FOR EACH ROW
IF LEFT(NEW.s2,1)<>'A' THEN
SET NEW.s1=0;
END IF;
$$

DELIMITER ; -- 將結束符號改回 ;


參考文件:
MySQL 5.0-触发器
MySQL 5.1参考手册 :: 21. 触发程序
2007-11-19

初次使用 mootools.js

最近為了網頁的動態效果,從 prototype.js 改使用 mootools.js 做開發依據,雖然 mootools.js 很好用,也比 prototype.js 更簡化了許多,但也應為更簡化讓我有點不太能上手。

為了避免相容性的問題,使用其中很多的函數作媒介,雖然是個很好用的 Framework ,但效率確不如 prototype.js 快,當然不可能要馬兒跑得快,又要馬兒不吃草,mootools.js 在背後為了處理相容性的問題用掉不少時間,也簡化開發時架構的複雜度。

由於對 mootools.js 還不是熟,可能需要花點時間去瞭解,但還是一句老話:

要知道積木有那些,才能蓋出偉大的城堡
2007-11-16

用 mount 設置虛擬目錄

今天團隊在開發上出現了一個問題,在設計 Smarty 樣版時必須用到 CSS 的載入檔,造成在預覽上有很不方便的問題,為了這個問題必須在 ftp server 與 web server 上都開虛擬目錄,然後在網路上找到一個方便的指令:

mount --bind olddir newdir

olddiv :主要的連結目錄的路徑
newdir :目的地的連結目錄的路徑
這兩個目錄必須事先建立好,建議使用絕對路徑去下這個指令。
EX:mount --bind /home/test /home/test2/test3

利用掛載的方式做出虛擬目錄,就像一個捷徑將兩個目錄連在一起,這是系統上的支援,而且在 ftp server 與 web server 上都能正常操作。
2007-11-09

MySQL UNIQUE KEY 複合鍵

由於網路上說明這個語法的中文文章不多,所以想記錄一下

語法:
UNIQUE KEY `test` (`xref_key`,`xref_dbname`)
UNIQUE KEY `xref_key` (`xref_key`,`xref_dbname`)

這個語法會檢查 xref_key 與 xref_dbname 的組合是否為唯一值,當然不只有是兩個欄位的組合,你也可以設定一或多個欄位,test 是索引表的欄位名稱。

適合用來解決欄位相依時,必須滿足唯一性的處理,在時常新增或刪除的資料表中 AUTO_INCREMENT 的 PRIMARY KEY 會造成大量的斷層,這類容易變動的資料表使用 AUTO_INCREMENT 並不是一個很適合的索引值,所以可以採用 UNIQUE KEY 來處理這樣的問題。

參考文章:藍色小舖-請問關於UNIQUE敘述的疑問
2007-11-07

[PHP] 驗證碼

最近在實做文章回復所需要的功能,這是一個既簡單又好用的認證碼,但是他有個缺點,就是單一用戶同時只能存取一次驗證碼,簡單的說就是一次只能寫一篇回應,當然還是可以用其他方式去加強這個缺點。

<?php
header("Content-type:image/png");
header("Content-Disposition:filename=image_code.png");
//定義 header 的文件格式為 png,第二個定義其實沒什麼用

// 開啟 session
if (!isset($_SESSION)) { session_start(); }

// 設定亂數種子
mt_srand((double)microtime()*1000000);

// 驗證碼變數
$verification__session = '';

// 定義顯示在圖片上的文字,可以再加上大寫字母
$str = 'abcdefghijkmnpqrstuvwxyz1234567890';

$l = strlen($str); //取得字串長度

//隨機取出 6 個字
for($i=0; $i<6; $i++){
$num=rand(0,$l-1);
$verification__session.= $str[$num];
}

// 將驗證碼記錄在 session 中
$_SESSION["verification__session"] = $verification__session;


// 圖片的寬度與高度
$imageWidth = 160; $imageHeight = 50;
// 建立圖片物件
$im = @imagecreatetruecolor($imageWidth, $imageHeight)
or die("無法建立圖片!");


//主要色彩設定
// 圖片底色
$bgColor = imagecolorallocate($im, 255,239,239);
// 文字顏色
$Color = imagecolorallocate($im, 255,0,0);
// 干擾線條顏色
$gray1 = imagecolorallocate($im, 200,200,200);
// 干擾像素顏色
$gray2 = imagecolorallocate($im, 200,200,200);

//設定圖片底色
imagefill($im,0,0,$bgColor);

//底色干擾線條
for($i=0; $i<10; $i++){
imageline($im,rand(0,$imageWidth),rand(0,$imageHeight),
rand($imageHeight,$imageWidth),rand(0,$imageHeight),$gray1);
}

//利用true type字型來產生圖片
imagettftext($im, 20, 0, 25, 35, $Color,
"/var/lib/defoma/fontconfig.d/D/DejaVu-Serif-Bold.ttf",
$verification__session);
/*
imagettftext (int im, int size, int angle,
int x, int y, int col,
string fontfile, string text)
im 圖片物件
size 文字大小
angle 0度將會由左到右讀取文字,而更高的值表示逆時鐘旋轉
x y 文字起始座標
col 顏色物件
fontfile 字形路徑,為主機實體目錄的絕對路徑,
可自行設定想要的字型
text 寫入的文字字串
*/

// 干擾像素
for($i=0;$i<90;$i++){
imagesetpixel($im, rand()%$imageWidth ,
rand()%$imageHeight , $gray2);
}

imagepng($im);
imagedestroy($im);

輸出結果:



參考文章:php確認碼圖片
2007-11-06

MySQL 遠端連線

MySQL 預設是不允許遠端連線的
要在 my.ini 或 my.cnf 中將他開啟
找到下面兩行將他註解掉
當然使用者也必須設定為可以遠端的權限

skip-networking
bind-address=127.0.0.1
2007-11-01

MySQL5 Procedure For PHP5

今天在編寫 MySQL5 的預存程序,稍微研究了一下,功能蠻強大的,可以讓我用來將複雜的查詢指令包裝起來,就像寫函式一樣的好用。

範例:

DELIMITER $$ -- 變更結束符號為 $$

DROP PROCEDURE IF EXISTS `getData` $$ -- 將原本有的程序刪除
-- 建立程序並設定參數屬性
CREATE PROCEDURE `getData`(id INT, uid CHAR(30))
DETERMINISTIC

BEGIN -- 程序內容起始
SELECT A.FriendUser FROM
(SELECT A.fu, A.Pri FROM A WHERE A.myid = id) AS A1
INNER JOIN
(SELECT B.fu, B.Pri FROM B WHERE B.blid = uid) AS B1
ON A1.fu = B1.fu WHERE A1.Pri >= B1.Pri ;
END $$ -- 程序內容結尾

DELIMITER ; -- 將結束符號改回 ;


執行方法 CALL getData(12,'jax');

由於 phpMyAdmin 沒有支援的工具,也不能匯入,所以只好使用指令模式匯入了,將上面的指令寫到 procedure.sql 文件中,就像寫資料庫建立文件是一樣的,再利用下面的方法將建立指令匯入。
mysql -u username -p < procedure.sql
PS:由於用這個方法匯入時,錯誤訊息的行數會以上一個結束符號為起點,所以在檢查時要看仔細一點,建議先確認程序內容是否正確,在建立預存程序。

預存程序參考文章:
樂多日誌
MySQL 5.0 Reference Manual


在 PHP5 中可以用 db_mysqli.dll 這個函示庫來存取 MySQL 預存程序,如果你也是習慣使用 Dreamweaver 來寫網頁的人,只要將所有的 mysql_xxxx() 都換成 mysqli_xxxx() 就可以了,不過還是要注意 MySQL 連線的參數方法。

$link = mysqli_connect(
'localhost', /* The host to connect to */
'root', /* The user to connect as */
'root', /* The password to use */
'db_name' /* The default database to query */
);

mysqli_query($link, "CALL getData(12,'jax')");


PHP5 參考文章:
PHP 調用 MySQL 預存程序(MySql5.0)