2008年6月30日 星期一

gcin的大易輸入法

gcin的大易輸人法無法使用鍵盤輸入標點符號,要解決這個問題,有兩個方法可以解決:

1.在大易輸入法下,按住ctrl-alt-逗號,就會顯示符號表,用滑鼠點選符號就可以輸入標點符號,不過使用滑鼠輸入比不上用鍵盤快速,不太方便。

2.在EN圖示上按右鍵->設定->倉擷/行列/大易/嘸蝦米設定->編輯內定輸入法的使用者外加字詞

加入下面兩行

,, ,
.. 。

以後輸入逗號時,按兩次逗號就會出現逗號。
要輸入句號,按兩次點號就可以了。

第一欄是輸入的鍵盤符號
第二欄是輸入後的文字
第一欄及第二欄間以空白分隔

其他的標點符號如果要使用鍵盤輸入,也是用同樣的方式設定。

stored procedure


Stored procedure
http://dev.mysql.com/doc/refman/5.0/en/stored-procedures.html

什麼是stored procedure
stored procedure是由一群sql敘述及流程控制的語法組成,本質上就是mysql中的程式語言,只是stored procedure的程式語法,跟php的不一樣,能使用的環境只限於mysql資料庫中,專為處理資料庫的操作,為了處理資料庫中的資料,有一些語法與php這種泛用型的程式語言,語法方面就稍微有些不同。就像戰機有雖然都有戰鬥功能,但為了不同的目的,有不同設計,以發揮團隊作戰的整體力量,有的戰機是專用對付入侵的戰機,是屬於空優型戰機,有的戰機,武裝不強,但體型龐大,有匿蹤功能,可以攜帶大量彈藥轟炸敵軍,屬於轟炸機。
mysql的stored procedure的語法遵循SQL:2003的語法標準,IBM的DB2也一樣遵循這套標準,遵循相同的標準有相當明顯的好處,如果要轉換資料庫,stored procedure不同重新撰寫,除錯,可以輕易的進行轉換,不會因為換了資料庫,必須重頭學習另一種語法,所有的基礎重頭來過。
使用stored procedure可以減少php程式碼的數量並增加程式的效能,php程式中只要呼叫stored procedure,stored procedure便會執行stored procedure中所有的sql敘述,並將結果傳回php程式中,php不用再一一呼叫sql statement,執行各自獨立的sql statement,再一一判斷結果,進行處理,這些sql statement及判斷統統都包裝在stored procedure裡頭,php及mysql之間傳遞的資料數量大幅減少,由於php與mysql之間等待資料傳送的時間及次數減少,可以加快程式的速度,也由於只要呼叫stored procedure,而不用呼叫各自獨立的sql statement,也減少了程式碼的數量。
目前,stored procedure不支援遞迴呼叫,如果要使用遞迴呼叫,必須將mysql變數:max_sp_recursion_depth 設定為非零的數字,預設是零,不允許遞迴,設為1,允許遞迴一次,設為2,允許遞迴二次,以此類推。

stored procedure的管理
stored procedure都存在mysql資料庫中的proc資料表中(mysql.proc),這個資料表儲存所有的stroed procedure,這些資料透過管理工具,可以運作正常,但如果手動修改,就有可能發生不可預期的後果,絕對不要手動修改這些資料,而是要透過create procedure,alter proceudre或是drop procedure來進行管理。


要建立stored procedure就必須有create routine的權限

要修改stored procedure就必須有alter routine的權限

要執行stored procedure就必須有execute的權限

有create routine的權限就自動會有alter routine及execute的權限

建立stored procedure的語法
create [definer={usercurrent_user}] procedure sp_name([sp_parameter],[sp_parameter]...)
[characteristic]
stored procedure body
[characteristic]
language sql
目前沒有作用
[not] deterministic
如果沒設,預設為 not deterministic
{ CONTAINS SQL NO SQL READS SQL DATA MODIFIES SQL DATA }
目前沒有強制性,mysql只會當做註解
sql security {definerinvoker}
預設為definer
comment '註解內容'

修改
alter procedure sp_name ...

刪除
drop procedure sp_name;

