食物禁忌

          蝦+維C=中毒   感冒藥+可樂=中毒
          還有一些,你知道么?!
          1、雞蛋忌糖精┄┄同食中毒、死亡
          2、豆腐忌蜂蜜┄┄同食耳聾
          3、海帶忌豬血┄┄同食便秘
          4、土豆忌香蕉┄┄同食生雀斑
          5、牛肉忌紅糖┄┄同食脹死人
          6、狗肉忌黃鱔┄┄同食則死
          7、羊肉忌田螺┄┄同食積食腹脹
          8、芹菜忌兔肉┄┄同食脫頭發
          9、番茄忌綠豆┄┄同食傷元氣
          10、螃蟹忌柿子┄┄同食腹瀉
          11、鵝肉忌鴨梨┄┄同食傷腎臟
          12、洋蔥忌蜂蜜┄┄同食傷眼睛
          13、黑魚忌茄子┄┄同食肚子痛
          14、甲魚忌莧菜┄┄同食中毒
          15、皮蛋忌紅糖┄┄同食作嘔
          16、人參忌蘿卜┄┄同食積食滯氣
          17、白酒忌柿子┄┄同食心悶

          不能一起吃的食物:
          1.紅薯和柿子——會得結石
          2.雞蛋和糖精——容易中毒
          3.洋蔥和蜂蜜——傷害眼睛
          4.豆腐和蜂蜜——引發耳聾
          5.蘿卜和木耳——皮膚發炎
          6.芋頭和香蕉——腹脹
          7.花生和黃瓜——傷害腎臟
          8.牛肉和栗子——引起嘔吐
          9.兔肉和芹菜——容易脫發
          10.螃蟹和柿子——腹瀉
          11.鯉魚和甘草——會中毒
          以下食物在兩小時內一定不要同吃:
          羊肉忌西瓜———同食 傷元氣
          牛肉忌栗子———同食嘔吐
          柿子忌螃蟹———同食腹瀉
          雞蛋忌糖精———同食中毒
          兔肉忌芹菜———同食脫發
          鵝肉忌雞蛋———同食傷元氣
          洋蔥忌蜂蜜———同食傷眼睛
          黃瓜忌花生———同食傷身
          香蕉忌芋頭———同食腹脹
          豬肉忌菱角———同食肚子痛
          豆腐忌蜂蜜———同食耳聾
          蘿卜忌木耳———同食得皮炎
          狗肉忌綠豆———同食多吃易中毒
          馬肉忌木耳———同食得霍亂
          牛肉忌毛姜———同食中毒死亡
          羊肉忌梅干菜——同食生心悶
          雞肉忌芥菜———同食傷元氣
          驢肉忌黃花———同食心痛致命
          兔肉忌小白菜——同食易嘔吐
          鵝肉忌鴨梨———同食好生熱病
          黑魚忌茄子———同食易得霍亂
          海蟹忌大棗———同食易得瘧疾
          芥菜忌鴨梨———同食發嘔
          馬鈴薯忌香蕉———同食面部生斑

          一些蔬菜不能搭配吃 :
          豬肉菱角同食會肝疼,羊肉西瓜相會定互侵;
          狗肉如遇綠豆會傷身,蘿卜水果不利甲狀腺;
          鯉魚甘草加之將有害,蟹與柿子結伴會中毒;
          甲魚黃鱔與蟹孕婦忌,雞蛋再吃消炎片相沖;
          柿子紅薯搭配結石生,豆漿營養不宜沖雞蛋;
          洋蔥蜂蜜相遇傷眼睛,蘿卜木耳成雙生皮炎;
          豆腐蜂蜜相拌耳失聰,菠菜豆腐色美實不宜;
          胡蘿卜白蘿卜相互沖,蕃茄黃瓜不能一起食;
          香蕉芋艿入胃酸脹痛,馬鈴薯香蕉面部起斑。

          不宜吃的食物 :
          1、發芽、發青的土豆有毒,不能吃。
          2、新鮮的黃花菜(金針菜)有毒,不能吃。
          3、沒有炒透的四季豆、扁豆有毒,吃不得。
          4、老雞頭(5年以上雞頭)有大毒,吃不得。
          5、嫩炒豬肝,含有毒素,不宜吃。
          6、皮蛋、爆米花含鉛特別多,兒童不宜吃。
          7、烤焦的食物不能吃,吃后易患癌。
          8、爛姜有極毒,能壞死肝細胞,切不可吃。
          9、生豆油含有苯,會破壞造血系統,不可吃。
          10、久煮的水含有亞硝酸鹽,吃則易生癌。
          11、太燙食物不能吃,易燙傷消化道引起癌變。
          12、未熟透的豆漿不能吃,吃易中毒。
          13、腌制的食物含有致癌物質,不宜多吃。
          14、烘烤的肉串類、魚片含致癌物,不宜多吃。
          15、柿子空服易患胃內柿結石,千萬不要吃。
          16、食品添加劑、人造食素、香料、香精、皮蛋、方便面、午餐肉、油炸食物不宜多吃。

          posted @ 2010-03-31 10:14 小馬歌 閱讀(258) | 評論 (0)編輯 收藏
           

          我曾經愛過這樣一個男人
          他的名字是被叫做馬化騰
          他的公司很賺錢就是騰訊
          一直靠抄襲創新,
          也是這個被我深愛的男人
          把中國互聯網變成了孤墳
          他卻賺了很多很多money
          每一個創新他都會去抄襲
          不管創業者心疼

          我的要求并不高
          別把產品都抄掉
          奪走創業者佳肴
          可是每一天都在做同樣的抄 _
          最近他們又買下了開心農場
          要挾進入他懷抱

          你身上有太多的銅臭
          是我鼻子犯的罪,
          不該看到企鵝腿
          世界就此一起碎

          你想獨霸中國互聯網
          仗著產品線很多
          你的口吻太嚇人
          我永遠都別想睡

          posted @ 2010-03-31 10:13 小馬歌 閱讀(180) | 評論 (0)編輯 收藏
           
           
          1、精心編輯采集內容,或以專題的方式介紹采集的內容。

          2、加上自己的觀點,評點內容的精華。

          3、以專家的身份去寫原創內容,強調你的專業性。

          4、內容的可讀性,不要口水話太多。

          5、網站保持更新頻率,不管你內容多好,一個持久不更新的網站,最終會留失很多用戶。

          6、讓用戶可以和你的網站有互動的窗口,如百谷精SEO論壇、評論等,現在流行豆瓣和digg模式也不錯。

          7、讓用戶和你分享網站收入,這招也不錯的,例如幫你推廣網站或寫文章,用戶都有一定比例的收入。

          8、讓你的網站與眾不同,獨特的美工,獨特的內容,引用zac的一句話“沒有創意,沒有眼球”。
          posted @ 2010-03-15 11:03 小馬歌 閱讀(189) | 評論 (0)編輯 收藏
           
          下述十四個技巧,是許多人在大量的數據庫分析與設計實踐中,逐步總結出來的。對于這些經驗的運用,讀者不能生幫硬套,死記硬背,而要消化理解,實事求是,靈活掌握。并逐步做到:在應用中發展,在發展中應用。

            1. 原始單據與實體之間的關系

            可以是一對一、一對多、多對多的關系。在一般情況下,它們是一對一的關系:即一張原始單據對應且只對應一個實體。在特殊情況下,它們可能是一對多或多對一的關系,即一張原始單證對應多個實體,或多張原始單證對應一個實體。這里的實體可以理解為基本表。明確這種對應關系后,對我們設計錄入界面大有好處。

            〖例1〗:一份員工履歷資料,在人力資源信息系統中,就對應三個基本表:員工基本情況表、社會關系表、工作簡歷表。這就是“一張原始單證對應多個實體”的典型例子。

            2. 主鍵與外鍵

            一般而言,一個實體不能既無主鍵又無外鍵。在E?R 圖中, 處于葉子部位的實體, 可以定義主鍵,也可以不定義主鍵(因為它無子孫), 但必須要有外鍵(因為它有父親)。

            主鍵與外鍵的設計,在全局數據庫的設計中,占有重要地位。當全局數據庫的設計完成以后,有個美國數據庫設計專家說:“鍵,到處都是鍵,除了鍵之外,什么也沒有”,這就是他的數據庫設計經驗之談,也反映了他對信息系統核心(數據模型)的高度抽象思想。因為:主鍵是實體的高度抽象,主鍵與外鍵的配對,表示實體之間的連接。

            3. 基本表的性質

            基本表與中間表、臨時表不同,因為它具有如下四個特性:

            (1) 原子性。基本表中的字段是不可再分解的。

            (2) 原始性。基本表中的記錄是原始數據(基礎數據)的記錄。

            (3) 演繹性。由基本表與代碼表中的數據,可以派生出所有的輸出數據。

            (4) 穩定性。基本表的結構是相對穩定的,表中的記錄是要長期保存的。

            理解基本表的性質后,在設計數據庫時,就能將基本表與中間表、臨時表區分開來。

            4. 范式標準

            基本表及其字段之間的關系, 應盡量滿足第三范式。但是,滿足第三范式的數據庫設計,往往不是最好的設計。為了提高數據庫的運行效率,常常需要降低范式標準:適當增加冗余,達到以空間換時間的目的。

            〖例2〗:有一張存放商品的基本表,如表1所示。“金額”這個字段的存在,表明該表的設計不滿足第三范式,因為“金額”可以由“單價”乘以“數量”得到,說明“金額”是冗余字段。但是,增加“金額”這個冗余字段,可以提高查詢統計的速度,這就是以空間換時間的作法。

            在Rose 2002中,規定列有兩種類型:數據列和計算列。“金額”這樣的列被稱為“計算列”,而“單價”和“數量”這樣的列被稱為“數據列”。

            表1 商品表的表結構

            商品名稱 商品型號 單價 數量 金額

            電視機 29? 2,500 40 100,000

            5. 通俗地理解三個范式

            通俗地理解三個范式,對于數據庫設計大有好處。在數據庫設計中,為了更好地應用三個范式,就必須通俗地理解三個范式(通俗地理解是夠用的理解,并不是最科學最準確的理解):

            第一范式:1NF是對屬性的原子性約束,要求屬性具有原子性,不可再分解;

            第二范式:2NF是對記錄的惟一性約束,要求記錄有惟一標識,即實體的惟一性;

            第三范式:3NF是對字段冗余性的約束,即任何字段不能由其他字段派生出來,它要求字段沒有冗余.

            沒有冗余的數據庫設計可以做到。但是,沒有冗余的數據庫未必是最好的數據庫,有時為了提高運行效率,就必須降低范式標準,適當保留冗余數據。具體做法是:在概念數據模型設計時遵守第三范式,降低范式標準的工作放到物理數據模型設計時考慮。降低范式就是增加字段,允許冗余。

            6. 要善于識別與正確處理多對多的關系

            若兩個實體之間存在多對多的關系,則應消除這種關系。消除的辦法是,在兩者之間增加第三個實體。這樣,原來一個多對多的關系,現在變為兩個一對多的關系。要將原來兩個實體的屬性合理地分配到三個實體中去。這里的第三個實體,實質上是一個較復雜的關系,它對應一張基本表。一般來講,數據庫設計工具不能識別多對多的關系,但能處理多對多的關系。

            〖例3〗:在“圖書館信息系統”中,“圖書”是一個實體,“讀者”也是一個實體。這兩個實體之間的關系,是一個典型的多對多關系:一本圖書在不同時間可以被多個讀者借閱,一個讀者又可以借多本圖書。為此,要在二者之間增加第三個實體,該實體取名為“借還書”,它的屬性為:借還時間、借還標志(0 表示借書,1表示還書),另外,它還應該有兩個外鍵(“圖書”的主鍵,“讀者”的主鍵),使它能與“圖書”和“讀者”連接。

            7. 主鍵PK的取值方法

            PK是供程序員使用的表間連接工具,可以是一無物理意義的數字串, 由程序自動加1來實現。也可以是有物理意義的字段名或字段名的組合。不過前者比后者好。當PK是字段名的組合時,建議字段的個數不要太多,多了不但索引占用空間大,而且速度也慢。

            8. 正確認識數據冗余

            主鍵與外鍵在多表中的重復出現, 不屬于數據冗余,這個概念必須清楚,事實上有許多人還不清楚。非鍵字段的重復出現, 才是數據冗余!而且是一種低級冗余,即重復性的冗余。高級冗余不是字段的重復出現,而是字段的派生出現。

            〖例4〗:商品中的“單價、數量、金額”三個字段,“金額”就是由“單價”乘以“數量”派生出來的,它就是冗余,而且是一種高級冗余。冗余的目的是為了提高處理速度。只有低級冗余才會增加數據的不一致性,因為同一數據,可能從不同時間、地點、角色上多次錄入。因此,我們提倡高級冗余(派生性冗余),反對低級冗余(重復性冗余)。

            9. E--R圖沒有標準答案

            信息系統的E--R圖沒有標準答案,因為它的設計與畫法不是惟一的,只要它覆蓋了系統需求的業務范圍和功能內容,就是可行的。反之要修改E-- R圖。盡管它沒有惟一的標準答案,并不意味著可以隨意設計。好的E?R圖的標準是:結構清晰、關聯簡潔、實體個數適中、屬性分配合理、沒有低級冗余。

            10. 視圖技術在數據庫設計中很有用

            與基本表、代碼表、中間表不同,視圖是一種虛表,它依賴數據源的實表而存在。視圖是供程序員使用數據庫的一個窗口,是基表數據綜合的一種形式, 是數據處理的一種方法,是用戶數據保密的一種手段。為了進行復雜處理、提高運算速度和節省存儲空間, 視圖的定義深度一般不得超過三層。若三層視圖仍不夠用, 則應在視圖上定義臨時表, 在臨時表上再定義視圖。這樣反復交迭定義, 視圖的深度就不受限制了。

            對于某些與國家政治、經濟、技術、軍事和安全利益有關的信息系統,視圖的作用更加重要。這些系統的基本表完成物理設計之后,立即在基本表上建立第一層視圖,這層視圖的個數和結構,與基本表的個數和結構是完全相同。并且規定,所有的程序員,一律只準在視圖上操作。只有數據庫管理員,帶著多個人員共同掌握的“安全鑰匙”,才能直接在基本表上操作。請讀者想想:這是為什么?

            11. 中間表、報表和臨時表

            中間表是存放統計數據的表,它是為數據倉庫、輸出報表或查詢結果而設計的,有時它沒有主鍵與外鍵(數據倉庫除外)。臨時表是程序員個人設計的,存放臨時記錄,為個人所用。基表和中間表由DBA維護,臨時表由程序員自己用程序自動維護。

            12. 完整性約束表現在三個方面

            域的完整性:用Check來實現約束,在數據庫設計工具中,對字段的取值范圍進行定義時,有一個Check按鈕,通過它定義字段的值城。參照完整性:用PK、FK、表級觸發器來實現。用戶定義完整性:它是一些業務規則,用存儲過程和觸發器來實現。

            13. 防止數據庫設計打補丁的方法是“三少原則”

            (1) 一個數據庫中表的個數越少越好。只有表的個數少了,才能說明系統的E--R圖少而精,去掉了重復的多余的實體,形成了對客觀世界的高度抽象,進行了系統的數據集成,防止了打補丁式的設計;

            (2) 一個表中組合主鍵的字段個數越少越好。因為主鍵的作用,一是建主鍵索引,二是做為子表的外鍵,所以組合主鍵的字段個數少了,不僅節省了運行時間,而且節省了索引存儲空間;

            (3) 一個表中的字段個數越少越好。只有字段的個數少了,才能說明在系統中不存在數據重復,且很少有數據冗余,更重要的是督促讀者學會“列變行”,這樣就防止了將子表中的字段拉入到主表中去,在主表中留下許多空余的字段。所謂“列變行”,就是將主表中的一部分內容拉出去,另外單獨建一個子表。這個方法很簡單,有的人就是不習慣、不采納、不執行。

            數據庫設計的實用原則是:在數據冗余和處理速度之間找到合適的平衡點。“三少”是一個整體概念,綜合觀點,不能孤立某一個原則。該原則是相對的,不是絕對的。“三多”原則肯定是錯誤的。試想:若覆蓋系統同樣的功能,一百個實體(共一千個屬性) 的E--R圖,肯定比二百個實體(共二千個屬性) 的E--R圖,要好得多。

            提倡“三少”原則,是叫讀者學會利用數據庫設計技術進行系統的數據集成。數據集成的步驟是將文件系統集成為應用數據庫,將應用數據庫集成為主題數據庫,將主題數據庫集成為全局綜合數據庫。集成的程度越高,數據共享性就越強,信息孤島現象就越少,整個企業信息系統的全局E?R圖中實體的個數、主鍵的個數、屬性的個數就會越少。

            提倡“三少”原則的目的,是防止讀者利用打補丁技術,不斷地對數據庫進行增刪改,使企業數據庫變成了隨意設計數據庫表的“垃圾堆”,或數據庫表的“大雜院”,最后造成數據庫中的基本表、代碼表、中間表、臨時表雜亂無章,不計其數,導致企事業單位的信息系統無法維護而癱瘓。

            “三多”原則任何人都可以做到,該原則是“打補丁方法”設計數據庫的歪理學說。“三少”原則是少而精的原則,它要求有較高的數據庫設計技巧與藝術,不是任何人都能做到的,因為該原則是杜絕用“打補丁方法”設計數據庫的理論依據。

            14. 提高數據庫運行效率的辦法

            在給定的系統硬件和系統軟件條件下,提高數據庫系統的運行效率的辦法是:

            (1) 在數據庫物理設計時,降低范式,增加冗余, 少用觸發器, 多用存儲過程。

            (2) 當計算非常復雜、而且記錄條數非常巨大時(例如一千萬條),復雜計算要先在數據庫外面,以文件系統方式用C++語言計算處理完成之后,最后才入庫追加到表中去。這是電信計費系統設計的經驗。

            (3) 發現某個表的記錄太多,例如超過一千萬條,則要對該表進行水平分割。水平分割的做法是,以該表主鍵PK的某個值為界線,將該表的記錄水平分割為兩個表。若發現某個表的字段太多,例如超過八十個,則垂直分割該表,將原來的一個表分解為兩個表。

            (4) 對數據庫管理系統DBMS進行系統優化,即優化各種系統參數,如緩沖區個數。

            (5) 在使用面向數據的SQL語言進行程序設計時,盡量采取優化算法。

            總之,要提高數據庫的運行效率,必須從數據庫系統級優化、數據庫設計級優化、程序實現級優化,這三個層次上同時下功夫。
          posted @ 2010-03-10 14:55 小馬歌 閱讀(154) | 評論 (0)編輯 收藏
           
           /***                 phpall技術交流群:75345798

                          英文原文:http://net.tutsplus.com/tutorials/php/6-codeigniter-hacks-for-the-masters/
                          翻譯原文:http://www.phpall.cn/forum/read.php?tid=389
                    ***/
                Codeigniter是一個簡潔而又強大的開源web應用框架。今天,我們將會使用一些核心的技巧來對這個框架做一些小的改變并提高它的性能。
          在這過程之中,你將會對框架得到一個更好的理解。
          作者:burak guze


                他是一個住在亞利桑那州的全職php web開發者,從伊斯坦布爾來的。他獲得了計算機科學與工程的學士學                 位。他擁有8年的phpmysql工作經驗。你能閱讀他的更多的文章在PHPandStuff.com,他的twitter
          here


          聲明

          1.不推薦在已經存在的項目中使用這些技巧。因為他們改變了ci的核心功能,可能會使已經寫的代碼崩潰。
          2.我寫這篇文章的時候,ci1.7.2版本是最新的發行版本,這些技巧對以前的版本沒有作用。
          3.盡管ci是被設計php4兼容的。但是這些技巧需要你安裝php5.
          4.當你對cisystem文件做的任何更改,你都應該對這些改變做好記錄,供以后參考。下次當你升級ci的時候,你可能需要重新再處理這些變化。

          1.大師的6個codeigniter技巧——(1)自動加載models——php5風格


          這個技巧希望達到的目標是:

                在左邊,你會看到在controller里面通常加載model的方法。使用這個技巧以后,我們將能夠直接創建這個model對象。
          這個代碼是簡潔的并且容易理解對象。
              使用這個技巧以后會有2個影響。首先你不再需要繼承model類了。


          這個技巧

          我們需要做的就是添加一個php5風格的 autolader 函數

          添加這些代碼到system/application/config/config.php:
          <?php  
          // ...  
          function __autoload($class) {  
              if (file_exists(APPPATH."models/".strtolower($class).EXT)) {  
                  include_once(APPPATH."models/".strtolower($class).EXT);  
              }  
          }  
          ?>
          如果你也有興趣運用這個技巧到controller,你只需要添加以下代碼來代替上面的代碼。

          <?php  
          // ...  
          function __autoload($class) {  
              if (file_exists(APPPATH."models/".strtolower($class).EXT)) {  
                  include_once(APPPATH."models/".strtolower($class).EXT);  
              } else if (file_exists(APPPATH."controllers/".strtolower($class).EXT)) {  
                  include_once(APPPATH."controllers/".strtolower($class).EXT);  
              }  
          }  
          ?>
          任何時候,你試著使用一個沒有定義的類時候,這個__autoload函數將會被調用,它將會加載這個類文件。

          2.大師的6個codeigniter技巧——(2)防止model-controller名字沖突

          使用這個技巧要達到的目標:

          一般來說,模型和控制器你都不會有相同的類名字。讓我先創建一個取名為postmodel
          class Post extends Model {  

              // ...  

          }
          現在你就不能有一個像這樣的url
          http://www.mysite.com/post/display/13
          這個原因是因為你也需要有一個名字為postcontroller,如果創建了這樣的一個類的話將會引起致命錯誤。
          但是使用了這個技巧一般,一切皆有可能。那個url的控制器看起來是這樣的:

          // application/controllers/post.php  
          class Post_controller extends Controller {  

              // ...  

          }
          注意這個“__controller”后綴
          技巧:

          為了避免這個問題,通常大多數人都是添加‘_model’后綴到model名字(例如命名Post_model)。
          在所有的應用程序Model對象都被創建和引用,所以在所有的model名字后面跟上‘_model’有些無聊。
          我認為最好的辦法就是在controller上來添加后綴,因為在代碼中controller的名字幾乎從來不會被引用。
          首先我們需要繼承Router class。創建這樣一個文件:"application/libraries/MY_Router.php"
          class MY_Router extends CI_Router {  
              var $suffix = '_controller';  

              function MY_Router() {  
                  parent::CI_Router();  
              }  
              function set_class($class) {  
                  $this->class = $class . $this->suffix;  
              }  
              function controller_name() {  
                  if (strstr($this->class, $this->suffix)) {  
                      return str_replace($this->suffix, '', $this->class);  
                  }  
                  else {  
                      return $this->class;  
                  }  
              }  
          }  
          現在編輯"system/codeigniter/CodeIgniter.php"
          153
          if ( ! file_exists(APPPATH.'controllers/'.$RTR->fetch_directory().$RTR->controller_name().EXT))  
          然后第158

          include(APPPATH.'controllers/'.$RTR->fetch_directory().$RTR->controller_name().EXT);  

          然后編輯"system/libraries/Profiler.php"的第323

          $output .= "<div style="color:#995300;font-weight:normal;padding:4px 0 4px 0">".$this->CI->router->controller_name()."/".$this->CI->router->fetch_method()."</div>";  
          大功告成。使用這個技巧一定需要記住的是要把‘_controller’后綴放到你的controller的類的名字后面,不是放在你的控制器文件名中。


          大師的6個codeigniter技巧——(3)表單驗證“唯一值”(如注冊用戶名email)
                Ci有一個完美的表單驗證類。但是這個驗證有一點不足,例如當大部分用戶注冊用戶名的時候,需要驗證用戶名沒有被占用,或者郵箱是否存在在系統中。
          使用這個技巧,你將能夠非常容易添加這項驗證規則到你的表單提交中。

          注意最后一部分"unique[User.username]."這個新的驗證規則叫做“unique”,并且帶了一個方框在這個中括號中,它們是“tablename.filedname.所以它將會檢測數據庫的“user數據表的“username”列確定提交的值在數據庫里面不存在。
          同理,你也能利用這個規則驗證相同的郵件地址。
          $this->form_validation->set_rules('email', 'E-mail',  
                  'required|valid_email|unique[User.email]');  
          你的應用程序將會得到以下錯誤信息

          與其說這是一個技巧而不如說是一個擴展。雖然如此,我們將要添加一個核心ci類庫并且改善它。
          創建 "application/libraries/MY_Form_validation.php"文件

          class MY_Form_validation extends CI_Form_validation {  

              function unique($value, $params) {  

                  $CI =& get_instance();  
                  $CI->load->database();  

                  $CI->form_validation->set_message('unique',  
                      'The %s is already being used.');  

                  list($table, $field) = explode(".", $params, 2);  

                  $query = $CI->db->select($field)->from($table)  
                      ->where($field, $value)->limit(1)->get();  

                  if ($query->row()) {  
                      return false;  
                  } else {  
                      return true;  
                  }  

              }  
          }
          現在你就能使用這個“唯一”驗證規則了。

          4.大師的6個codeigniter技巧——(4)從命令行運行codeigniter

          目標:
          就像這個標題所說,我們的目標是能夠從命令行運行ci。對于創建定時任務,這個是必須的,或者是運行更多的特別的操作,
          所以你沒有web腳本的資源限制,就像最大執行時間一樣。
          這就是本地windows機器上面運行的效果

          技巧
          創建一個“cli.php”文件在ci的根目錄(即與index.php在同一目錄)
          if (isset($_SERVER['REMOTE_ADDR'])) {  
              die('Command Line Only!');  
          }  
          set_time_limit(0);  
          $_SERVER['PATH_INFO'] = $_SERVER['REQUEST_URI'] = $argv[1];  
          require dirname(__FILE__) . '/index.php';

          如果你在linux環境下使用,并且想要讓這代碼自動執行,你能添加以下代碼在cli.php文件的第一行

          #!/usr/bin/php  
          如果你需要一個僅僅能在命令行下使用的控制器,你能阻止web調用控制器構造函數
          class Hello extends Controller {  
              function __construct() {  
                  if (isset($_SERVER['REMOTE_ADDR'])) {  
                      die('Command Line Only!');  
                  }  
                  parent::Controller();  
              }  

              // ...  
          }

          5.大師的6個codeigniter技巧——(5)添加Doctrine orm 到codeigniter
          (Doctrine orm是一個比較復雜的東西,我們將會繼續出一些相關教程
          目標
          Doctine是一個流行的php的關系對象映射(orm)。添加它到ci里面以后,你將會一個更加強大的模型層。

          技巧:
          其實安裝Doctrine不是那么難,就像安裝插件一樣。然后一旦安裝成功,你的model類將需要繼承Doctrine基類,而不是繼承cimodel類。這將會完全改變model層的工作方式。你建立的對象將會有持久的數據庫連接并且也將能有其他對象的數據庫關系。
          按照以下幾步:
          1. 建立文件夾:application/plugins
          2. 創建文件夾:application/plugins/doctrine
          3. 下載文件(1.2版本的)
          4. Doctrine復制“lib”文件夾到“application/plugins/doctrine
          5. 創建“application/plugins/doctrine_pi.php

          // system/application/plugins/doctrine_pi.php  
          // load Doctrine library  
          require_once APPPATH.'/plugins/doctrine/lib/Doctrine.php';  
          // load database configuration from CodeIgniter  
          require_once APPPATH.'/config/database.php';  
          // this will allow Doctrine to load Model classes automatically  
          spl_autoload_register(array('Doctrine', 'autoload'));  
          // we load our database connections into Doctrine_Manager  
          // this loop allows us to use multiple connections later on  
          foreach ($db as $connection_name => $db_values) {  
              // first we must convert to dsn format  
              $dsn = $db[$connection_name]['dbdriver'] .  
                  '://' . $db[$connection_name]['username'] .  
                  ':' . $db[$connection_name]['password'].  
                  '@' . $db[$connection_name]['hostname'] .  
                  '/' . $db[$connection_name]['database'];  
              Doctrine_Manager::connection($dsn,$connection_name);  
          }  
          // CodeIgniter's Model class needs to be loaded  
          require_once BASEPATH.'/libraries/Model.php';
          // telling Doctrine where our models are located
          Doctrine::loadModels(APPPATH.'/models');  

          然后,編輯‘application/config/autoload.php’自動加載Doctrine插件
          $autoload['plugin'] = array('doctrine');
          你也要確定在“application/config/database.php的數據庫配置好了,”
          就這樣,現在你就能使用ci應用程序創建Doctrine模型了。閱讀更多的資源在這里

          6.大師的6個codeigniter技巧——(6)運行多個站點
          目標:
          這個技巧將會使安裝一個codeigniter就能運行多個站點成為可能,每個站點有它自己的application文件夾,但是他們共享這相同的系統文件夾。

          技巧
          安裝ci服務器的任何位置。然后將application文件夾從system文件夾拿出來。放在外面,請看上面的圖片。
          現在復制index.php文件到每個站點的跟目錄下面(即圖中的application_site1application_site2等)
          然后編輯它:
          在第26行,給出system文件夾的完整路徑
          $system_folder = dirname(__FILE__) . '../codeigniter/system';  
          在第43行,給出application文件夾的文章路徑
          $application_folder = dirname(__FILE__) . '../application_site1';  
          現在你就能使用獨立的application文件夾來建立不同的站點了,而只是共享同一個system文件夾
          這里有一個相似的操作在ci用戶手冊



          7.大師的6個codeigniter技巧——(7)允許所有類型的文件上傳
          目標:
          當使用ci的上傳類的時候,你必須指明哪些文件類型允許上傳。

          復制代碼
          • $this->load->library('upload');   $this->upload->set_allowed_types('jpg|jpeg|gif|png|zip');

          如果你沒有指明特定的上傳類型,你將會從ci那里得到一個錯誤信息"Youhave not specified any allowed file types."
          所有,默認的方式,將沒有辦法允許所有的文件上傳。我們需要做一些小的改變來處理這個限制。我們設定“*”將能夠運行所有類型的文件上傳。

          復制代碼
          • $this->load->library('upload');   $this->upload->set_allowed_types('*');
          技巧:
          我們需要修改上傳文件類。
          創建文件:application/librarys/My_upload.php
          class MY_Upload extends CI_Upload {  
              function is_allowed_filetype() {  
                  if (count($this->allowed_types) == 0 OR ! is_array($this->allowed_types))  
                  {  
                      $this->set_error('upload_no_file_types');  
                      return FALSE;  
                  }  
                  if (in_array("*", $this->allowed_types))  
                  {  
                      return TRUE;  
                  }  
                  $image_types = array('gif', 'jpg', 'jpeg', 'png', 'jpe');  
                  foreach ($this->allowed_types as $val)  
                  {  
                      $mime = $this->mimes_types(strtolower($val));  

                      // Images get some additional checks  
                      if (in_array($val, $image_types))  
                      {  
                          if (getimagesize($this->file_temp) === FALSE)  
                          {  
                              return FALSE;  
                          }  
                      }  
                      if (is_array($mime))  
                      {  
                          if (in_array($this->file_type, $mime, TRUE))  
                          {  
                              return TRUE;  
                          }  
                      }  
                      else  
                      {  
                          if ($mime == $this->file_type)  
                          {  
                              return TRUE;  
                          }  
                      }  
                  }  
                  return FALSE;  
              }  
          posted @ 2010-01-11 16:09 小馬歌 閱讀(2483) | 評論 (0)編輯 收藏
           
          from : http://blog.csdn.net/phphot/archive/2009/04/29/4134913.aspx

          最近發現兩臺MySQL server在中午的時候忽然(很突然的那種)發飆,不斷的掛掉。重啟mysql也盡是失敗,看mysql的errorlog,只能看到類似如下的信息:

          Forcing close of thread 12232 user: 'root'

          用mysqladmin 簡單的監控了下mysql的情況:

          mysqladmin -uroot -p******** status -i 1

          發現Queries per second avg只有200左右,可以說很低,但是Threads 確非常不穩定,居然會瞬間升級200以上,一般情況下這個線程這個值都是不會高于5的個位數!

          然后繼續看

          mysqladmin -uroot -p******** processlist

          居然有大量的unauthenticated user?? 如下情況

          +------+-----------+---------+----+---------+------+-------+------------------+
          [root@app028 ~]# mysqladmin -uroot -p************ processlist
          +------+-----------+---------+----+---------+------+-------+------------------+
          | Id   | User                 | Host               | db | Command | Time | State | Info       |
          +------+-----------+---------+----+---------+------+-------+------------------+
          | 2007 | unauthenticated user | 192.168.4.29:58519 |    | Connect |     | login | |
          | 2008 | unauthenticated user | 192.168.4.29:58553 |    | Connect |     | login | |
          | 2009 | unauthenticated user | 192.168.4.29:58571 |    | Connect |     | login | |
          | 2010 | unauthenticated user | 192.168.4.29:58577 |    | Connect |     | login | |
          | 2011 | unauthenticated user | 192.168.4.29:58579 |    | Connect |     | login | |
          | 2012 | unauthenticated user | 192.168.4.29:58589 |    | Connect |     | login | |

          google了一下,

          發現這算屬MySQL的一個bug,不管連接是通過hosts還是ip的方式,MySQL都會對DNS做反查,IP到DNS,由于反查的接續速度過慢(不管是不是isp提供的dns服務器的問題或者其他原因),大量的查詢就難以應付,線程不夠用就使勁增加線程,但是卻得不到釋放,所以MySQL會“假死”。

          解決的方案很簡單,結束這個反查的過程,禁止任何解析。

          打開mysql的配置文件(my.cnf),在[mysqld]下面增加一行:

          skip-name-resolve

          重新載入配置文件或者重啟MySQL服務即可。


          ==================================

          看下手冊中的解釋是:unauthenticated user refers to a thread that has become associated with a client connection but for which authentication of the client user has not yet been done。意即:有一個線程在處理客戶端的連接,但是該客戶端還沒通過用戶驗證。
          原因可能有:
          1、        服務器在做DNS反響解析,解決辦法有2:
          1、) 在 hosts 中添加客戶端ip,如
          192.168.0.1  yejr
          2、) MySQL啟動參數增加一個skip-name-resolve,即不啟用DNS反響解析
          2、服務器的線程還處于排隊狀態,因此可以加大 back_log
          posted @ 2009-11-24 16:55 小馬歌 閱讀(512) | 評論 (0)編輯 收藏
           
          APNIC是管理亞太地區IP地址分配的機構 ,它有著豐富準確的IP地址分配庫,同時這些信息也是對外公開的!下面就讓我們看看如何在Linux下獲得一些電信運營商的IP地址分配情況:
          shell> wget http://ftp.apnic.net/apnic/dbase/tools/ripe-dbase-client-v3.tar.gz
          shell> tar xzvf ripe-dbase-client-v3.tar.gz
          shell> cd whois-3.1
          shell> ./configure
          shell> make

          完成上述編譯安裝工作后,我們開始獲取IP地址段;

            中國網通:shell> ./whois3 -h whois.apnic.net -l -i mb MAINT-CNCGROUP > /var/cnc

            中國電信:shell> ./whois3 -h whois.apnic.net -l -i mb MAINT-CHINANET > /var/chinanet

            中國鐵通:shell> ./whois3 -h whois.apnic.net -l -i mb MAINT-CN-CRTC > /var/crtc

            打開獲取后的文件可以看到里面的信息非常詳細,甚至可以看到各個分公司的負責人、電話、電子郵件等等信息。如果想得到一份整齊干凈的IP地址段文件,只要用grep和awk簡單過濾就可以了。

          posted @ 2009-11-11 10:11 小馬歌 閱讀(263) | 評論 (0)編輯 收藏
           

          轉載的一篇REST介紹,歡迎大家去原文出處去看精彩評論:
          http://www.javaeye.com/topic/70113

          REST的基本思想。[Fielding]把REST形式化地定義為一種架構風格(architecture style),它有架構元素(element)和架構約束(constraint)組成。這些概念比較晦澀難懂,而且我們做工程的往往并不需要形而上的理解。我們只知道,REST是一種針對網絡應用的設計和開發方式,可以降低開發的復雜性,提高系統的可伸縮性。REST提出了一些設計概念和準則:

          網絡上的所有事物都被抽象為資源(resource);
          每個資源對應一個唯一的資源標識(resource identifier);
          通過通用的連接器接口(generic connector interface)對資源進行操作;
          對資源的各種操作不會改變資源標識;
          所有的操作都是無狀態的(stateless)。
          對于當今最常見的網絡應用來說,resource identifier是url,generic connector interface是HTTP,第4條準則就是我們常說的url不變性。這些概念中的resouce最容易使人產生誤解。resouce所指的并不是數據,而是數據+特定的表現形式(representation),這也是為什么REST的全名是Representational State Transfer的原因。舉個例子來說,“本月賣得最好的10本書”和“你最喜歡的10本書”在數據上可能有重疊(有一本書即賣得好,你又喜歡),甚至完全相同。但是它們的representation不同,因此是不同的resource。

          REST之所以能夠簡化開發,是因為其引入的架構約束,比如Rails 1.2中對REST的實現默認把controller中的方法限制在7個:index、show、new、edit、create、update和 destory,這實際上就是對CURD的實現。更進一步講,Rails(也是當今大部分網絡應用)使用HTTP作為generic connector interface,HTTP則把對一個url的操作限制在了4個之內:GET、POST、PUT和DELETE。

          REST之所以能夠提高系統的可伸縮性,是因為它強制所有操作都是stateless的,這樣就沒有context的約束,如果要做分布式、做集群,就不需要考慮context的問題了。同時,它令系統可以有效地使用pool。REST對性能的另一個提升來自其對client和server任務的分配: server只負責提供resource以及操作resource的服務,而client要根據resource中的data和 representation自己做render。這就減少了服務器的開銷。

          既然REST有這樣的好處,那我們應該義無反顧地擁抱它啊!目前一些大牛(像DHH)都已經開始投入到了REST的世界,那我們這些人應該做什么或者說思考寫什么你呢?我覺得我們應該思考兩個問題:

          如何使用REST;
          REST和MVC的關系。
          第一個問題假設REST是我們應該采用的架構,然后討論如何使用;第二個問題則要說明REST和當前最普遍應用的MVC是什么關系,互補還是取代?

          我們先來談談第一個問題,如何使用REST。我感覺,REST除了給我們帶來了一個嶄新的架構以外,還有一個重要的貢獻是在開發系統過程中的一種新的思維方式:通過url來設計系統的結構。根據REST,每個url都代表一個resource,而整個系統就是由這些resource組成的。因此,如果 url是設計良好的,那么系統的結構就也應該是設計良好的。對于非高手級的開發人員來說,考慮一個系統如何架構總是一個很抽象的問題。敏捷開發所提倡的 Test Driven Development,其好處之一(我覺得是最大的好處)就是可以通過testcase直觀地設計系統的接口。比如在還沒有創建一個class的時候就編寫一個testcase,雖然設置不能通過編譯,但是testcase中的方法調用可以很好地從class使用者的角度反映出需要的接口,從而為 class的設計提供了直觀的表現。這與在REST架構中通過url設計系統結構非常類似。雖然我們連一個功能都沒有實現,但是我們可以先設計出我們認為合理的url,這些url甚至不能連接到任何page或action,但是它們直觀地告訴我們:系統對用戶的訪問接口就應該是這樣。根據這些url,我們可以很方便地設計系統的結構。

          讓我在這里重申一遍:REST允許我們通過url設計系統,就像Test Driven Development允許我們使用testcase設計class接口一樣。
          (我的觀點:測試驅動開發,通過測試來設計接口是個方法。通過url設計系統,需要考慮并抽象出所有用戶的需求。這需要很強的抽象能力。。。并不像TDD那樣簡單。)

          OK,既然url有這樣的好處,那我們就著重討論一下如何設計url。網絡應用通常都是有hierarchy的,像棵大樹。我們通常希望url也能反映出資源的層次性。比如對于一個blog應用:/articles表示所有的文章,/articles/1表示id為1的文章,這都比較直觀。遺憾的是,網絡應用的資源結構永遠不會如此簡單。因此人們常常會問這樣一個問題:RESTful的url能覆蓋所有的用戶請求嗎?比如,login如何RESTful?search如何RESTful?

          從REST的概念上來看,所有可以被抽象為資源的東東都可以使用RESTful的url。因此對于上面的兩個問題,如果login和search可以被抽象為資源,那么就可以使用RESTful的url。search比較簡單,因為它會返回搜索結果,因此可以被抽象為資源,并且只實現index方法就可以了(只需要顯示搜索結果,沒有create、destory之類的東西)。然而這里面也有一個問題:search的關鍵字如何傳給server? index方法顯然應該使用HTTP GET,這會把關鍵字加到url后面,當然不符合REST的風格。要解決這個問題,可以把每次search看作一個資源,因此要創建create和 index方法,create用來在用戶點擊“搜索”按鈕是通過HTTP POST把關鍵字傳給server,然后index則用來顯示搜索結果。這樣一來,我們還可以記錄用戶的搜索歷史。使用同樣的方法,我們也可以對 login應用REST,即每次login動作是一個資源。

          現在,我們來復雜一些的東東。如何用url表達“category為ruby的article”?一開始可能想到的是 /category/ruby/articles,這種想法很直觀。但是我覺得里面的category是不需要的,我們可以直接把“/ruby”理解為 “category是ruby”,也就是說“ruby”出現的位置說明了它指的就是category。OK,/ruby/articles,單單從這個 url上看,我們能獲得多少關于category的信息呢?顯然category隱藏在了url后面,這樣做到底好不好,應該是仁者見仁,智者見智了。對于如何表達category這樣的東西,我還沒想出很好的方式,大家有什么好idea,可以一起討論。

          另外還有一種url形式,它對應到程序中的繼承關系。比如product是一個父類,book和computer是其子類。那么所有產品的url應該是 /products,所有書籍的url應該是/books,所有電腦的url應該是/computers。這一想法就比較直觀了,而且再次驗證了url可以幫助我們進行設計的論點。

          讓我再說明一下我的想法:如果每個用戶需求都可以抽象為資源,那么就可以完全使用REST。
          (我的觀點:每個用戶需求都可以抽象為資源嗎?是不是有點困難了,MVC和REST混合模式有什么不好,Rails做的挺好。)
          由此看來,使用REST的關鍵是如何抽象資源,抽象得越精確,對REST的應用就越好。因此,如何改變我們目前根深蒂固的基于action的思想是最重要的。
          (也許是該換一種思維模式,但是哪有那么簡單)
          有了對第一個問題的討論,第二個問題就容易討論多了。REST會取代MVC嗎?還是彼此是互補關系(就像AOP對于OOP)?答案是It depends!如果我們可以把所有的用戶需求都可以抽象為資源,那么MVC就可以推出歷史的舞臺了。如果情況相反,那么我們就需要混合使用REST和 MVC。
          (也許在小的項目中,需求簡單的項目中可以完全用REST替代,但是需求變更以后呢,我們當初抽象的資源就不能用了吧,應付變更的情況會不會很復雜?)
          當然,這是非常理想的論斷。可能我們無法找到一種方法可以把所有的用戶需求都抽象為資源,因為保證這種抽象的完整性(即真的是所有需求都可以)需要形式化的證明。而且即使被證明出來了,由于開發人員的能力和喜好不同,MVC肯定也會成為不少人的首選。但是對于希望擁抱REST的人來說,這些都沒有關系。只要你開發的系統所設計的問題域可以被合理地抽象為資源,那么REST就會成為你的開發利器。

          所以,所有希望擁抱REST的朋友們,趕快訓練自己如何帶上資源的眼鏡看世界吧,這才是REST的核心所在

          posted @ 2009-11-10 12:31 小馬歌 閱讀(252) | 評論 (0)編輯 收藏
           
          < 期刊
          跳轉到: 導航 , 搜索跳轉到: 導航 , 搜索

          目錄目錄

          [隱藏]

          [ 編輯 ] Single Page Application [ 編輯 ] Single Page Application

          [ 編輯 ] 所依賴的Web技術 [ 編輯 ] 所依賴的Web技術

          AjaxAsynchorous Javascript And XML ,早期Ajax被用作來傳輸單純的HTML或是XML,並且利用DOM的innerHTML屬性來更新部分HTML內容。 AjaxAsynchorous Javascript And XML ,早期Ajax被用作來傳輸單純的HTML或是XML,并且利用DOM的innerHTML屬性來更新部分HTML內容。 如今Ajax在SPA中被當作重要的傳輸媒介(Transport),無論範本資料到應用程式資料,都是利用Ajax在背景傳輸完後,再由Javascript Template來產生HTML。如今Ajax在SPA中被當作重要的傳輸媒介(Transport),無論范本資料到應用程式資料,都是利用Ajax在背景傳輸完后,再由Javascript Template來產生HTML。

          JSONJavascript Simple Object Notation ,在標準的Javascript語法中,以{ }及[ ]這兩個語法,可以宣告物件與陣列,並可以使用eval函式將他轉換為Javascript物件。 JSONJavascript Simple Object Notation ,在標準的Javascript語法中,以{ }及[ ]這兩個語法,可以宣告物件與陣列,并可以使用eval函式將他轉換為Javascript物件。 例如object=eval("({a:'b'})"),此時object物件便有一個屬性"a"其值為"b"。例如object=eval("({a:'b'})"),此時object物件便有一個屬性"a"其值為"b"。 在SPA中,JSON被運用來作為一種資料格式,藉此取代複雜的XML,以節省頻寬。在SPA中,JSON被運用來作為一種資料格式,借此取代復雜的XML,以節省頻寬。 而傳輸的JSON資料又可以快速還原為javascrip物件,又更節省程式執行的時間。而傳輸的JSON資料又可以快速還原為javascrip物件,又更節省程式執行的時間。

          在SPA中, HTML DOM是一個最重要的元素,尤其是DIV及SPAN等Container的操作更是。在SPA中, HTML DOM是一個最重要的元素,尤其是DIV及SPAN等Container的操作更是。 由於絕大多數的畫面都不進行任何換頁的動作,程式裡大部分都是在控制DOM及Container。由于絕大多數的畫面都不進行任何換頁的動作,程式里大部分都是在控制DOM及Container。 而對於A (Anchor)而言,href裡的URL也沒有太大意義,多半都是在onclick裡寫javascript,或是用Javascript函式庫去bind onclick事件。而對于A (Anchor)而言,href里的URL也沒有太大意義,多半都是在onclick里寫javascript,或是用Javascript函式庫去bind onclick事件。 由於直接呼叫瀏覽器提供的DOM函式庫功能,會遇到像IE一樣不符合W3C規格的問題。由于直接呼叫瀏覽器提供的DOM函式庫功能,會遇到像IE一樣不符合W3C規格的問題。 要選用一個合適的Javascript擴充函式庫,如Prototype.js或是jQuery,如此才不會有太多跨瀏覽器問題。要選用一個合適的Javascript擴充函式庫,如Prototype.js或是jQuery,如此才不會有太多跨瀏覽器問題。

          CSS在以往的Web應用程式中,多半都拿來當作畫面的修飾,布景主題或是顏色特校。 CSS在以往的Web應用程式中,多半都拿來當作畫面的修飾,布景主題或是顏色特校。 但在SPA中,必須要熟悉CSS的Dimentation (長寬控制), Classification (顯示行為), Positioning (定位)。但在SPA中,必須要熟悉CSS的Dimentation (長寬控制), Classification (顯示行為), Positioning (定位)。 在無法換頁的狀況下, 只能靠著移動,隱藏,顯示這些方法來控制畫面的元素。在無法換頁的狀況下,只能靠著移動,隱藏,顯示這些方法來控制畫面的元素。 如果要瞭解這些進階CSS的主題,都可以在w3school裡的教學找到。如果要了解這些進階CSS的主題,都可以在w3school里的教學找到。

          Trimpath是Google為了SPA而開發出來的一個函式庫集合,也可以說是Rails的Javascript版。 Trimpath是Google為了SPA而開發出來的一個函式庫集合,也可以說是Rails的Javascript版。 如果要撰寫下面所說第一種SPA,就必須利用到Trimpath的全部,而第二種只需要用到Trimpath Javascript Template即可。如果要撰寫下面所說第一種SPA,就必須利用到Trimpath的全部,而第二種只需要用到Trimpath Javascript Template即可。 Javascript Template(JST)如同PHP的Smarty一樣,是標準的範本技術,只是採用的語言是Javascript。 Javascript Template(JST)如同PHP的Smarty一樣,是標準的范本技術,只是采用的語言是Javascript。 為了撰寫SPA,必須要好好地運用JST。為了撰寫SPA,必須要好好地運用JST。

          快取的機制在SPA也相當的重要,為了達到讓使用者感受到程式的反應快速,就必須應用多方面的快取。快取的機制在SPA也相當的重要,為了達到讓使用者感受到程式的反應快速,就必須應用多方面的快取。

          • View Cache:SPA中的View就是指已經顯示出來的HTML,很多常用,而不需要經常改變的HTML,就可以將放在Container(DIV或SPAN)裡。 View Cache:SPA中的View就是指已經顯示出來的HTML,很多常用,而不需要經常改變的HTML,就可以將放在Container(DIV或SPAN)里。 不用的時候就隱藏,需要的時候就顯示。不用的時候就隱藏,需要的時候就顯示。 而另一種方式是可以用z-index將選單或是清單的Container放在最下層,而要回到這個清單的時候就將蓋在其上的container隱藏。而另一種方式是可以用z-index將選單或是清單的Container放在最下層,而要回到這個清單的時候就將蓋在其上的container隱藏。
          • Template Cache:一般來說JST的範本資料只要讀取一次就可以,又因為這些只是字串,可以直接就存在Hash裡。 Template Cache:一般來說JST的范本資料只要讀取一次就可以,又因為這些只是字串,可以直接就存在Hash里。
          • Javascript Cache:在我提出的SPA實做中,有一個特性是將各個JST的「行為」程式碼分開,就如同sap.net將aspx與cs檔分開的作法一樣。 Javascript Cache:在我提出的SPA實做中,有一個特性是將各個JST的「行為」程式碼分開,就如同sap.net將aspx與cs檔分開的作法一樣。 而如果採用這個作法,不需要重複讀取的javascript就必須要快取。而如果采用這個作法,不需要重復讀取的javascript就必須要快取。
          • Data Cache:資料快取是最難的一部份,牽扯到了快取一致性的問題。 Data Cache:資料快取是最難的一部份,牽扯到了快取一致性的問題。 而現在在javascript中並沒有對於XML或JSON的資料快取解決方案,未來如果能夠有這樣的函式庫,就能夠更提升整體的效率。而現在在javascript中并沒有對于XML或JSON的資料快取解決方案,未來如果能夠有這樣的函式庫,就能夠更提升整體的效率。

          以上說明的都是Client Side所必須要使用到的技術,而Server Side的技術多半與Service Design息息相關。以上說明的都是Client Side所必須要使用到的技術,而Server Side的技術多半與Service Design息息相關。

          RESTRepresentational State Transfer ,他比較像是一種設計樣式(Design Pattern),而不是Web技術。 RESTRepresentational State Transfer ,他比較像是一種設計樣式(Design Pattern),而不是Web技術。 在以往Web應用程式的規劃中,URL並不完全具有意義,傳輸的內容型態多半是HTML,而HTTP的各種動作也並未完全利用。在以往Web應用程式的規劃中,URL并不完全具有意義,傳輸的內容型態多半是HTML,而HTTP的各種動作也并未完全利用。 在SPA中,由於需要在不同時間傳輸各種資料,如HTML範本,JS範本,或是XML及JSON資料。在SPA中,由于需要在不同時間傳輸各種資料,如HTML范本,JS范本,或是XML及JSON資料。 此時REST的設計技巧就可以節省下很多重複的命名,而讓程式碼整體更有意義。此時REST的設計技巧就可以節省下很多重復的命名,而讓程式碼整體更有意義。 支援REST設計樣式的Web Framework如Ruby On Rails,讓整體設計較為簡單。支援REST設計樣式的Web Framework如Ruby On Rails,讓整體設計較為簡單。

          [ 編輯 ] SPA的架構 [ 編輯 ] SPA的架構

          SPA就分類而言,算是RIA的一種,只是不採用任何的sandbox而已。 SPA就分類而言,算是RIA的一種,只是不采用任何的sandbox而已。 典型的SPA是不需要任何的後端的Web Service或是Offline Database,只需要一個htm檔或是一個網頁就能夠運作,如微軟的HyperText Application(HTA)就是,但還是缺乏完善的資料儲存能力。典型的SPA是不需要任何的后端的Web Service或是Offline Database,只需要一個htm檔或是一個網頁就能夠運作,如微軟的HyperText Application(HTA)就是,但還是缺乏完善的資料儲存能力。

          spa_01.png

          第一種SPA程式,如同著名的Google Reader離線版,具有一個離線資料庫與一個同步管理程式,在有網路連線的時候,會將資料同步回線上的資料庫。第一種SPA程式,如同著名的Google Reader離線版,具有一個離線資料庫與一個同步管理程式,在有網路連線的時候,會將資料同步回線上的資料庫。 這個最大的優點就是完全利用了Client的CPU資源,使用者雖然看見的是網頁,但卻是在使用在本機執行的獨立應用程式,因此速度是相當流暢。這個最大的優點就是完全利用了Client的CPU資源,使用者雖然看見的是網頁,但卻是在使用在本機執行的獨立應用程式,因此速度是相當流暢。 比起一般的動態網頁,這樣子的使用體驗更能夠顛覆一般人對於「網頁」的看法,而逐漸瞭解何謂Web應用程式。比起一般的動態網頁,這樣子的使用體驗更能夠顛覆一般人對于「網頁」的看法,而逐漸了解何謂Web應用程式。 另一個例子是使用Trimpath函式庫撰寫成的NextAction,是一個多功能的ToDo List。另一個例子是使用Trimpath函式庫撰寫成的NextAction,是一個多功能的ToDo List。

          spa_02.png

          另一種就是較簡單的SPA,不具有離線瀏覽的能力,但是承襲了使用javascript的高效能。另一種就是較簡單的SPA,不具有離線瀏覽的能力,但是承襲了使用javascript的高效能。 必須提及的是Server Side並不是採用XML,而是可以快速轉換為Javascript物件的JSON,來當作Web Service。必須提及的是Server Side并不是采用XML,而是可以快速轉換為Javascript物件的JSON,來當作Web Service。 如此Server Side的語言只需要具備能夠快速將物件serialize成JSON的能力即可。如此Server Side的語言只需要具備能夠快速將物件serialize成JSON的能力即可。

          [ 編輯 ] Rails與SPA [ 編輯 ] Rails與SPA

          這個小節所要說明的是相當技術性的部分,無法說明的太詳細,有興趣的讀者可以寫mail一起討論。這個小節所要說明的是相當技術性的部分,無法說明的太詳細,有興趣的讀者可以寫mail一起討論。 為了簡化觀念,我使用Sequence Diagram來說明Rails要如何應用在SPA上:為了簡化觀念,我使用Sequence Diagram來說明Rails要如何應用在SPA上:

          • URLRequester是一個javascript函式,主要的工作就是以REST方式對一個URL進行不同Content-Type的Request,並且將回傳的資料產生HTML,並填到container裡顯示出來。 URLRequester是一個javascript函式,主要的工作就是以REST方式對一個URL進行不同Content-Type的Request,并且將回傳的資料產生HTML,并填到container里顯示出來。
          • HTTPRequest在這裡作為進行Ajax呼叫的傳輸媒介。 HTTPRequest在這里作為進行Ajax呼叫的傳輸媒介。
          • RailsController表示伺服器端對應至特定URL的程式,在這裡也必須使用REST方式來回應。 RailsController表示伺服器端對應至特定URL的程式,在這里也必須使用REST方式來回應。 也因此如果要求content-type為HTML的時候就傳JST範本,要求JSON的時候就傳資料,要求javascript的時候就傳javascript文件。也因此如果要求content-type為HTML的時候就傳JST范本,要求JSON的時候就傳資料,要求javascript的時候就傳javascript文件。
          • RailsModel代表伺服器端的資料庫,在要求資料的時候,勢必定要連資料庫來取得資料的。 RailsModel代表伺服器端的資料庫,在要求資料的時候,勢必定要連資料庫來取得資料的。 而回傳的時候,就將ruby物件serialize成JSON。而回傳的時候,就將ruby物件serialize成JSON。

          spa_03.png

          1. Client呼叫URLRequester函式,例如http://servername/controller/action/id。 Client呼叫URLRequester函式,例如http://servername/controller/action/id。
          2. HTTPRequest送出一個要求,並指定Content-Type為HTML。 HTTPRequest送出一個要求,并指定Content-Type為HTML。
          3. RailsController接到指定的URL,並執行controller#action。 RailsController接到指定的URL,并執行controller#action。 我將JST寫在rhtml裡面,JST基本上也是html,不過是範本的標籤換成{}而已。我將JST寫在rhtml里面,JST基本上也是html,不過是范本的標簽換成{}而已。 因為REST設計方式會因為指定的content-type回傳對應的型態,此時直接將內容的JST文件傳回。因為REST設計方式會因為指定的content-type回傳對應的型態,此時直接將內容的JST文件傳回。
          4. 在前面我有提及快取的重要性,所以這裡就快取住這個JST,下次要求同樣的內容就可以直接使用而不用重複傳輸。在前面我有提及快取的重要性,所以這里就快取住這個JST,下次要求同樣的內容就可以直接使用而不用重復傳輸。
          5. 對於同一個URL,使用HTTPRequest送出要求,並指定Content-Type為JSON。對于同一個URL,使用HTTPRequest送出要求,并指定Content-Type為JSON。
          6. 因為REST的特性,這次會執行到content-type為JSON時的程式碼,接著就可以照一般方式使用Rails Model讀取資料庫。因為REST的特性,這次會執行到content-type為JSON時的程式碼,接著就可以照一般方式使用Rails Model讀取資料庫。
          7. Model傳回的Ruby物件,當然就要轉換成JSON回傳。 Model傳回的Ruby物件,當然就要轉換成JSON回傳。 而在ruby中相當簡單地便是呼叫to_json就可以轉換了。而在ruby中相當簡單地便是呼叫to_json就可以轉換了。
          8. 回傳的JSON,併和剛剛快取的JST,使用trimpath javascript template函式庫產生成HTML,並更新至container裡。回傳的JSON,并和剛剛快取的JST,使用trimpath javascript template函式庫產生成HTML,并更新至container里。
          9. 在這裡我採用行為javascript程式碼與範本分離的方式,所以還是以HTTPRequest再次傳送要求,並將Content-Type指定為Javascript。在這里我采用行為javascript程式碼與范本分離的方式,所以還是以HTTPRequest再次傳送要求,并將Content-Type指定為Javascript。
          10. 同樣地根據要求的content-type,會回傳javascript文件。同樣地根據要求的content-type,會回傳javascript文件。
          11. 快取,並呼叫eval執行回傳的javascript。快取,并呼叫eval執行回傳的javascript。
          12. 將container顯示在想要放置的畫面區域。將container顯示在想要放置的畫面區域。

          [ 編輯 ] 結論 [ 編輯 ] 結論

          許多人都在說Web 2.0可能又是另一次的泡沫化,這個熱潮怎樣開始的,又怎樣消退的,也是相當明顯。許多人都在說Web 2.0可能又是另一次的泡沫化,這個熱潮怎樣開始的,又怎樣消退的,也是相當明顯。 網路上對於各種新技術名詞的炒作,將不同應用層次的技術,全部攪和在一起說明或稱做是最終解決方案,也模糊了使用者的眼睛。網路上對于各種新技術名詞的炒作,將不同應用層次的技術,全部攪和在一起說明或稱做是最終解決方案,也模糊了使用者的眼睛。 那麼,在這個時代,到底還有什麼可以相信,可以學習的?那么,在這個時代,到底還有什么可以相信,可以學習的?

          唯一能夠做的就是重新審視這些技術,瞭解因果。唯一能夠做的就是重新審視這些技術,了解因果。 就可以知道哪些作法是適合用在自己現在的專案,那些是本質相同的,哪些是跨大其詞的。就可以知道哪些作法是適合用在自己現在的專案,那些是本質相同的,哪些是跨大其詞的。 根本的觀念正確,就不需要擔心這些延伸的技術是否會有誤解或誤用。根本的觀念正確,就不需要擔心這些延伸的技術是否會有誤解或誤用。

          posted @ 2009-11-10 12:09 小馬歌 閱讀(1250) | 評論 (0)編輯 收藏
           
          在Web Service, Ajax, Web 2.0, REST等Web應用與技術話題熱潮,帶動許多第二代的Web開發技術成長之后,這些話題也漸漸地消退。 不過許多人可能不曾發現,其實這些技術名詞,是在慢慢地顯露一點:Web應用程式逐漸從Server Side轉移到Client Side,也就是瀏覽器身上。不過許多人可能不曾發現,其實這些技術名詞,是在慢慢地顯露一點:Web應用程式逐漸從Server Side轉移到Client Side,也就是瀏覽器身上。

          本篇文章要從以往的Server Side Web應用程式,其開發方式與演進來介紹Single Page Application(SPA) 與現今所有Web技術。本篇文章要從以往的Server Side Web應用程式,其開發方式與演進來介紹Single Page Application(SPA)與現今所有Web技術。

          我在Web 2.0過去,現在與未來介紹Ruby On Rails都有提到一些Web技術的演進,比較明顯的趨勢就是從靜態到動態頁面,而設計的方式也更程式化。我在Web 2.0過去,現在與未來介紹Ruby On Rails都有提到一些Web技術的演進,比較明顯的趨勢就是從靜態到動態頁面,而設計的方式也更程式化。 而在Web2.0:過去,現在及未來«就是愛程式也有讀者在前言提到,技術並不是將一個名詞安上去就好。而在Web2.0:過去,現在及未來«就是愛程式也有讀者在前言提到,技術并不是將一個名詞安上去就好。 我相當贊同這句話,因此也在這篇文章中希望來做個總整理,以技術及歷史來看看Web是怎樣成長的。我相當贊同這句話,因此也在這篇文章中希望來做個總整理,以技術及歷史來看看Web是怎樣成長的。

          本篇文章也同步發佈於http://kiwi.csie.chu.edu.tw/blog/archives/156本篇文章也同步發布于http://kiwi.csie.chu.edu.tw/blog/archives/156

          目錄目錄

          [隱藏]

          [ 編輯 ] Web應用程式的演進 [ 編輯 ] Web應用程式的演進

          [ 編輯 ] 動態網頁 [ 編輯 ] 動態網頁

          儘管Web並不是一個三言兩語能拿個版本號碼來解釋,但實際上Web技術確實有些明顯的分隔點。盡管Web并不是一個三言兩語能拿個版本號碼來解釋,但實際上Web技術確實有些明顯的分隔點。

          最早期我們熟知的就是靜態網頁,這應該沒啥問題。最早期我們熟知的就是靜態網頁,這應該沒啥問題。 儘管在2000前,php,asp就開始流行,坊間的書上也都稱之為動態網頁。盡管在2000前,php,asp就開始流行,坊間的書上也都稱之為動態網頁。 而我在此提及的動態網頁程式 ,實際上卻是從php4釋出的那一年開始。而我在此提及的動態網頁程式 ,實際上卻是從php4釋出的那一年開始。 這邊要讓大家瞭解的分界點,其實是php4開始被許多商業公司所採用,而軟體的形式也更為套裝化,而不再像之前大家認定的「動態」網頁僅僅只是拿來完成一些簡單的區塊來與一般的靜態網頁整合。這邊要讓大家了解的分界點,其實是php4開始被許多商業公司所采用,而軟體的形式也更為套裝化,而不再像之前大家認定的「動態」網頁僅僅只是拿來完成一些簡單的區塊來與一般的靜態網頁整合。

          在2004年的時候,Web Framework的產生,創造了Web應用程式另一個新的高峰。在2004年的時候,Web Framework的產生,創造了Web應用程式另一個新的高峰。 而在這個時候也開始有一些Rich Web Client概念的雛形了。而在這個時候也開始有一些Rich Web Client概念的雛形了。 我將Ruby On Rails定為一個分界點是因為,他顛覆了傳統動態網頁還在使用設計方式,而改用MVC。我將Ruby On Rails定為一個分界點是因為,他顛覆了傳統動態網頁還在使用設計方式,而改用MVC。 但要注意的是Ruby On Rails儘管整合了Ajax與進階Javascript函式庫,但還是沒有改變回傳完整或部分HTML的方式,意思便是HTML的產生始終在Server Side。但要注意的是Ruby On Rails盡管整合了Ajax與進階Javascript函式庫,但還是沒有改變回傳完整或部分HTML的方式,意思便是HTML的產生始終在Server Side。

          [ 編輯 ] Rich Internet Application [ 編輯 ] Rich Internet Application

          一直到現在,有相當多的Web應用程式,都還是維持使用URL來切換各種功能與畫面。一直到現在,有相當多的Web應用程式,都還是維持使用URL來切換各種功能與畫面。 而這些以「頁面」為主的程式,並不太需要控制DOM,就不常遇到跨瀏覽器問題。而這些以「頁面」為主的程式,并不太需要控制DOM,就不常遇到跨瀏覽器問題。 然而自從Firefox逐漸也在市場佔有一席之地,Javascript的應用普及之後,跨瀏覽器問題也接著發生。然而自從Firefox逐漸也在市場占有一席之地,Javascript的應用普及之后,跨瀏覽器問題也接著發生。 為了避開各種不同的瀏覽器所帶來的問題,各大企業都獨力發展自己可以嵌入在瀏覽器的應用程式。為了避開各種不同的瀏覽器所帶來的問題,各大企業都獨力發展自己可以嵌入在瀏覽器的應用程式。 早期如Java Applet及微軟的的Active X,算是Rich Internet Application(RIA)的開始,但效能方面還是差強人意。早期如Java Applet及微軟的的Active X,算是Rich Internet Application(RIA)的開始,但效能方面還是差強人意。

          直到2004年的時候,RIA出現了兩種不同的實做方法:一種是承襲以往需要安裝額外Runtime或是在特定瀏覽器才能執行的方式,稱做Sandbox;另一種是只採用CSS,HTML,並以Javascript控制HTML DOM的Dynamic HTML方式,優點就是只需要瀏覽器就可以執行。直到2004年的時候,RIA出現了兩種不同的實做方法:一種是承襲以往需要安裝額外Runtime或是在特定瀏覽器才能執行的方式,稱做Sandbox;另一種是只采用CSS,HTML,并以Javascript控制HTML DOM的Dynamic HTML方式,優點就是只需要瀏覽器就可以執行。 而後者也延伸出利用Offline Database或是Ajax+Web Service來傳送與儲存程式資料,並可以儲存成一個獨立頁面的Web應用程式,稱做Single Page Application(SPA)而后者也延伸出利用Offline Database或是Ajax+Web Service來傳送與儲存程式資料,并可以儲存成一個獨立頁面的Web應用程式,稱做Single Page Application(SPA) SPA最典型的例子,就是Gmail。 SPA最典型的例子,就是Gmail。 Google盡力克服了跨瀏覽器的問題,將Javascript發揮的淋漓盡致,讓大家驚嘆光靠純粹的Web技術竟能做到如此程度。 Google盡力克服了跨瀏覽器的問題,將Javascript發揮的淋漓盡致,讓大家驚嘆光靠純粹的Web技術竟能做到如此程度。

          而我將2005定為Sandbox RIA真正開始的年代,也是因為Adobe併購Macromedia,而有了較完整的開發環境與資源,並不是以往單純地嵌入Flash。而我將2005定為Sandbox RIA真正開始的年代,也是因為Adobe并購Macromedia,而有了較完整的開發環境與資源,并不是以往單純地嵌入Flash。 這個契機也促使微軟改變策略,比起效能較差的Asp.Net,而拿Sliverlight作為Web下一代主力軍。這個契機也促使微軟改變策略,比起效能較差的Asp.Net,而拿Sliverlight作為Web下一代主力軍。

          RIA或SPA都是學習歷程長,語言多又複雜的Web應用程式技術,也因此發展速度相當緩慢,但不可小看的是這些優點: RIA或SPA都是學習歷程長,語言多又復雜的Web應用程式技術,也因此發展速度相當緩慢,但不可小看的是這些優點:

          • 相較以往在Server上產生HTML並回傳至瀏覽器,任何畫面皆利用瀏覽器本身或附加的功能來產生。相較以往在Server上產生HTML并回傳至瀏覽器,任何畫面皆利用瀏覽器本身或附加的功能來產生。 形同於借用了Client Side CPU的運算資源,減少Server成本。形同于借用了Client Side CPU的運算資源,減少Server成本。 使用者感受到的互動性與回應速度皆有大幅的提升。使用者感受到的互動性與回應速度皆有大幅的提升。
          • 由於Server並不是回傳複雜龐大的HTML,而是純粹傳輸資料,使用的頻寬也相對變小。由于Server并不是回傳復雜龐大的HTML,而是純粹傳輸資料,使用的頻寬也相對變小。
          • Server Side除了使用傳統XML Web Service,更可以採用REST,讓Client的應用程式可以更快速掌握資料的新增修改刪除(CRUD)。 Server Side除了使用傳統XML Web Service,更可以采用REST,讓Client的應用程式可以更快速掌握資料的新增修改刪除(CRUD)。
          • 能夠快速Mashup其他的Web應用程式資源,又能擁有高速的執行效能。能夠快速Mashup其他的Web應用程式資源,又能擁有高速的執行效能。

          下表列出了Web技術的演進,要注意到後三種技術集合,其時間是並行的:下表列出了Web技術的演進,要注意到后三種技術集合,其時間是并行的:

          靜態網頁 靜態網頁 動態網頁程式 動態網頁程式 Web應用程式 Web應用程式 Rich Internet Application with Sandbox Rich Internet Application with Sandbox Single Page Application Single Page Application
          時期 時期 2000以前 2000以前 2000(php4釋出)~2004 2000(php4釋出)~2004 2004(Ruby On Rails釋出)以後 2004(Ruby On Rails釋出)以后 2005(macromedia被adobe併購)以後 2005(macromedia被adobe并購)以后 2004(Gmail釋出beta)以後 2004(Gmail釋出beta)以后
          表現層 表現層 CSS CSS CSS,HTML,Javascript CSS,HTML,Javascript CSS,HTML,Javascript CSS,HTML,Javascript Flash, Sliverlight Flash, Sliverlight CSS,HTML(DOM) CSS,HTML(DOM)
          邏輯層 邏輯層 Javascript Javascript Template或自行撰寫 Template或自行撰寫 Web Framework Web Framework Action Script, C# Action Script, C# Javascript或是撰寫Web Service的語言 Javascript或是撰寫Web Service的語言
          資料層 資料層 HTML HTML Database(SQL) Database(SQL) Database(ORM) Database(ORM) Database(ORM) Database(ORM) Offline Database, Web Service Offline Database, Web Service
          開發方式 開發方式 網頁編輯程式網頁編輯程式 整合HTML及Server Side語言的編輯器整合HTML及Server Side語言的編輯器 整合Web Framework的IDE整合Web Framework的IDE 整合Sandbox的IDE整合Sandbox的IDE 整合Server Side與Client Side語言的IDE整合Server Side與Client Side語言的IDE
          運算資源 運算資源 所有資料直接透過Web Server送出,除了硬碟讀取,幾乎不需要額外的運算所有資料直接透過Web Server送出,除了硬碟讀取,幾乎不需要額外的運算 因為使用了Server Side語言來Render表現層,運算多半會消耗在Server因為使用了Server Side語言來Render表現層,運算多半會消耗在Server 因為使用了Server Side語言來Render表現層,運算多半會消耗在Server因為使用了Server Side語言來Render表現層,運算多半會消耗在Server 運算資源平均被分散在Server及Client,但Client需要Sandbox去執行,所以會消耗更多CPU資源運算資源平均被分散在Server及Client,但Client需要Sandbox去執行,所以會消耗更多CPU資源 運算資源平均被分散在Server及Client運算資源平均被分散在Server及Client
          資料格式 資料格式 傳送完整的HTML傳送完整的HTML 傳送完整的HTML傳送完整的HTML 傳送部分或完整的HTML傳送部分或完整的HTML 只需第一次傳送HTML及內嵌程式(Flash或Sliverlight),其餘傳送XML只需第一次傳送HTML及內嵌程式(Flash或Sliverlight),其余傳送XML 只需第一次傳送HTML及Javascript,其餘可傳送XML或JSON只需第一次傳送HTML及Javascript,其余可傳送XML或JSON
          優點 優點 簡單易學簡單易學 學習同一種Server Side語言,搭配簡單的HTML,CSS,JS觀念便能夠有成果學習同一種Server Side語言,搭配簡單的HTML,CSS,JS觀念便能夠有成果 整合Ajax或進階Javascript函式庫,REST及MVC。整合Ajax或進階Javascript函式庫,REST及MVC。 使得設計概念更為物件導向化使得設計概念更為物件導向化 使用者介面反應快速,變化多且美觀。使用者介面反應快速,變化多且美觀。 兼顧視窗程式的反應速度,且能部分相容傳統HTML應用。兼顧視窗程式的反應速度,且能部分相容傳統HTML應用。 完全相容傳統HTML應用,及任何可能的Web應用程式Mashup。完全相容傳統HTML應用,及任何可能的Web應用程式Mashup。 可以採用不同的傳輸方式,併和REST及瀏覽器快取來節省頻寬,使得整體反應相當快速。可以采用不同的傳輸方式,并和REST及瀏覽器快取來節省頻寬,使得整體反應相當快速。
          缺點 缺點 無法讓使用者儲存任何應用程式資料,任何資料必須藉由人工設計無法讓使用者儲存任何應用程式資料,任何資料必須藉由人工設計 對於龐大的應用程式,便得花上大量的Server成本。對于龐大的應用程式,便得花上大量的Server成本。 程式反應速度受限於伺服器負載,需要叢集架構來彌補。程式反應速度受限于伺服器負載,需要叢集架構來彌補。 設計方式更為簡單快速,但相對於傳統的動態網頁程式付出更大的Server成本。設計方式更為簡單快速,但相對于傳統的動態網頁程式付出更大的Server成本。 除了CSS,HTML,JS以外還需學習一兩種不同的語言才能進行開發。除了CSS,HTML,JS以外還需學習一兩種不同的語言才能進行開發。 RIA通常程式資料較大,在開始使用前必須等候一段下載時間。 RIA通常程式資料較大,在開始使用前必須等候一段下載時間。 除了CSS,HTML,JS以外還需學習一種撰寫Web Service的語言。除了CSS,HTML,JS以外還需學習一種撰寫Web Service的語言。 需要相當熟悉DOM及CSS,也需考慮瀏覽器的差異,開發起來相對地困難許多。需要相當熟悉DOM及CSS,也需考慮瀏覽器的差異,開發起來相對地困難許多。

          表現層的演進可以得知,不管是RIA利用sandbox或者是SPA利用DHTML作為表現層,相較起來傳統以文字HTML拼湊出畫面的作法已經無法符合使用者的需求。表現層的演進可以得知,不管是RIA利用sandbox或者是SPA利用DHTML作為表現層,相較起來傳統以文字HTML拼湊出畫面的作法已經無法符合使用者的需求。 更動態,更彈性的作法才能讓使用者獲得操作感。更動態,更彈性的作法才能讓使用者獲得操作感。

          而在邏輯層上,演進到了SPA則是變得較為複雜。而在邏輯層上,演進到了SPA則是變得較為復雜。 如果是使用Web Service作為Server Side,除了必須撰寫該語言外,也還是得撰寫Javascript來控制畫面的呈現。如果是使用Web Service作為Server Side,除了必須撰寫該語言外,也還是得撰寫Javascript來控制畫面的呈現。 而這也影響到開發方式,以往的編輯器多半著重一種主要的語言上,但現在的Web IDE多半都可以完整的處理所有瀏覽器的語言,及多種Server Side語言。而這也影響到開發方式,以往的編輯器多半著重一種主要的語言上,但現在的Web IDE多半都可以完整的處理所有瀏覽器的語言,及多種Server Side語言。 例如Aptana IDE就是最好的例子。例如Aptana IDE就是最好的例子。

          資料層的演進就比較簡單,直到RIA的時期,還是相當依賴傳統的Database。資料層的演進就比較簡單,直到RIA的時期,還是相當依賴傳統的Database。 但SPA的時期,就可以採用Offline Database,這裡指的就是Google Gears但SPA的時期,就可以采用Offline Database,這里指的就是Google Gears 但如果要使用傳統的Online Database,全部都尚未有Javascript的Client,就必須透過Web Service來轉換資料。但如果要使用傳統的Online Database,全部都尚未有Javascript的Client,就必須透過Web Service來轉換資料。 而在SQL到ORM的演進上,雖然使用物件導向的作法減緩執行速度,但相對降低開發難度,帶來更大的價值。而在SQL到ORM的演進上,雖然使用物件導向的作法減緩執行速度,但相對降低開發難度,帶來更大的價值。

          [ 編輯 ] 小結 [ 編輯 ] 小結

          本篇說明了Web技術的歷史,來帶出現今的Web技術。本篇說明了Web技術的歷史,來帶出現今的Web技術。 下一篇要介紹的是Single Page Application與它在Ruby On Rails上的應用。下一篇要介紹的是Single Page Application與它在Ruby On Rails上的應用。

          posted @ 2009-11-10 12:08 小馬歌 閱讀(387) | 評論 (0)編輯 收藏
          僅列出標題
          共95頁: First 上一頁 62 63 64 65 66 67 68 69 70 下一頁 Last 
           
          主站蜘蛛池模板: 岳阳市| 德化县| 石林| 壶关县| 皮山县| 台东市| 建宁县| 红原县| 宁夏| 社旗县| 云梦县| 石泉县| 舞钢市| 新邵县| 从化市| 梧州市| 威信县| 上林县| 淅川县| 安溪县| 太仆寺旗| 沂源县| 崇明县| 健康| 柯坪县| 田东县| 武宁县| 安平县| 泾阳县| 巢湖市| 陆良县| 达拉特旗| 平顶山市| 抚宁县| 泗水县| 长宁县| 千阳县| 区。| 东乡| 霍城县| 建水县|