執行stored procedure
call 預存程序名稱(參數);
以實際範例操作會比較清楚。
/**
*建立store procedure,名稱為sp_test
*/
delimiter //
create definer=current_user procedure sp_test(out version varchar(60),out day varchar(60))
language sql
not deterministic
contains sql
sql security definer
begin
select version() into version;
select curdate() into day;
end;
//
delimiter ;
/**
*執行stored procedure,stored procedure的名稱為sp_test
*/
call sp_test(@version,@day);
select @version,@day;

變數的處理
變數宣告
declare i int default 1;
變數的設定
set i=3;
select 4*5 into i;

例外處理
例外訊息列表
http://dev.mysql.com/doc/refman/5.0/en/error-messages-server.html
看下面的實例比較快
delimiter //
create procedure sp_h()
begin
declare no_table condition for 1146;
declare continue handler for no_table
begin
select 'hi!! world!';
end;
select * from a;
end
//
delimiter ;

cursor
只能讀
只能單向移動,不能跳過任一列
create procedure test()
begin
declare var_name varchar(30);
declare cur1 cursor for select name from a;
declare exit handler for sqlstate '02000' begin end;
open cur1;
repeat
fetch cur1 into var_name;
select var_name;
until 0 end repeat;
close cur1;
end;

宣告的順序
變數及condition
cursor
handler

流程控制
mysql的stored procedure流程控制語法跟一般的程式語言相同,有迴圈及判斷式的二類。迴圈及判斷式的用法與php的用法相同,只是語法不一樣,寫幾個具體範例熟悉一下迴圈及判斷式的語法會比較較快進入狀況,manual上的說明,範例太少了,自己出幾個題目,動手寫一些小程式會比較快熟悉stored procedure的迴圈判斷式的語法。
Mysql的stored procedure的iterate及leave是用在迴圈的語法,iterate的功能與php中的continue相同,leave就跟php中的break相同,都是控制迴圈進行的語法,讓程式能依照判斷式跳出迴圈或繼續重頭執行迴圈中的程式碼。
底下是使用stored procedure的語法寫的簡易程式,最好是使用記本先打好,再匯入mysql或是使用mysql的圖形化介面的管理工具,如navicat、Mysql Administrator,進行stored procedure的撰寫,才會比較快速有效率,不然是很難進行除錯的。工欲善其事,必先善其器,好的工具及方法,可以加快你進入stored procedure世界的速度。
程式很簡單,只要有程式基礎,看一下manual就知道程式是怎麼運作,但學習方法比較容易被忽略,如果只是看看過去,沒有實際撰寫的話,不容易深入了解stored procedure的運作。最好自己出題,實際寫幾個stored procedure,搭配manual上的說明,才能對stored procedure有完整的認識。
以loop迴圈寫的九九乘法表
delimiter //
create procedure sp_a()
begin
declare i int default 1;
declare j int default 1;
label_a: loop
if i<=9 then
set j=1;
label_b: loop
if j<=9 then
select i,j,i*j;
set j=j+1;
iterate label_b;
end if;
leave label_b;
end loop label_b;
set i=i+1;
iterate label_a;
end if;
leave label_a;
end loop label_a;
end;
//
delimiter ;


以repeat迴圈寫的九九乘法表
delimiter //
create procedure sp_b()
begin
declare i int default 1;
declare j int default 1;
repeat
set j=1;
repeat
select i,j,i*j;
set j=j+1;
until j>9 end repeat;
set i=i+1;
until i>9 end repeat;
end;
//
delimiter ;


以while迴圈寫的九九乘法表
delimiter //
create procedure sp_c()
begin
declare i int default 1;
declare j int default 1;
while i<=9 do
set j=1;
while j<=9 do
select i,j,i*j;
set j=j+1;
end while;
set i=i+1;
end while;
end;
//
delimiter ;


if判斷式的使用
delimiter //
create procedure sp_d(in age int)
begin
if age<18 then
select 'you are young man';
elseif age>=18 and age<40 then
select 'you have many life experiences';
else
select 'you ard old man';
end if;
end;
//
delimiter ;


case判斷式的使用
delimiter //
create procedure sp_e(in selector int)
begin
case selector
when 1 then
select 'yellow';
when 2 then
select 'black';
when 3 then
select 'red';
else
select 'no color selected';
end case;
end;
//
delimiter ;

2008年6月28日 星期六

看chm

在ubuntu上看chm檔的工具

apt-get install gnochm

大易輸入法

ubuntu上內定的輸入工具scim,大易輸入法是使用三碼輸入,跟我習慣的四碼輸入不太一樣,要重頭適應,實在是很痛苦.

上網找了一下資料,把scim換成gcin,就可以用四碼的大易輸入法了.但是標點符號,還是一樣沒辦法用大易四碼的方式打出來,輸入標點符號挺麻煩的.

scim換成gcin的步驟如下

apt-get install gcin
im-swith -s gcin
登出
重新登入

2008年6月24日 星期二

上傳檔案的設定

http://www.php.net/manual/en/features.file-upload.common-pitfalls.php

php相關設定
upload_max_filesize
memory_limit
max_execution_time
post_max_size

mysql相關設定
max_allowed_packet

撰寫上傳物件的問題

想要寫一個檔案上傳的物件,以方便以後程式碼的重複使用,不必重造輪子,做相同的事情,仔細思考很久,如果上傳的檔案都存在目錄裡,還必須考量到檔案備份、程式碼中檔案上傳的安全性,使用者上傳的檔案名稱也必須做管控,才能避免檔案重複,造成檔案彼此覆蓋的問題,因此決定將上傳物件,寫成將插入資料庫的型式,如果以物件導向的模式方式思考,其實應該實做一個interface或abstract,再分別撰寫要上傳至資料庫的物件,及上傳至目錄的物件,這樣才能顧及程式的擴展性及可維護性,不過現在沒想那麼多,先能用就好了。

檔案存到資料庫中,只要必份資料庫並小心權限設定,程式碼使用prepared statement操控資料庫,就可以避掉sql injection及檔案備份的問題,以後只要備份資料庫就可以了,而不用再備份檔案,也不用再花心思控管上傳檔案的安全性。比較省事。

上傳物件,在網路上有許多現成的程式碼可以參考,各種寫法看了讓人頭昏眼花,參考了php manual後,最後決定使用file_get_contents函數進行檔案的處理,這個函數是php manual上建議使用的函數,雖然php 6.0以後才會完整支援所有的參數,但轉換檔案為string時,這個函數的轉換效率是最好的。

如果使用fopen開啟檔案,再使用read()函數進行讀取,要記得加上參數'rb',如fopen(檔案,'rb'),因為windows系統對待binary跟文字檔是不同的,所以要記得加b,操作時才不會出錯。

測試上傳物件時,檔案比較大的物件上傳時,都會被切成只有64k,找程式碼找了半天,也找不到錯誤,後來,在mysql manual上找到原因了,blob的儲存上限是64k,mediumblob是16M,bigblob是4g,改欄位的資料型態就一切正常了。

另一個在測試時碰到的問題,就是中文檔名下載時會出會錯誤,只要使用urlencode()函數將檔名重新編碼,就不會有這個問題了。

2008年6月23日 星期一

多媒體播放器

在pchome上看到的二套多媒體播放器,中文檔名不會出現亂碼

看影片

smplayer



聽mp3

偏好設定的部份,取消「使用點陣字」勾選,就可顯示中文

audacious

2008年6月18日 星期三

Zend_Acl_Role的設計




/**

* 程式碼是以陳瑩光老師新版學務系統的認證模組改寫的。

*/




要實做Zend_Acl_Role的多重繼承架構,有四個區塊的觀念必須弄清楚,才能把整個架構完整的實做,這四個區塊都弄楚了,程式的實做就是水到渠成的事情。




第一個要弄清楚的區塊就是Zend_Acl_Role的多重繼承觀念,Zend_Acl_Role的繼承關係,跟Zend_Acl_Resource不一樣,Zend_Acl_Resource只能有一個parent,但Zend_Acl_Role卻可以有很多個parent,就像現實生活中的人物一樣,每個人都身兼多重身份,Zend_Acl_Role也可以同時繼承多個parent,與一個實例說明:假設一個Zend_Acl_Role的身份是專案經理,同時繼承了程式設計師、架構設計師及資料庫規畫師的身份,那麼專案經理就同時繼承了指定給這三個身份的所有資源。




第二個要弄清楚的區塊是資料庫結構,如果不使用資料庫,而將Zend_Acl_Role的資料寫在程式碼中,程式碼會變得很冗長,要一行一行coding,不是用幾個迴圈就可以解決的,也難以維護,如果資料非常龐雜,不但程式碼的行數會呈等比級數增加,也會很難搞清楚其中的繼承關係,程式也容易寫錯,為了一勞永逸,最好將這些資料都存入資料庫進行維護管理。存成xml或是ini檔也是可以解決部份的問題,不過資料如果太複雜,也會造成難以維護的結果,最好的解決辦法,就是使用資料庫。




第三個要弄清楚的就是陣列結構,使用陣列結構,只要從資料庫中抓一次資料,將資料轉為陣列結構,在後續的程序中直接使用陣列結構進行資料的操作,如果不使用陣列,那麼後續的程序,會不斷的讀取資料庫,雖然不能說這樣的作法有錯,但資料庫的資料都是存放在硬碟中的,每次讀取資料庫中的資料都會讀取硬碟,而陣列是存放在記憶體裡頭,在速度上,記憶體比硬碟快很多,因此,陣列的操作速度會比資料庫的操作速度快,為了加快速度,最好儘量使用陣列結構進行程式資料的存取。




第四個區塊就是程式的邏輯,這部份要花費很大的心思才能搞懂,如果弄懂了,程式的實做就很快了,只要照著你的思考順序,一步步的將解決方式寫出來就可以建構完整的程式碼了。




用freemind畫了四個區塊的架構圖,以後如果忘記了,不用看程式碼,也不用看說明,看這張圖就一目了然了。



以Zend Framework實做Zend_Acl_Role的雛型


class AclController extends Zend_Controller_Action{
public function init(){
$this->_helper->viewRenderer->setNoRender();
Zend_Loader::loadClass('Zend_Acl');
Zend_Loader::loadClass('Zend_Acl_Role');
Zend_Loader::loadClass('Zend_Acl_Resource');

$acl=new Zend_Acl();
Zend_Registry::set('acl',$acl);
}

public function roleAction(){

$baseDir=Zend_Registry::get('baseDir');

$config=new Zend_Config(require($baseDir.'/application/etc/db.php'));

$db=Zend_Db::factory($config->public);

$db->query('set names utf8');

$sql='select a.id,b.parent_id from acl_role as a left outer join acl_inheritance as b on a.id=b.child_id';
$stmt=$db->query($sql);
$rows=$stmt->fetchAll();

/**
* 將資料轉為所需的陣列結構
* Zend_Acl_Role註冊時所需的陣列結構
*/
$roles=array();
foreach($rows as $row){
if(!isset($roles[$row['id']]))
$roles[$row['id']]=array();
if(isset($row['parent_id']))
$roles[$row['id']][]=$row['parent_id'];
}

$acl=Zend_Registry::get('acl');
do{
$flag=false;

/**
* 註冊role
*/
foreach($roles as $key=>$role){
if(!$acl->hasRole($key) && (!isset($role) || $this->hasAllRole($role))){
$acl->addRole(new Zend_Acl_Role($key),$role);
}
/**
* 檢查第一維的key是否都己註冊為role
* 是---離開
* 否---繼續
*/
if(!$acl->hasRole($key))
$flag=true;
}
}while($flag);

}

public function hasAllRole(array &$role){
$acl=Zend_Registry::get('acl');
foreach($role as $parent_id){
if(!$acl->hasRole($parent_id))
return false;
}
return true;
}

}

2008年6月17日 星期二

Zend_Acl_Resource的樹狀結構



Zend_Acl_Resource的樹狀結構

要建立Zend_Acl_Resource的樹狀結構,對我來說難度滿高的,想了很久,都想不出解法,最後看了陳瑩光老師寫的新版學務系統中的認證模組,找到了解法,不過雖然解法找到了,卻不明瞭為何要這樣寫,思考了很久,才把需要了解的區塊,一個個弄清楚,再把整個解法背後運用的思考邏輯用freemind全部畫出來,再依照這張畫出來的圖,自己弄出一個建構Zend_Acl_Resource樹狀結構的原型,我自己寫的程式改良了原來程式碼的部份寫法,不過,沒有將錯誤機制考慮在內,也就是說,在資料庫內的資料都必須是正確的。



建立Zend_Acl_Resource樹狀結構的資料庫內的欄位資料

資料表:resource

欄位
id----------Primary key(resource的名稱)
parent_id---參照id或是null


要建立Zend_Acl_Resource的樹狀結構的第一步就是將資料從資料庫中抓到陣列中,如果不這麼做,那麼每建立一層樹狀結構就要把資料表的全部資料讀取一遍,是非常耗時的,如果把資料抓到陣列中,由於陣列是存放在記憶體中,比起存放在資料表中的資料,讀取速度快非常多,為了效能的考量,一定要先將資料讀入陣列中。

第二步就是開始建立整個樹狀結構,原理是利用迴圈的方式,第一次迴圈會找出所有id未註冊且parent_id是null的陣列值,註冊為最上層的resource,第二次迴圈會找出所有id未註冊且parent_id(參照到最上層resource的id)已註冊的陣列值,註冊為第二層的resource,第三次迴圈會找出所有id未註冊且parent_id(參照到第二層的resource的id)已註冊的陣列值,註冊為第三層的resource。這個迴圈會一直持續到所有id都註冊為止。


Zend_Loader::loadClass('Zend_Acl');
Zend_Loader::loadClass('Zend_Acl_Role');
Zend_Loader::loadClass('Zend_Acl_Resource');
Zend_Loader::loadClass('Zend_Db');
Zend_Loader::loadClass('Zend_Config');
Zend_Loader::loadClass('Zend_Registry');

$baseDir=Zend_Registry::get('baseDir');

$config=new Zend_Config(require($baseDir.'/application/etc/db.php'));

/**
* 讀取資料表欄位,將資料表內的資料讀入陣列
*/
$db=Zend_Db::factory($config->public);
$db->query('set names utf8');
$sql='select id,parent_id from resource';
$stmt=$db->query($sql);
$rows=$stmt->fetchAll();




/**
* 建立resource的樹狀結構
*/
$acl=new Zend_Acl();
do{
$flag=false;
foreach($rows as $row){

/**
* 建立resource樹狀結構的判斷流程程式碼
*/
if(!$acl->has($row['id']) && ($row['parent_id']===null || $acl->has($row['parent_id']) ) ){
$acl->add(new Zend_Acl_Resource($row['id']),$row['parent_id']);
}

/**
* 判斷所有id是否已註冊為resource,如果有未註冊的id,旗標設為true,繼續執行迴圈
* 如果所有的id都已註冊,就會跳出迴圈
*/
if(!$acl->has($row['id']))
$flag=true;

}
}while($flag);

2008年6月11日 星期三

php上傳物件

參考網址

http://www.devshed.com/c/a/PHP/Developing-a-Modular-Class-For-a-PHP-File-Uploader/1/


檔案上傳物件

上列網址是一個檔案上傳物件的實例,用了一些php內建的函數及物件,使用內建函數及物件,執行效率會提高(因為是用c寫的),程式內也用了迴圈的方式把全域陣列$_FILE中的key/value都對應到物件中的屬性,這樣就不用寫一堆討人厭的$_FILE['userfile']['name']這類一長串不好輸入的字元,整個程式碼很清爽。

撰寫這個物件的背景知識

使用的函數及物件
Exception物件
in_array()函數
move_uploaded_file()函數

使用的全域陣列
$_FILE['userfile']['name'] 原始檔名
$_FILE['userfile']['tmp_name'] 儲在server上的暫存檔名
$_FILE['userfile']['type'] 檔案的mime型態
$_FILE['userfile']['size'] 檔案大小,單位是byte
$_FILE['userfile']['error'] 上傳錯誤,錯誤代碼查php manual就知道了


從上列網址post上來的上傳物件的範例程式碼


class FileUploader{

private $uploadFile;

private $name;

private $tmp_name;

private $type;

private $size;

private $error;

private $allowedTypes=array
('image/jpeg','image/gif','image/png','text/plain','application/ms-word');

public function __construct($uploadDir='C:uploaded_files'){

if(!is_dir($uploadDir)){

throw new Exception('Invalid upload directory.');

}

if(!count($_FILES)){

throw new Exception('Invalid number of file upload parameters.');

}

foreach($_FILES['userfile'] as $key=>$value){

$this->{$key}=$value;

}

if(!in_array($this->type,$this->allowedTypes)){

throw new Exception('Invalid MIME type of target file.');

}

$this->uploadFile=$uploadDir.basename($this->name);

}

// upload target file to specified location

public function upload(){

if(move_uploaded_file($this->tmp_name,$this->uploadFile)){

return true;

}

// throw exception according to error number

switch($this->error){

case 1:

throw new Exception('Target file exceeds maximum allowed size.');

break;

case 2:

throw new Exception('Target file exceeds the MAX_FILE_SIZE value specified on the upload form.');

break;

case 3:

throw new Exception('Target file was not uploaded completely.');

break;

case 4:

throw new Exception('No target file was uploaded.');

break;

case 6:

throw new Exception('Missing a temporary folder.');

break;

case 7:

throw new Exception('Failed to write target file to disk.');

break;

case 8:

throw new Exception('File upload stopped by extension.');

break;

}

}

}

?>



物件使用範例




try{

if($_POST['send']){

require_once 'fileuploader.php';

$fileUploader=new FileUploader();

if($fileUploader->upload()){

echo 'Target file uploaded successfully!';

}

}

}




catch(Exception $e){

echo $e->getMessage();

exit();

}

?>

2008年6月10日 星期二

郵件過量

用evolution收信,一段時間後信箱容量超過2G,就不能再收信,覺得很悶,找了一下郵件的放置位置,發現evolution中同一個資料夾的郵件都放在同一個檔案裡頭,難怪資料夾的容量到了一定上限就不能再存了.

上網找了一下資料,解決方式不難,只要再建一個資料夾,建立新的郵件規則,將收到的信都存到這個資料夾中,就解決了.

測試了一下,果然可以繼續收信,只不過不知道有沒有漏掉重要的信件.

workbench的使用



http://dev.mysql.com/downloads/workbench/5.0.html

MySQL Workbench可以很方便的畫出EER(enhance entity relationship)圖,圖形介面的操作方式非常容易上手,可以很快的畫出資料表跟資料表之間的關係,要修改資料表或資料庫的設定也非常容易,用滑鼠點一點、按一按,就修改好了,這種針對資料庫的專用工具,比起自己用freemind或dia畫EER圖,更有效率,由於Workbench將資料庫層面的物件關係加在設計裡頭,也更容易看出資料表之間的關連,不用自己發揮想像力,克難地使用不適當地工具,進行資料庫的設計。

用workbench畫好EER圖後,這張EER圖可以依使用者的需求輸出成pdf、圖檔或是sql命令,最方便地部份就是輸出成sql命令了,將資料庫設計好後,直接將sql命令匯到mysql server後,整個資料庫就在server上全部建立完成了。只不過根據我自己的測試,workbench有一項小缺點,他不會檢查foreign key的型態與referenced key的型態是否一致,這二個如果不一致是沒辦法在mysql裡頭建立資料表的,但workbench不會檢查這項錯誤,如果將這類的sql命令匯入mysql中,資料表會無法建立,致於還有沒有其他的缺點,就不清楚了。

workbench目前只有window版,沒有linux版,有點不方便,我家裡的電腦已經換成ubuntu了,如果沒有linux版,在家裡就沒辦法用了,不過網站上的roadmap,指出今年會推出linux版,看來需要耐心等待linux版的推出,不然就要再想想別的辦法了。

2008年6月6日 星期五

Zend Controller設計概念

Zend Controller是Zend Framework的核心元件,Zend Controller 實做了MVC及Front Controller的設計模式,使用MVC可以將網站程式的商業邏輯及呈現外貌的程式碼分離,Front Controller會將使用者的送出的要求全部導向單人入口。

為了顧及程式的延展性,Zend Controller可以讓程式設計師subclass,或是使用interface及abstract的方式擴增程式的功能,或是撰寫plugin及action helper達到相同的功能。

Zend Controller的設計提供一個撰寫程式的架構,基本上,遵循這些設計模式,幾乎大部份的程式功能都可以有條不紊的實做出來,Zend Controller的架構比自己建立的架構,具有更高的流通性,由於Zend網站上就有現成的文件及程式碼解說,與別人進行交流時不用再重頭適應彼此的撰寫模式及架構,也可避免大家都浪費心力做同一件事情--建立基礎架構,而且Zend Controller的架構都是高手建構出來的,模仿他們的設計,可以吸取高手的菁華,快速提升程式碼的品質。

2008年6月5日 星期四

css概念


參考網址

http://www.hsiu28.net/style/

http://css.1keydata.com/tw/



如果以我的思考方式解釋css(cascading style sheet),css是一種表現網頁物件的方式,在css中,每個物件都是一個box,這個box中可以出現文字、圖片,也能設定這個box的邊框大小、背景的樣式,box中出現的文字、圖片也可以再進行設定,在網頁中出現的大大小小的box,組成了整個網頁的外貌。

組成網頁的box,可以在box中再裝進其他的box,或是進行box位置的排列,這會產生許多不同的變化,讓網頁產生不同的面貌,使用這種方式設計網頁,會使整個網頁的程式碼減少,因為是以box為單位,進行設定,而不是對所有的單一元素進行設定,而且不同的box,可以使用套用相同的設定,這樣不但使程式碼減少,而且網頁內容—html碼,及網頁呈現方式—css碼,可以完全分離,如果要改變網頁的外貌,只要更改css碼,所有的網頁外觀就會立刻更換,而不用繁鎖的一一更改所有網頁元素的設定。

花了點時間,用freemind把css的模式畫出來,也標記了常用的屬性,這樣要用到時就比較方便了,不用再上網查css屬性要怎麼用,也比較不容易在box model的迷宮中走失。

善用工具,不求甚解

以前從國小升上國中時,翻看數學,物理,化學,這些科目的教科書,感覺有如天書,經過一段時間後,與書本那種遙遠的距離感消失了,但那神秘感也消失殆盡,只感覺這些只是用另一種不常見的符號,解釋周遭現象的另一種方式.但心裡總覺得這些背後應該還有更神秘的原理支配著,這種感覺常讓我懷疑,學習這些東西,並沒有真的碰到核心.

剛接觸php程式語言時,也是一頭霧水,等到了解基本語法時,就會感覺好像只是運用一些語句,組合出各種狀況下要電腦做的事情,似乎又是另外一種換句話說的方式,底層的運作到底是怎麼樣的一個狀況,這個問題一直縈繞心頭.

接觸的電腦知識稍微廣些後,知道要通透了解整個的運作是不可能的,跟php相關的電腦議題含括apach,mysql,linux,c語言,設計模式等,要再搞懂底下的這些就要再花很大的功夫,如果再延伸下去,那是沒完沒了的.

很多底層的東西,只要大概了解就好,不須全盤鑽研,就像建築師,只要能善用建築材料,組合出客戶想要的建築物就可以了,甚於房子怎麼搭,鋼筋怎麼綁,那是另一種專業,不需太過清楚,如果一個建築師花大量的心力在研究怎麼砌磚頭,那他大概不會是一位出色的建築師,也許磚頭砌得很好,但建物的造型設計,人性化等方面大概很難兼顧.

接觸php必須以宏觀角度審視整個程式運作流程,致於函數的底層運作機制,不須全盤了解,就像建築師一樣,只要會善用最適當的材料,工法,就能組合出最佳設計,php也一樣,善用工具,才能以宏觀角度使整 個程式運作更符合需求,否則會陷入不斷追求最佳工具的迴圈中,跳脫不出來.