2016年3月14日 星期一

出國旅行 會這50句英語就夠了

出國旅行英語不好,沒關係,掌握這50句英語常用會話,登機、購物、用餐、坐車、住宿輕鬆搞定!

(本圖擷取自網路)

1.請問1號登機口在哪?

Excuse me, where is boarding gate one?

2.請問航班CZ623(航班號)在哪換登機牌?

Hi, where can I get the boarding pass for flight CZ623?

3.我在何處可取得行李?

Where can I get my baggage/luggage?

4.這些是我私人使用的東西。

These are for personal use.

5.旅遊諮詢中心在那裡?

Where is tourist information?

6.是否可建議一間較為廉價的旅館?

Can you recommend an economical hotel?

7.是否有機場巴士可到市區?

Is there a bus to the city?

8.是否有每晚花費在50美元以下的飯店?

Is there a hotel that costs under 50 dollars a night?

9.巴士站牌(出租車招呼站)在那裡?

Where is the bus stop(taxi stand)?

10.是否可建議一家位於市中心的旅館?

Could you recommend a hotel in center city?

(本圖擷取自網路)

11.我要早上8:00設定電話叫醒。

I would like to have a morning call at8:00 in the morning.

12.我要食物送到房間的服務。

I’d like to order room service, please.

13.我要單人房。

I’d like a single room.

14.我要兩張床的房間。

I’d like a double room.

15.我要在702房多加一張床。

I’d like an extra bed for room702.

16.退房的適合時間?

What is the time for check-out?

17.我想訂房。

I would like to book a room.

18.我要訂一間雙人房從(日期)到(日期)

I’d like to book a double room for3 nights from…(日期)..to(日期).

19.我會晚一點到達,請保留所預訂的房間。

I’m going to be arriving late, but please keep my reservation.

20.早餐幾點開始供應?

When is breakfast served?

(本圖擷取自網路)

21.你好,我們有2位。

Hi, a table for two, please.

22.我們想坐在靠窗的位子。

We prefer to sit by the window.

23.我可以坐這個位子嗎?

Can I take this seat?

24.我可以要冰水嗎?

May I have some ice water?

25.請給我菜單。

May I have a menu?

26.是否有中文菜單?

Do you have a menu in chinese?

27.這裡最受歡迎的餐點是什麼呢?

What is the most popular dish here?

28.不要辣椒。

Not spicy.

29.可以再幫我加點水嗎?

Can I have some more water?

30.買單

Check, please?

(本圖擷取自網路)

31.這裡有從機場去市中心的巴士嗎?

Is there an airport bus to center city?

32.巴士車站在哪裡?

Where is the bus stop?

33.乘計程車到市中心需要多少錢?

How much does it cost to take a taxi to center city?

34.不用找錢了。

Keep the change.

35.請拉我去這個地址。

Take me to this address, please.

36.到市中心需要多長時間?

How long does it take to go to center city?

37.請停在這裡。

Stop here, please.

38.幾點發車?

What time is the departure?

39.在哪裡買票?

Where can I get a ticket?

40.我想到(地名),請問要多少錢?

How much is it to(地名)?

(本圖擷取自網路)

41.我可以試穿這個嗎?

May I try this on?

42.這免稅嗎?

Is this tax free?

43.我可不可以用信用卡付帳?

Can I pay by credit card?

44.太貴了,打個折吧?

It’s too expensive. How about a discount?

45.你能賣便宜一點嗎?

Can you come down a little bit?

46.不能再便宜了嗎?

Is this your final price?

47.我要大一點的。

I’d like one size up.

48.我要買這個。

I’ll take this one.

49.我要在哪裡換錢?

Where can I change money?

50.收銀台在哪裡?

Where is the cashier?

2016年3月10日 星期四

Google 搜尋技巧 by GREEN

Google應該是目前使用者最多的網頁搜索網站了,但您真的會用它來找到需要的資料呢?

或是您找了一堆資料後,又要花時間去過濾不相干的資料?

看看這篇,或許對您有所幫助!

首先我們可以利用 google的進階搜尋來測試語法:

https://www.google.com/advanced_search

含以下所有字詞:輸入關鍵字: 黃金獵犬

與以下字詞或語句完全相符:在指定完全相符的字詞前後加上引號: "黃金獵犬"

含以下任何字詞:在各搜尋字詞之間輸入 OR: 小型 OR 標準

不含以下任何字詞:在想要排除的字詞前面加上減號: -黃金, -"拉布拉多" (注意,- 號前面要有空格!)

例如:

天龍八部 -林志穎

表示想找網頁中含有 天龍八部 但不含  林志穎 的網頁

也可以輸入多個字詞排除:

例如:

天龍八部 -林志穎 -特权

2016年3月8日 星期二

jQuery 教學 - 基礎篇

jQuery 教學 - 基礎篇

jQuery, 原創教學

[前言]


jQuery 是一套 JavaScript 的 Library,因此,你必須稍具 JavaScript 的基礎,至少寫過一些 JavaScript 才比較容易上手,並且看得懂後續的教學。jQuery 的核心程式並非包山包海、什麼都可以幫你做,相反地,jQuery 主要是用在 DOM 文件的操作,包含「快速選取元素(Element)」並且「做一些事情」,快速選取元素可以讓你一次選取單一或多個的元素,然後你可以將這些被選取的元素做一些改變,例如隱藏、顯示等等。此外 jQuery 的核心程式還加強了非同步傳輸(AJAX)以及事件(Event)的功能,讓你更容易操作遠端文件及事件。
以上看得出來 jQuery 是針對 JavaScript 內在不足的地方加以增進,你仍然需要自己寫一些程式來完成你需要的各種功能,不同的是,正確地使用了 jQuery 可以讓你的程式碼更精簡、更優雅的表達出來,這在後續的範例中可以看到,更重要的是,應該也會讓你更快速的開發出你要的功能。
或許你會想說,在這個 Web 2.0 的時代,我需要多點漂亮、絢麗的 Widgets 來裝飾我的網站,就像 Yahoo UI 或 ExtJS 提供的那些功能一樣,jQuery 有嗎?其實 jQuery 的設計上有考慮到這類擴展性的問題,目前 jQuery 的 plugin 已經有上百個了,你也不一定要完全自己動手寫,上 jQuery 官方網站找找看,或許你需要的功能別人已經幫你做好了。以 UI 來講, jQuery 跟 UI 相關的 plugins 已經做過了一些整合,目前獨立發佈為 jQuery UI (http://ui.jquery.com/),如果你之前沒聽過 jQuery UI,建議你上去網站上看一下展示的範例,嗯,雖然可能還有一些 bug 存在,但是整體來說已經有相當的水準了,或許你會對 jQuery 更有興趣了。
以下的教學內容,主要是擷取了 jQuery 作者 John Resig 的一篇簡報 "Building Interactive
Prototypes with jQuery" 的內容加以調整並註解,希望能以比較忠實的方式來呈現 jQuery 的設計含意。

[初探]


jQuery 怎麼用來「快速選取元素」並且「做一些事情」呢?請看看程式碼:
  1. $("div").addClass("special"); 

錢記號 $ 是 jQuery 的物件,使用 $("div") 就是用 jQuery 來選取元素,這個範例可以選取文件內所有的 <div> 元素。後面接著的 .addClass("special")就是用來做一些事情,這個範例是將先前所選取到的所有元素都加上一個名為 "special" 的 class。也就是透過 $("div").addClass("special") 的語法,可以讓你一次幫文件上有的 <div> 元素都加入 special 的 class。
請注意喔,剛剛的例子可以針對已選取的多個元素做批次的操作,也就是說如果文件上有三個 <div>,那就會一次找出三個 <div> 並且全部套用後續的動作。這和你原本自己使用 JavaScript 來寫程式有很大的差異,原本自己寫可能會需要用到迴圈之類的語法,而 jQuery 的函數大多具有批次處理的功能,光是這點就可以讓你的程式更簡潔了。
關於錢記號 $ 將會是你學習及使用 jQuery 的過程中最重要的物件(或者你要把 $ 當成一個函數也可以,事實上也是這樣),使用方式就像剛剛你看到的,用來找元素用的,把參數帶入即可。或許你不習慣錢記號也可以當成函數名稱,那麼你也可以用 jQuery 這個名字,錢記號其實是被當成 jQuery 的縮寫,讓你的函數看起來更簡潔一些,如果你要自己設定另外一個縮寫,例如 $j,也是可以的,這部份後續再解釋,先看看已下的範例,結果將會和上面的範例是一模一樣的:

  1. jQuery("div").addClass("special"); 

[選取元素]


前面的例子使用 $("div") 來選取元素,帶入的參數 div 是表示你要找的元素,這是 CSS 選擇器(CSS Selector) 的語法,就如同 CSS 在做排版和外觀所使用的選擇器語法一樣。jQuery 所支援的 CSS Selector 包含了 CSS 1、CSS2 以及仍未正式發佈的 CSS3,此外透過 plugin 還可支援常用的 XPath 語法,善用這些 CSS、XPath 語法就可以很容易地找到你要處理的網頁元素,底下來看看更多的範例。
這是一段原始的 HTML:
  1. <div id="body">
  2. <h2>Some Header</h2>
  3. <div class="contents">
  4. <p>...</p>
  5. <p>...</p>
  6. </div>
  7. </div>

以下用一連串的範例,以藍色字體展示一些基本的語法並且以深色字顯示文件中會被選取的元素。
$("div")
<div id="body">
  <h2>Some Header</h2>
  <div class="contents">
    <p>...</p>
    <p>...</p>
  </div>
</div>
解釋:選取所有 <div>
$("#body")
<div id="body">
  <h2>Some Header</h2>
  <div class="contents">
    <p>...</p>
    <p>...</p>
  </div>
</div>
解釋:選取 id 為 body 的元素
$("div#body")
<div id="body">
  <h2>Some Header</h2>
  <div class="contents">
    <p>...</p>
    <p>...</p>
  </div>
</div>
解釋:選取 id 為 body 的 <div>
$("div.contents p")
<div id="body">
  <h2>Some Header</h2>
  <div class="contents">
    <p>...</p>
    <p>...</p>
  </div>
</div>
解釋:選取 class 為 contents 的 <div> 所包住的所有下層的 <p>
$("div > div")
<div id="body">
  <h2>Some Header</h2>
  <div class="contents">
    <p>...</p>
    <p>...</p>
  </div>
</div>
解釋:選取被 <div> 包住的下一層 <div>
$("div:has(div)")
<div id="body">
  <h2>Some Header</h2>
  <div class="contents">
    <p>...</p>
    <p>...</p>
  </div>
</div>
解釋:和前一個範例相反,這邊是選取至少有包住一個 <div> 的 <div>

[做一些事情]


前一段的教學中介紹了如何使用 jQuery 來選取元素,其中大部份的語法都是可以讓你快速地一次選取多個元素,接下來當然就是要來對這些選取到的元素做些改變囉。透過 jQuery 內建的函數,你可以:
  • 對 DOM 進行操作,例如對文件節點的新增或修改
  • 添加事件處理
  • 做一些基本的視覺效果,例如隱藏、顯示、下拉顯示、淡出淡入等等
  • 使用 AJAX 傳送表單內容或取得遠端文件

[範例1] 選取所有有 target 屬性的 <a>,並且在其節點下加入一段文字。
  1. $("a[target]").append(" (Opens in New Window)"); 

這是一段原始的 HTML :

  1. <a href="http://jsgears.com">jsGears</a>
  2. <a href="http://google.com" target="_blank">Google</a>
  3. <a href="http://amazon.com" target="_blank">Amazon</a>

選取有 target 屬性並加入文字後的結果:

  1. <a href="http://jsgears.com">jsGears</a>
  2. <a href="http://google.com" target="_blank">Google (Opens in New Window)</a>
  3. <a href="http://amazon.com" target="_blank">Amazon (Opens in New Window)</a>

[範例2] 選取 id 為 body 的元素,並且修改兩個 css 屬性。

  1. $("#body").css({  
  2.   border: "1px solid green",  
  3.   height: "40px"
  4. }); 

這是一段原始的 HTML :

  1. <div id="body">
  2.   ...  
  3. </div>

選取 id 為 body 的元素並修改 css 後的結果(示意):

  1. <div id="body" style="border: 1px solid green; height: 40px">
  2.   ...  
  3. </div>

[範例3] 在網頁上的表單送出時加入一個判斷,如果 username 這個欄位是空值的話,就顯示 help 這個區塊內的文字。

  1. $("form").submit(function() {  
  2. if ($("input#username").val() == "")  
  3.     $("span.help").show();  
  4. }); 

可作用在類似以下的 HTML,一開始 span.help 是隱藏的,如果沒有輸入 username,才會顯示:

  1. <style type="text/css">
  2.   .help {display: none}  
  3. </style>
  4. <form>
  5. <label for="username">請輸入大名</label>
  6. <input type="text" id="username" name="username" />
  7. <span class="help">這個欄位必填喔</span>
  8. </form>

[範例4] 當 user 點選 id 為 open 的連結時,顯示 id 為 menu 的區塊,並回傳 false 避免瀏覽器真的換頁。

  1. $("a#open").click(function() {  
  2.   $("#menu").show();  
  3. return false;  
  4. }); 

可作用在類似以下的 HTML:

  1. <style type="text/css">
  2.   #menu {display: none}  
  3. </style>
  4. <a id="open" href="#">控制面板</a>
  5. <ul id="menu">
  6. <li><a href="#1">控制面板首頁</a></li>
  7. <li><a href="#2">編輯個人資料</a></li>
  8. <li><a href="#3">個人空間管理</a></li>
  9. </ul>

[範例5] 將 id 為 menu 的區塊以下拉布幕的動態效果快速顯示:

  1. $("#menu").slideDown("fast"); 

可作用在類似以下的 HTML,原本隱藏的選單會以動態下拉的方式顯示出來:

  1. <style type="text/css">
  2.   #menu {display: none}  
  3. </style>
  4. <ul id="menu">
  5. <li><a href="#1">控制面板首頁</a></li>
  6. <li><a href="#2">編輯個人資料</a></li>
  7. <li><a href="#3">個人空間管理</a></li>
  8. </ul>

[範例6] 將所有的 <div> 漸變為寬 300px、文字與邊界寬 20px

  1. $("div").animate({  
  2.     width: '300px',  
  3.     padding: '20px'
  4.   }, 'slow'); 

可作用在類似以下的 HTML:

  1. <div style="width: 100px; border: solid 1px red;">
  2.   Hello world!  
  3. </div>

PS. jQuery 核心程式的 animate 函數能改變的元素屬性並不多,但是可以透過其他 plugin 提供更多的動態效果。
[範例7] 動態效果的 callback 的範例,將所有的 <div> 以 0.5 秒的動態效果隱藏後,再以 0.5 秒的動態效果顯示。hide() 的第二個參數就是一個 callback 函數,其中 $(this) 是原本程式所處理的各個元素。

  1. $("div").hide(500, function(){  
  2. // $(this) 是每一個各別的 <div>
  3.   $(this).show(500);  
  4. }); 

可作用在類似以下的 HTML:

  1. <div style="width: 100px; border: solid 1px red;">
  2.   Hello world!  
  3. </div>
  4. <div style="width: 100px; border: solid 1px red;">
  5.   jsGears.com!  
  6. </div>

[範例8] 取得 sample.html 並將找出文件內所有 <div> 下一層的 <h1> 填入原本文件 id 為 body 的元素內

  1. $("#body").load("sample.html div > h1"); 

這是一段原始的 HTML :

  1. <div id="body"></div>

sample.html 的片段:

  1. <div>
  2. <h1>Hello world!</h1>
  3. <h2>This is H2</h2>
  4. <h1>jsGears.com!</h1>
  5. </div>

執行程式碼之後的結果:

  1. <div id="body">
  2. <h1>Hello world!</h1>
  3. <h1>jsGears.com!</h1>
  4. </div>

[範例9] 透過 getJSON() 取得 JSON 格式的資料,並透過 callback 函數處理資料

  1. $.getJSON("test.json", function(data){  
  2. for (var idx in data)  
  3.     $("#menu").append("<li>" + data[idx] + "</li>");  
  4. }); 

這是一段原始的 HTML:

  1. <ul id="menu">
  2. <li>項目1</li>
  3. </ul>

test.json 的內容:

  1. [  
  2. "Hello world!",   
  3. "jsGears.com!"
  4. ] 

執行程式碼之後的結果:

  1. <ul id="menu">
  2. <li>項目1</li>
  3. <li>Hello world!</li>
  4. <li>jsGears.com!</li>
  5. </ul>

[連續使用函數]


jQuery 很重要的一個特性是可以連續地使用函數(Chaining),當你選取了一個或一組的元素後,可以連續對這些元素進行多個處理。以下範例會將所有的 <div> 隱藏,修改文字顏色為藍色,再將 <div> 以下拉布幕的效果顯示出來:
  1. $("div").hide();  
  2. $("div").css("color", "blue");  
  3. $("div").slideDown(); 

這樣的三行程式碼可以用以下一行的程式碼取代,結果會是完全相同的:

  1. $("div").hide().css("color", "blue").slideDown(); 

是否感到很神奇呢?在 jQuery 的架構設計上,大部分的函數都會在處理完該做的事情後,再將原本傳入的元素給回傳回去,因此函數都可以連續這樣一個接著一個的使用。還記得一開始所說的 jQuery 可以讓你的程式碼更精簡嗎?看了上面的一些範例後,現在應該有點感覺了吧。
講到 jQuery 的函數連續使用,有兩個很重要的函數必須在此介紹一下。第一個是 end(),這個函數執行後,會回傳「前一組找到的元素」。另一個是 find(),這個函數的用法如同使用 $() 找文件內的元素一樣是帶入 CSS 選擇器,執行後回傳找到的元素,不同的是 $() 是找整個文件,而 find() 是根據先前找到的元素再找其底下的元素,像是一個再過濾的功能。

  1. $("ul.open")                // [ ul, ul, ul ]
  2.   .children("li")           // [ li, li, li ]
  3.   .addClass("open")         // [ li, li, li]
  4.   .end()                    // [ ul, ul, ul ]
  5.   .find("a")                // [ a, a, a ]
  6.   .click(function(){  
  7.     $(this).next().toggle();  
  8. return false;  
  9.   })                        // [ a, a, a ]
  10.   .end();                   // [ ul, ul, ul ]

上面這一段程式碼連續使用多個函數,且透過 end() 和 find() 來分別對不同的元素進行操作,詳細的步驟解釋如下:

  • 找出文件內所有 class 為 open 的 <ul>
  • 過濾出下一層的所有 <li>
  • 對這些 <li> 新增一個 class
  • 回前一次搜尋的結果,也就是所有的 <ul>
  • 再找出底下所有的 <a>
  • 對 <a> 新增事件處理
  • 回前一次搜尋的結果

[待續]


jQuery 基礎篇的教學到此囉,希望對初學者能有所幫助,如果任何誤謬之處,也希望大家不吝指正。後續應該會再規劃一些 jQuery 實用的 plugin 介紹,作為基礎篇的延續,敬請期待。

收藏分享

7

To infinity and beyond!

wmh

管理員

Rank: 9Rank: 9Rank: 9

帖子
760
主題
210
精華
2
積分
232
威望
232 
金錢
0 

2#

發表於 2008-3-13 01:18 | 只看該作者

補充兩點

[document ready 事件]


有些時候,我們必須在網頁下載完成之後立即執行一些程式,可能是想要把游標放在預設的輸入框,或是馬上顯示一些歡迎訊息等等。過去你可能用過 window.onload 來處理,或是直接在 <body> 標籤上加入 onload 的事件處理函數,但是 jQuery 提供了另一種選擇,請參考下面的範例:
  1. $(document).ready(function() {  
  2.   alert('您好,歡迎來到 jsGears.com ~');  
  3. }); 

先透過 $() 取得 document 物件,接著使用 ready() 帶入一個函數,就可以在網頁下載完成後立即執行。jQuery 的 document ready 事件是模擬 W3C DOM 標準的 DOMContentLoaded 事件,DOMContentLoaded 和 window.onlad 的差異在於前者是在 DOM 文件下載完成後觸發,而後者是文件和所有文件內的元件,包含圖檔等等全部下載完成後才會觸發,因此通常 window.onload 的發生時間要比 DOMContentLoaded 晚一點(如果你的網頁內確實有用到一些圖檔),有時候你所需要執行的程式並不需要等所有圖檔都下載完成,因此,放到 DOMContentLoaded 事件內處理是比較合適的。但是,IE 目前的版本 6 和 7 並不支援 DOMContentLoaded 事件,所以 jQuery 用了一些技巧來達到模擬 DOMContentLoaded 的事件,而成果就是上面看到的這個例子的用法。
DOMContentLoaded 和 window.onlad 的另一個差異在於 window.onload 並沒有辦法多次指定不同的函數來執行,最後指定的那個函數會複寫掉先前的,例如以下範例:

  1. window.onload = function() {  
  2.   alert('Hello world!');  
  3. };  
  4. window.onload = function() {  
  5.   alert('您好,歡迎來到 jsGears.com ~');  
  6. }; 

上面的例子在同一個頁面上用了兩次 window.onload,結果將會是後面的函數會被執行到,前面的函數將消失無影蹤,當然,只要你稍具 JavaScript 處理 Event 的技巧,真要連續指定兩個函數來執行也不是太困難,不過用 jQuery 會更容易,看看以下相同的範例:

  1. $(document).ready(function() {  
  2.   alert('Hello world!');  
  3. });  
  4. $(document).ready(function() {  
  5.   alert('您好,歡迎來到 jsGears.com ~');  
  6. }); 

相同的例子使用 jQuery 的 document ready 函數,則帶入的兩個函數都會被執行到,很簡單吧,完全不需用到什麼技巧。再提供一個精簡的語法, document ready 函數也可以這樣用:

  1. $(function() {  
  2.   alert('您好,歡迎來到 jsGears.com ~');  
  3. }); 

直接把函數放到 $() 裡面就可以了,是不是超精簡啊。

[$() 別名]


前面用到了很多 $(),包含剛介紹的 document ready 及先前的選取功能,都是透過這個簡短的錢記號來達成,其實這個錢記號是 「jQuery」這個物件的縮寫,也就是剛剛所有你看到用 $() 的地方,都可以改寫成用 jQuery(),例如:
  1. jQuery(document).ready(function() {  
  2.   jQuery("div").addClass("special");  
  3. }); 

沒事應該不會有人想用比較長的名稱來寫程式,簡短的 $ 不是挺好的。但是,某些情況可能你無法使用 $(),例如你進行中的專案已經使用了其他的 JavaScript Library,而 $ 這個名稱已經被使用了,例如另一套知名的 prototype,也使用了 $() 這樣的函數名稱,這時如果你需要再搭配使用 jQuery 的話,jQuery 本身有提供一個方式來避免 $() 的衝突:

  1. jQuery.noConflict();  
  2. jQuery(document).ready(function() {  
  3.   jQuery("div").addClass("special");  
  4. }); 

使用 jQuery 前,先下達 jQuery.noConflict() 這樣就可以避免掉 $() 衝突的問題,接著再用 jQuery 物件來進行操作即可。此外,你也可以自行幫 jQuery 這個物件設定另一個別名,例如:

  1. var $j = jQuery.noConflict();  
  2. $j(document).ready(function() {  
  3.   $j("div").addClass("special");  
  4. }); 

使用一個變數來接 jQuery.noConflict() 的回傳值,這個變數就可以做為 jQuery 的一個別名,透過這個別名不但避免了和其他 Library 錢記號的衝突,也可以將函數名稱縮短,算是 jQuery 一個蠻貼心的設計。

To infinity and beyond!

JavaScript 物件(OO)寫法基本介紹。

FishFactory Paradigm

下面的寫法讓你做出一個Fish的物件。

var Fish= new Object;  

Fish.color = 'red';  

Fish.size = 4;  

Fish.type= '淡水';  

Fish.showColor = function() {  
     alert(this.color);  
};  

但可能你需要的產生很多 Fish 物件,這種方式只能一個個寫他的屬性跟方法,那是一件非常可怕的事情。

現在把他修改一下,把他包起來,讓他比較像我們在C++或JAVA的樣子。

function createCar() {

var Fish= new Object;

Fish.color = 'red';

Fish.size= 4;

Fish.type = '淡水';  

Fish.showColor = function() {
    alert(this.color);
};

return Fish;

};

var Fish1= createCar();
var Fish2 = createCar();                   

可是這樣還是一樣Fish1跟Fish2 完全一樣,並沒有太大的幫助。還是要寫好多個。

這樣是有一點物件導向的味道了,但是我們如果不用 new 這個關鍵字,感覺缺乏了 Semantic 的意義。

Constructor paradigm

如前述的問題,我們改寫一下,讓 Fish函式成為一個建構式,可以很方便地用一個 new 的關鍵字製造出許多的 Objects

function Fish(iColor,iSize,iType) {

this.color = iColor;

this.Size = iSize;

this.Type = iType;

this.showColor = function() {

alert(這條的魚的顏色是 ' + this.color);

};

};

var Fish1 = new Fish('red', 4, '淡水');

var Fish2 = new Fish('blue', 3, '海水');

Fish1.show();

這樣有沒有就比較接近JAVA或C++的物件格式了,上述的程式碼會跳出Alert 這條的魚的顏色是red。

上述的寫法是目前最容易看到的寫法之一,也是一般網路上最常見的寫法。

Hybrid Constructor / Prototype Paradigm

上述的寫法是目前最容易看到的寫法之一。但是有些人會考量到效能面,如 showColor() 這個方法,每次 instantiate 時,裡面所有的屬性與方法都會被複製一份。其實我們可以讓這個方法只產生一次、而且被共用。但是並不是所有狀況都適用。

function Fish(iColor,iSize,iType) {

this.color = iColor;

this.Size = iSize;

this.Type = iType;

this.showColor = function() {

alert(這條的魚的顏色是 ' + this.color);

};

};

Fish.prototype.showColor = function() {

alert(這條的魚的顏色是 ' + this.color);

};

var Fish1 = new Fish('red', 4, '淡水');

var Fish2 = new Fish('blue', 3, '海水');

Fish1.show();

雖然這樣的效能比較好,但原則上我個人是比較喜歡包裝在一個 constructor 內,在撰寫期間比較容易觀看,但是要看程適應用的層面。

Prototype paradigm

眼尖的人會看到 Hybrid 這個字,所以我還是介紹一下 Prototype 的寫法

//先有一個空的 function  
function Fish() {  

};  

//再利用 prototype 的方式幫這個 Car() 新增屬性及方法  

Fish.prototype.color = 'red';  

Fish.prototype.doors = 4;  

Fish.prototype.mpg = 23;  

Fish.prototype.showColor = function() {  
    alert(這隻魚顏色是 ' + this.color); 
};   

//無法用參數...   

var Fish1 = new Fish();   

var Fish2 = new Fish(); 

這種寫法有一個很討厭的缺點,就是沒辦法利用參數設定屬性。必須在 Instantiate 物件後再 Assign。我是從來沒用過這個寫法,而且有時候後面的人加東西,就會整個一團亂。

後來我也看了很多文章,我覺得下面這樣的寫法,是我覺得比較好,也比較容易debug的方法。

function Fish(iColor,iSize,iType) {

// 因為 this 容易產生誤解,所以指定為 oComponent 
MyObj=this;

MyObj.color = iColor;

MyObj.Size = iSize;

MyObj.Type = iType;

//下面這樣的宣告模式跟Public 的意思是一樣的。
MyObj.showColor = function() {

alert(這條的魚的顏色是 ' + MyObj.color);

};

//這樣的宣告模式..就跟private是一樣的
var showSize= function(sMethod,sParameters){

alert(這條的魚的的類型 ' + MyObj.Type);

};

};

var Fish1 = new Fish('red', 4, '淡水');

var Fish2 = new Fish('blue', 3, '海水');

Fish1.showColor();

//這行是會有錯誤的
Fish2.showSize();

希望這篇文章對你有幫助,順便付上一個網址,是我看完那些資料之後,整理出來的。希望對你是有幫助的。

我之後會再補上一篇 有Var跟沒有的差別。

http://www.josephjiang.com/presentation/OOJS/object-oriented-paradigms.html#section1

什麼是 JSON

什麼是 JSON?JSON 全稱 JavaScript Object Notation是一種非常輕量級的資料交換格式它是基於JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999的一個子集JSON 主要利用了成對的 {} 來包住各個object(物件),用成對的 [] 來包各個array(陣列),用成對的 "" 來包住各字串,用逗號來區隔各變數而資料型態有 string, number, array, object

在介紹 JSON 之前,先來看看 Javascript 是怎麼表示物件跟陣列的。

先稍微了解一下JavaScript的陣列:

你可以建立一個陣列物件,其中包含該有的元素,如下:

var myArray = new Array ("Hero", "Euro", "MyCat");

此外,你也可以這樣表示一個陣列:

var myArray = ["Hero", "Euro", "MyCat"];

Javascript 的陣列是混和式的陣列,你可以在一個陣列中包含各種型態的物件,字串、數字或者自建物件等,通通都可以。

在來說明一下物件,你可以以如下程式建立一個新物件:

var myCat = new Object();

myCat.name = "Hero";

myCat.age = 5;

myCat.color = "silver";

上面是一般建立物件的概念。此外,你也可以用底下的方式來代表一個新物件(這比較重要):

var myCat = { "name": "Hero", "age": 5, "color": "silver" };

//以下兩種方式顯示的結果都相同
alert(myCat.name);
alert(myCat.age);
alert(myCat.color);

//這總就是值接把物件的變數名稱當做陣列的參數呼叫(了解下來方是對你比較有幫助)
alert(myCat["name"]);
alert(myCat["age"]);
alert(myCat["color"]);

上述兩種方法分別會跳出對話視窗顯示HERO,5,silver。

再來,陣列物件混和使用:

var myCats = [ { "name": "Hero", "age": 5, "color": "silver" },
                        { "name": "Euro", "age": 2, "color": ["brown", "white", "black"] } ];

alert(myCats[0].name); //結果會跳出對話視窗,顯示HERO

alert(myCats[1].age);  //結果會跳出對話視窗,顯示2

OK,你已經知道 JSON 是什麼了,上面講的 Javascript Object and Array notation,就是JSON的概念了。

物件陣列的文字表示法就是 JSON 的精神,因此 JSON 全名就是「JavaScript Object Notation」。

一個簡單的 JSON 範例如下:

{
     "myCats": [
                        { "name": "Hero", "age": 5, "color": "silver" },
                        { "name": "Euro", "age": 2, "color": ["brown", "white", "black"] }
                      ]
}

這樣看來,JSON 有什麼用?有什麼了不起的?事實上,你可以當它是種資料交換格式,就像 XML 一樣,你可以將這兩種格式視為相同,可以互轉,但是不是絕對等於,也不能互相取代。
怎麼用JSON?

舉例,如果你有一串 JSON 的字串,如下:

var json = '{  "myCats"  :
                       [
                             {"name": "Hero", "age": 5, "color": "silver" },
                             {"name": "Euro", "age": 2, "color": ["brown", "white", "black"] }
                       ] 
                  }';

怎麼用?就這樣用:

var obj = eval ("(" + json + ")");

alert('I have ' + obj.myCats.length + ' cats.');    //這裡會顯示2 

alert(obj.myCats[0].name);     // 這裡會顯示 Hero 

alert(obj.myCats[1].name);     // 這裡會顯示 Euro

利用 eval() 來將 JSON 字串轉成物件,不過字串的前後記得要加上刮號 (),這是用來告知 Javascript Interpreter 這是個物件描述,不是要執行的 statement。
但是呼叫 eval() 是危險的,因為他會執行任何字串中的 Javascript 程式碼,容易有 XSS 攻擊的危險,所以一般都建議引用官網上所提供的 parser - http://www.json.org/json.js 。

var obj = JSON.parse(json);

alert('I have ' + obj.myCats.length + ' cats.');

alert(obj.myCats[0].name);

alert(obj.myCats[1].name);

此外 json.js 還提供了一項方便的功能,就是增加了 toJSONString() 函式,您可以直接如下傳回物件的JSON表示法: 

function Person( name, age, phone) {
                    this.name = name;
                    this.age = age;
                    this.phone = phone;
}

var person = new Person( "Roger", 30 , 0912345678);
json = person.toJSONString() ;
var object = JSON.parse(json);

Ex : object.person.name = Roger ; object.person.age = 30

其實除了 AJAX 外,一般 Web UI 應用應該也是可以運用 JSON 的,現在一般的 UI 設計都是以伺服器端的 PHP、ASP、CGI 等依據資料來控制網頁的編排,但是有時候為了 DHTML 設計,又非得在用戶端的瀏覽器上利用 Javascript 做變動,同樣的 UI 設計卻需要同時在兩端做考量,網頁設計師與程式設計師的溝通就變的複雜,如何改進?我的想法是,底層 PHP、ASP、CGI 等就一次把前端所需要的資料寫在網頁上,要怎麼安排介面,只需要修改 Javascript 即可,前端程式有了資料後可以自由安排版面配置,後端程式只需要關心如何從資料庫撈資料就好,所以既然如此,最好的資訊呈現方式就非 JSON 莫屬了,Javascript 的一塊肉。資料回存資料庫也類似,JSON 也可以與 PHP 的物件互轉,同樣可以在用戶端將資訊轉成 JSON 格式,到了伺服器端,轉換成物件,一樣可以做資料檢查驗證等,甚至轉換成 SQL,回存資料庫。

JQuery 基本概念

自從jQuery被微軟選秀入宮採納應用於未來產品之後,從原本Javascript老鳥才會識貨相挺的另類神兵利器,忽然一夕間傳遍鄉里,老幼皆知。不過我相信仍有不少人對jQuery十分陌生,這篇文章主要還是讓有寫過JavaScript,但是不曾碰過JQuery的人。 讓你對JQuery的用途有個概念。

jQuery 是一套 JavaScript 的 Library,因此,你必須稍具 JavaScript 的基礎,至少寫過一些 JavaScript 才比較容易上手,並且看得懂後續的教學。jQuery 的核心程式並非包山包海、什麼都可以幫你做,相反地,jQuery 主要是用在 DOM 文件的操作,包含「快速選取元素(Element)」並且「做一些事情」,快速選取元素可以讓你一次選取單一或多個的元素,然後你可以將這些被選取的元素做一些改變,例如隱藏、顯示等等。此外 jQuery 的核心程式還加強了非同步傳輸(AJAX)以及事件(Event)的功能,讓你更容易操作遠端文件及事件。

以上看得出來 jQuery 是針對 JavaScript 內在不足的地方加以增進,你仍然需要自己寫一些程式來完成你需要的各種功能,不同的是,正確地使用了 jQuery 可以讓你的程式碼更精簡、更優雅的表達出來,這在後續的範例中可以看到,更重要的是,應該也會讓你更快速的開發出你要的功能。

或許你會想說,在這個 Web 2.0 的時代,我需要多點漂亮、絢麗的 Widgets 來裝飾我的網站,就像 Yahoo UI 或 ExtJS 提供的那些功能一樣,jQuery 有嗎?其實 jQuery 的設計上有考慮到這類擴展性的問題,目前 jQuery 的 plugin 已經有上百個了,你也不一定要完全自己動手寫,上 jQuery 官方網站找找看,或許你需要的功能別人已經幫你做好了。以 UI 來講, jQuery 跟 UI 相關的 plugins 已經做過了一些整合,目前獨立發佈為 jQuery UI (http://ui.jquery.com/),如果你之前沒聽過 jQuery UI,建議你上去網站上看一下展示的範例,嗯,雖然可能還有一些 bug 存在,但是整體來說已經有相當的水準了,或許你會對 jQuery 更有興趣了。

簡而言之!JQuery 就跟他的主題重一點一樣。Wirte less. Do more.

1.jQuery是什麼?

jQuery是一組可以神奇地簡化Javascript程式寫法的Open Source Library,由John Resig於2006發表。透過Selector、函數串接、元素陣列整批處理等巧妙的語言特色,加上對於HTML處理中常用的Event、Attribute、CSS Style、元素新增/刪除都提供了簡便的寫法,能將原本要寫上數百行的Javascript程式簡化到幾行搞定,故深受許多Javascript開發者的歡迎。

2.為什麼Javascript老鳥看到jQuery這麼興奮? 她當真如此傾國傾城?

寫好Javascript從來不是件簡單事,從拼拼湊湊在自己的IE上運作正常,要提升到讓Internet四面八方湧來的Firefox、Opera、Safar都能跑得順暢,猶如登七星山到爬黑色奇萊的差別。Javascript Framework可以幫我們處理掉惱人的相容細節,讓我們用統一的方式就搞定大部分的主流瀏覽器,當未來有新的瀏覽器規格問市時,我們只要更新Framework版本即可。同時,Framework還會針對常用的功能,提供簡便的公用函數,用較簡單寫法取代原本繁瑣的程式。而眾多Javascript Framework中, jQuery算是最能實現Do More With Less精神的一個,跟其他Framework相比,完成同樣工作,所需要程式行數少得嚇人,因此特別吸引寫Javascript已經寫到手酸的老鳥。

3.jQuery好學嗎?

說jQuery好學是騙人的,它一開始的學習曲線頗為陡峭。Do More With Less的先決條件是要先搞懂像魔法咒語一般的CSS Selector,了解函數接接樂原理、以及一些jQuery慣用的簡潔Javascript語法(這部分未來會再介紹),得花些心思才能上手,但我保證這個投資的報酬非常驚人。在程式設計上有個很棒的比擬,Regular Expression,一點也不好學,但學會後,原本200行的程式碼只要兩行就可以搞定。

4.我不會寫Javascript,jQuery對我有用嗎?

微軟對ASP.NET/ASP.NET AJAX加了一些很奇妙的設計,利用PostBack+Update Panel,就有開發者一行Javascript也沒寫過,單單用C#/VB.NET寫Server-Side Event就做出很棒很炫的AJAX效果。不過,PostBack+Update Panel的寫法常涉及大量ViewState資料的來回傳送,較為笨重;而光靠現成的東西也不可能解決全部的問題,某些時候,自己動手寫幾行Javascript可以更有效率地滿足系統需求。暗示了這麼久,你如果還是堅持不碰Javascript... 這題的回答是: NO! jQuery對你沒什麼用處。

5.我想學jQuery,要怎麼開始?

對不會Javascript的人來說,jQuery只是塊石頭。所以學jQuery之前,要先對Javascript有基本的認識,對Javascript愈熟,運用jQuery所產生的威力愈大。Javascript出來很久了,坊間可以找到很多書籍,不想花錢Google一下"Javascript 教學"也可以找到成千上萬的網頁,但書籍的介紹可能會較有系統一些。要學習jQuery,我強力推薦

6.Selector是什麼? 為什麼一堆人對它津津樂道?

"我想要在將表格中的單數列加上淺藍色背景"
"我希望這五個輸入欄位可以用一個按鈕切換顯示或隱藏"
這些需求在傳統做法中,都要透過事前指定元素ID,或動態掃過全部的元素集合的方式處理。jQuery實現了CSS規格的CSS Selector概念,一行解決原本數十行才能搞定的效果,加上應用廣泛,所有開始使用jQuery的人一定會被它電到,從此愛不釋手。除了前述Visual jQuery可以找到範例外,我還找到另一篇完整的中文整理。

7.你老是在講的接接樂是啥?

利用Selector選出來的結果常是一堆網頁元素的集合(陣列),此時只要在後方加上處理函數(例如: 修改CSS格式、加掛Click事件),則可以直接對陣列中的每一個元素都做一次處理,最棒的是處理函數做完後會再傳回原本的陣列,所以可以馬上在後面加上第二個處理函數,再對同陣列的所有元素做其他處理,寫起來超省Code。例如: $("..選擇100個元素..").css(設定CSS格式).click(加上Click事件).append(在其中插入其他物件)。

8.寫Javascript過過癮,還有什麼好康?

並不是什麼東西都要自己用Javascript寫才能發揮jQuery的價值,jQuery是很受歡迎的Javascript Framework,現在已經有很多善心人士寫好的好用插件(Plug-In),例如: 照片展示、動態選單、自動完成、表格排序... 官方網站上有完整的整理,要自己動手做之前,不妨先找找有無現成的插件,可以省下可觀的時間。

Microsoft Exchange PHP WebDAV Examples

 

Author: Troy Wolf (troy@troywolf.com)
Modified Date: 2006-04-07

Does your organization use Microsoft Exchange?
Do you have a need to incorporate your Exchange data with your PHP web applications?
Do you NOT want to struggle for 2 days figuring this stuff out like I did?!

.....then these examples are for you. Learn from my pain, grasshopper.

If you are like me, you start this journey with a Google search for something like '"Exchange Server" PHP' or 'PHP "Microsoft Exchange" iterate contacts'. You quickly learn there are several different technologies--all rather cryptic-- to programmatically access your Exchange data. Let me shorten your reading time--WebDAV is the technology you want to use to allow your PHP applications to query Exchange.

Once I learned this technique, I made small tweaks to both my http and xml classes to support WebDAV queries. That's right, these examples incorporate two of my most popular classes. You can learn more about these PHP classes, but you don't need to in order to use these examples.

  1. class_http
  2. class_xml

By far, the most difficult part of querying your Exchange Server will be how exactly to construct the WebDAV request to get the information you want. You'll no doubt end up spending some time looking at the documentation and examples at http://msdn.microsoft.com/library/default.asp?url=/library/en-us/e2k3/e2k3/wss_references_webdav.asp.

You'll also need the reference material that documents all the Exchange object properties and what each one's urn is. http://msdn.microsoft.com/library/default.asp?url=/library/en-us/e2k3/e2k3/_exch2k_urn_content-classes_person.asp
The code examples below will help you see how these are used.

Whenever I personally use this class to accomplish a unique task, I update this page with a generic example of the technique. Currently, these examples are available:

The Code Examples

I'm not going to explain these examples too much--I'll just give a short description of what the code is querying, then show the full code example. Unfortunately, I don't have any publicly-accessible Exchange Servers so I am unable to give you any live, working examples. In all the examples below, I make the assumption that you have at least some programming experience and you'll understand to modify the parts you need to work in your environment. For example, obviously the name of your Exchange Server, the paths to your folders, your username and password will be different than what I show in these examples.

Example 1 - Iterate the folders in a user's inbox
This first example will include a lot of comments and examples of how to work with the objects produced after parsing the result XML. Later examples will be less complete.

<?php
// Modify the paths to these class files as needed.
require_once("class_http.php");
require_once("class_xml.php");
// Change these values for your Exchange Server.
$exchange_server = "http://NameOfYourExchangeServer";
$exchange_username = "YourExchangeUsername";
$exchange_password = "YourExchangePassword";
// We use Troy's http class object to send the XML-formatted WebDAV request
// to the Exchange Server and to receive the response from the Exchange Server.
// The response is also XML-formatted.
$h = new http();
$h->headers["Content-Type"] = 'text/xml; charset="UTF-8"';
// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/e2k3/e2k3/_webdav_depth_header.asp
$h->headers["Depth"] = "0";
$h->headers["Translate"] = "f";
// The trickiest part is forming your WebDAV query. This example shows how to
// find all the folders in the inbox for a user named 'twolf'.
$h->xmlrequest = '<?xml version="1.0"?>';
$h->xmlrequest .= <<<END
<a:searchrequest xmlns:a="DAV:" xmlns:s="http://schemas.microsoft.com/exchange/security/">
   <a:sql>
       SELECT "DAV:displayname"
       FROM SCOPE('hierarchical traversal of "$exchange_server/Exchange/twolf/inbox"')
   </a:sql>
</a:searchrequest>
END;
// IMPORTANT -- The END line above must be completely left-aligned. No white-space.
// The 'fetch' method does the work of sending and receiving the request.
// NOTICE the last parameter passed--'SEARCH' in this example. That is the
// HTTP verb that you must correctly set according to the type of WebDAV request
// you are making.  The examples on this page use either 'PROPFIND' or 'SEARCH'.
if (!$h->fetch($exchange_server."/Exchange/twolf/inbox", 0, null, $exchange_username, $exchange_password, "SEARCH")) {
  echo "<h2>There is a problem with the http request!</h2>";
  echo $h->log;
  exit();
}
// Note: The following lines can be uncommented to aid in debugging.
#echo "<pre>".$h->log."</pre><hr />\n";
#echo "<pre>".$h->header."</pre><hr />\n";
#echo "<pre>".$h->body."</pre><hr />\n";
#exit();
// Or, these next lines will display the result as an XML doc in the browser.
#header('Content-type: text/xml');
#echo $h->body;
#exit();
// The assumption now is that we've got an XML result back from the Exchange
// Server, so let's parse the XML into an object we can more easily access.
// For this task, we'll use Troy's xml class object.
$x = new xml();
if (!$x->fetch($h->body)) {
    echo "<h2>There was a problem parsing your XML!</h2>";
    echo "<pre>".$h->log."</pre><hr />\n";
    echo "<pre>".$h->header."</pre><hr />\n";
    echo "<pre>".$h->body."</pre><hr />\n";
    echo "<pre>".$x->log."</pre><hr />\n";
    exit();
}
// You should now have an object that is an array of objects and arrays that
// makes it easy to access the parts you need. These next lines can be
// uncommented to make a raw display of the data object.
#echo "<pre>\n";
#print_r($x->data);
#echo "</pre>\n";
#exit();
// And finally, an example of iterating the inbox folder names and url's to
// display in the browser. I also show you 2 methods to link to the folders.
// One uses the href provided in the response which opens the folder using OWA.
// The other is an Outlook style link to open the folder in the Outlook desktop
// client.
echo '<table border="1">';
foreach($x->data->A_MULTISTATUS[0]->A_RESPONSE as $idx=>$item) {
    echo '<tr>'
.'<td>'.$item->A_PROPSTAT[0]->A_PROP[0]->A_DISPLAYNAME[0]->_text.'</td>'
.'<td><a href="'.$item->A_HREF[0]->_text.'">Click to open via OWA</a></td>'
.'<td><a href="Outlook:Inbox/'.$item->A_PROPSTAT[0]->A_PROP[0]->A_DISPLAYNAME[0]->_text.'">Click to open via Outlook</a></td>'
."</tr>\n";
}
echo "<table>\n";
?>

Some notes regarding Outlook URL's
By "Outlook URL", I mean the special "outlook:" URLs you can create that open the Outlook Client app to view folders and items. If anyone finds definitive documentation for all the options, please let me know. I found this link helpful. It's really old, but still applicable. http://support.microsoft.com/?kbid=225007

If the 'twolf' inbox has a 'Company Picnic' subfolder, the code above would create a link to "Outlook:Inbox/Company Picnic". This link is really only good for twolf unless other users happen to have an Inbox/Company Picnic folder. You can make the link user-specific, but since it is unlikely any users have access to other users' mail folders, it is probably not that useful. But here is how you make that link: "Outlook://Mailbox - Troy Wolf/Inbox/Company Picnic".

I have not completely figured out what characters should be escaped and what should not. For example, it does not matter if you leave spaces as spaces or replace with %20, but you can not replace with a '+'. Other characters seem to break the URL if you urlencode them. Other characters seem to break the URL regardless of whether they are urlencoded or not! (The OWA hrefs seem to always work.)

Notes: You can run web pages in a normal browser or directly within Outlook. There are some caveats to be aware of.

  1. Links and new windows - When using Outlook: style links in a browser external to Outlook, the Outlook content will always open a new Outlook window regardless of the fact you may already have Outlook open. I see the argument for either way, but would prefer a method to indicate whether to open a new window or navigate the existing Outlook window. I think by default, folders should open in the existing Outlook window and specific items should open a new window--just like they do in Outlook normally. You taking notes, Bill? :) When using links on a web page running directly within Outlook, the content opens as expected. That is, folders navigate the current window to the folder and items pop in a new Outlook window.
  2. Authorization required content - When accessing content that requires basic authentication, your users will have to login when accessing the content inside Outlook. Then, if you pages pop new IE windows, they'll have to login again in the IE window. My assumption is that IE--the stand-alone browser--and IE running within Outlook use seperate memory space. If somebody has more technical details or workaround options, please send them to me at troy@troywolf.com.

Example 2 - Iterate the email items in a user's inbox

<?php
// Modify the paths to these class files as needed.
require_once("class_http.php");
require_once("class_xml.php");
// Change these values for your Exchange Server.
$exchange_server = "http://NameOfYourExchangeServer";
$exchange_username = "YourExchangeUsername";
$exchange_password = "YourExchangePassword";
// We use Troy's http class object to send the XML-formatted WebDAV request
// to the Exchange Server and to receive the response from the Exchange Server.
// The response is also XML-formatted.
$h = new http();
$h->headers["Content-Type"] = 'text/xml; charset="UTF-8"';
$h->headers["Depth"] = "0";
$h->headers["Translate"] = "f";
// Find all the email items in the inbox for a user named 'twolf'.
$h->xmlrequest = '<?xml version="1.0"?>';
$h->xmlrequest .= <<<END
<a:searchrequest xmlns:a="DAV:" xmlns:s="http://schemas.microsoft.com/exchange/security/">
   <a:sql>
       SELECT "DAV:displayname"
       ,"urn:schemas:httpmail:subject"
       FROM "$exchange_server/Exchange/twolf/inbox"
   </a:sql>
</a:searchrequest>
END;
// IMPORTANT -- The END line above must be completely left-aligned. No white-space.
// The 'fetch' method does the work of sending and receiving the request.
// NOTICE the last parameter passed--'SEARCH' in this example. That is the
// HTTP verb that you must correctly set according to the type of WebDAV request
// you are making.  The examples on this page use either 'PROPFIND' or 'SEARCH'.
if (!$h->fetch($exchange_server."/Exchange/twolf/inbox", 0, null, $exchange_username, $exchange_password, "SEARCH")) {
  echo "<h2>There is a problem with the http request!</h2>";
  echo $h->log;
  exit();
}
// The assumption now is that we've got an XML result back from the Exchange
// Server, so let's parse the XML into an object we can more easily access.
// For this task, we'll use Troy's xml class object.
$x = new xml();
if (!$x->fetch($h->body)) {
    echo "<h2>There was a problem parsing your XML!</h2>";
    echo "<pre>".$h->log."</pre><hr />\n";
    echo "<pre>".$h->header."</pre><hr />\n";
    echo "<pre>".$h->body."</pre><hr />\n";
    echo "<pre>".$x->log."</pre><hr />\n";
    exit();
}
// And finally, an example of iterating the email items to display in the
// browser. I also show you 2 methods to link to the items. One uses the href
// provided in the response which opens the folder using OWA. The other is an
// Outlook style link to open the folder in the Outlook desktop client.
echo '<table border="1">';
foreach($x->data->A_MULTISTATUS[0]->A_RESPONSE as $idx=>$item) {
    echo '<tr>'
.'<td>'.$item->A_PROPSTAT[0]->A_PROP[0]->D_SUBJECT[0]->_text.'</td>'
.'<td><a href="'.$item->A_HREF[0]->_text.'">Click to open via OWA</a></td>'
.'<td><a href="Outlook:Inbox/~'.$item->A_PROPSTAT[0]->A_PROP[0]->D_SUBJECT[0]->_text.'">Click to open via Outlook</a></td>'
."</tr>\n";
}
echo "<table>\n";
?>

Example 3 - Search for contacts that match a certain criteria
This example can easily be modified to simply iterate all contacts in a folder by simply deleting the WHERE clause in the WebDAV request.

<?php
// Modify the paths to these class files as needed.
require_once("class_http.php");
require_once("class_xml.php");
// Change these values for your Exchange Server.
$exchange_server = "http://NameOfYourExchangeServer";
$exchange_username = "YourExchangeUsername";
$exchange_password = "YourExchangePassword";
// We use Troy's http class object to send the XML-formatted WebDAV request
// to the Exchange Server and to receive the response from the Exchange Server.
// The response is also XML-formatted.
$h = new http();
$h->headers["Content-Type"] = 'text/xml; charset="UTF-8"';
$h->headers["Depth"] = "0";
$h->headers["Translate"] = "f";
// Find all the contacts for a specific company in a specific folder.
// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/e2k3/e2k3/_exch2k_urn_content-classes_person.asp
$h->xmlrequest = '<?xml version="1.0"?>';
$h->xmlrequest .= <<<END
<a:searchrequest xmlns:a="DAV:">
    <a:sql>
        SELECT "a:href"
        ,"urn:schemas:contacts:o"
        ,"urn:schemas:contacts:cn"
        ,"urn:schemas:contacts:fileas"
        ,"urn:schemas:contacts:title"
        ,"urn:schemas:contacts:email1"
        ,"urn:schemas:contacts:telephoneNumber"
        FROM "$exchange_server/public/Customer%20Contacts/"
        WHERE "urn:schemas:contacts:o" = 'XYZ Industries, Inc.'
        ORDER BY "urn:schemas:contacts:cn"
    </a:sql>
</a:searchrequest>
END;
// IMPORTANT -- The END line above must be completely left-aligned. No white-space.
// The 'fetch' method does the work of sending and receiving the request.
// NOTICE the last parameter passed--'SEARCH' in this example. That is the
// HTTP verb that you must correctly set according to the type of WebDAV request
// you are making.  The examples on this page use either 'PROPFIND' or 'SEARCH'.
if (!$h->fetch($exchange_server."/public/Customer%20Contacts", 0, null, $exchange_username, $exchange_password, "SEARCH")) {
  echo "<h2>There is a problem with the http request!</h2>";
  echo $h->log;
  exit();
}
// The assumption now is that we've got an XML result back from the Exchange
// Server, so let's parse the XML into an object we can more easily access.
// For this task, we'll use Troy's xml class object.
$x = new xml();
if (!$x->fetch($h->body)) {
    echo "<h2>There was a problem parsing your XML!</h2>";
    echo "<pre>".$h->log."</pre><hr />\n";
    echo "<pre>".$h->header."</pre><hr />\n";
    echo "<pre>".$h->body."</pre><hr />\n";
    echo "<pre>".$x->log."</pre><hr />\n";
    exit();
}
// And finally, an example of iterating the contact items to display in the browser.
echo '<table border="1">';
echo "<tr><th>Company</th><th>Name</th><th>Title</th><th>Email</th><th>Phone</th></tr>\n";
foreach($x->data->A_MULTISTATUS[0]->A_RESPONSE as $idx=>$contact) {
    echo '<tr>'
.'<td>'.$contact->A_PROPSTAT[0]->A_PROP[0]->E_O[0]->_text.'</td>'
.'<td><a href="outlook://Public%20Folders/All%20Public%20Folders/Account_Contacts/~'.str_replace(" ","%20",$contact->A_PROPSTAT[0]->A_PROP[0]->E_CN[0]->_text).'">'
.$contact->A_PROPSTAT[0]->A_PROP[0]->E_CN[0]->_text.'</a></td>'
.'<td>'.$contact->A_PROPSTAT[0]->A_PROP[0]->E_TITLE[0]->_text.'</td>'
.'<td>'.$contact->A_PROPSTAT[0]->A_PROP[0]->E_EMAIL1[0]->_text.'</td>'
.'<td>'.$contact->A_PROPSTAT[0]->A_PROP[0]->E_TELEPHONENUMBER[0]->_text.'</td>'
."</tr>\n";
}
echo "<table>\n";
?>

Example 4 - Grab all properties for an item
This example demonstrates returning all properties for a specific message item. You can use the allprop property to return all properties. This is very useful when you don't know what the property names are.

<?php
// Modify the paths to these class files as needed.
require_once("class_http.php");
require_once("class_xml.php");
// Change these values for your Exchange Server.
$exchange_server = "http://NameOfYourExchangeServer";
$exchange_username = "YourExchangeUsername";
$exchange_password = "YourExchangePassword";
// We use Troy's http class object to send the XML-formatted WebDAV request
// to the Exchange Server and to receive the response from the Exchange Server.
// The response is also XML-formatted.
$h = new http();
$h->headers["Content-Type"] = 'text/xml; charset="UTF-8"';
$h->headers["Depth"] = "0";
$h->headers["Translate"] = "f";
// Find all the properties for a specific item.
$h->xmlrequest = '<?xml version="1.0"?>';
$h->xmlrequest .= <<<END
<a:propfind xmlns:a="DAV:">
    <a:allprop/>
</a:propfind>
END;
// IMPORTANT -- The END line above must be completely left-aligned. No white-space.
// The 'fetch' method does the work of sending and receiving the request.
// NOTICE the last parameter passed--'PROPFIND' in this example. That is the
// HTTP verb that you must correctly set according to the type of WebDAV request
// you are making.  The examples on this page use either 'PROPFIND' or 'SEARCH'.
if (!$h->fetch($exchange_server."/public/Email%20Log/Some%20Message-668992879.EML", 0, null, $exchange_username, $exchange_password, "PROPFIND")) {
  echo "<h2>There is a problem with the http request!</h2>";
  echo $h->log;
  exit();
}
// The assumption now is that we've got an XML result back from the Exchange
// Server, so let's parse the XML into an object we can more easily access.
// For this task, we'll use Troy's xml class object.
$x = new xml();
if (!$x->fetch($h->body)) {
    echo "<h2>There was a problem parsing your XML!</h2>";
    echo "<pre>".$h->log."</pre><hr />\n";
    echo "<pre>".$h->header."</pre><hr />\n";
    echo "<pre>".$h->body."</pre><hr />\n";
    echo "<pre>".$x->log."</pre><hr />\n";
    exit();
}
echo "<pre>";
print_r($x->data);
echo "</pre>";
?>

Example 5 - Create a new contact
This example demonstrates how to programmatically create a new contact in a public contacts folder. We'll use the PROPPATCH WebDAV method. This method will create a new contact if the URL does not exist or update an existing contact. Notice the last 2 properties. Those are custom fields that must be pre-defined for the folder. I show an example where a custom field is a boolean YES/NO. I struggled with how to set this property for a few hours. You're welcome. There are many, many more contact fields available. Use the allprop example #4 above to list an existing contact to see all the fields and schemas available.

<?php
// Modify the path to this class file as needed.
require_once("class_http.php");
// Change these values for your Exchange Server.
$exchange_server = "http://NameOfYourExchangeServer";
$exchange_username = "YourExchangeUsername";
$exchange_password = "YourExchangePassword";
// We use Troy's http class object to send the XML-formatted WebDAV request
// to the Exchange Server and to receive the response from the Exchange Server.
// The response is also XML-formatted.
$h = new http();
$h->headers["Content-Type"] = 'text/xml; charset="UTF-8"';
$h->headers["Depth"] = "0";
$h->headers["Translate"] = "f";
// Build the XML request.
// This section must be against the left margin.
$h->xmlrequest = '<?xml version="1.0"?>';
$h->xmlrequest .= <<<END
<g:propertyupdate   xmlns:g="DAV:"
                    xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/"
                    xmlns:c="urn:schemas:contacts:"
                    xmlns:e="http://schemas.microsoft.com/exchange/"
                    xmlns:mapi="http://schemas.microsoft.com/mapi/"
                    xmlns:o="urn:schemas-microsoft-com:office:office"
                    xmlns:cust="urn:schemas:customproperty"
                    xmlns:ed="urn:schemas-microsoft-com:exch-data:"
                    xmlns:repl="http://schemas.microsoft.com/repl/"
                    xmlns:x="xml:"
                    xmlns:cal="urn:schemas:calendar:"
                    xmlns:mail="urn:schemas:httpmail:"
                    xmlns:ec="urn:schemas-microsoft-com:exch-data:expected-content-class"
                    xmlns:j="urn:content-classes:propertydef"
                    xmlns:mailheader="urn:schemas:mailheader:">
    <g:set>
        <g:prop>
            <g:contentclass>urn:content-classes:person</g:contentclass>
            <e:outlookmessageclass>IPM.Contact</e:outlookmessageclass>
            <e:keywords-utf8>
            <x:v>Buddies</x:v><x:v>Engineers</x:v>
            </e:keywords-utf8>
            <c:language>US English</c:language>
            <c:o>Innotech, Inc.</c:o>
            <c:givenName>John</c:givenName>
            <c:sn>Doe</c:sn>
            <c:cn>John Doe</c:cn>
            <c:fileas>Doe, John</c:fileas>
            <c:street>100 N. Main</c:street>
            <c:postofficebox>PO Box 555</c:postofficebox>
            <c:l>Kansas City</c:l>
            <c:st>MO</c:st>
            <c:postalcode>64118</c:postalcode>
            <c:co>USA</c:co>
            <c:telephoneNumber>425-555-1110</c:telephoneNumber>
            <c:facsimiletelephonenumber>425-555-1112</c:facsimiletelephonenumber>
            <c:homePhone>425-555-1113</c:homePhone>
            <c:mobile>425-555-1117</c:mobile>
            <mapi:email1addrtype>SMTP</mapi:email1addrtype>
            <mapi:email1emailaddress>john.doe@hotmail.com</mapi:email1emailaddress>
            <mapi:email1originaldisplayname>John Doe</mapi:email1originaldisplayname>
            <favoritecolor>Blue</favoritecolor>
            <newsletter b:dt="boolean">1</newsletter>
        </g:prop>
    </g:set>
</g:propertyupdate>
END;
// IMPORTANT -- The END line above must be completely left-aligned. No white-space.
// The http object's 'fetch' method does the work of sending and receiving the
// request. We use the WebDAV PROPPATCH method to create or update Exchange items.
$url = $exchange_server."/public/Company%20Contacts/john%20doe.EML";
if (!$h->fetch($url, 0, null, $exchange_username, $exchange_password, "PROPPATCH")) {
  echo "<h2>There is a problem with the http request!</h2>";
  echo $h->log;
  exit();
}
// You can print out the response to help troubleshoot.
echo "<pre>".$h->header."</pre><hr />\n";
echo "<pre>".$h->body."</pre><hr />\n";
?>

Example 6 - Create a new email message
This example demonstrates how to programmatically create a new email message. In this example, we'll create the example in the user's Drafts folder. The exchange username and password will need privileges to create items in the user's personal folders.

<?php
// Modify the path to this class file as needed.
require_once("class_http.php");
// Change these values for your Exchange Server.
$exchange_server = "http://NameOfYourExchangeServer";
$exchange_username = "YourExchangeUsername";
$exchange_password = "YourExchangePassword";
// We use Troy's http class object to send the XML-formatted WebDAV request
// to the Exchange Server and to receive the response from the Exchange Server.
// The response is also XML-formatted.
$h = new http();
$h->headers["Content-Type"] = 'text/xml; charset="UTF-8"';
$h->headers["Depth"] = "0";
$h->headers["Translate"] = "f";
$subject = "Ci@lis CHEAP!";
// Build the XML request.
// This section must be against the left margin.
$h->xmlrequest = '<?xml version="1.0"?>';
$h->xmlrequest .= <<<END
<a:propertyupdate   xmlns:a="DAV:"
                    xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/"
                    xmlns:g="http://schemas.microsoft.com/mapi/"
                    xmlns:e="urn:schemas:httpmail:"
                    xmlns:d="urn:schemas:mailheader:"
                    xmlns:c="xml:"
                    xmlns:f="http://schemas.microsoft.com/mapi/proptag/"
                    xmlns:h="http://schemas.microsoft.com/exchange/"
                    xmlns:i="urn:schemas-microsoft-com:office:office"
                    xmlns:k="http://schemas.microsoft.com/repl/"
                    xmlns:j="urn:schemas:calendar:"
                    xmlns:l="urn:schemas-microsoft-com:exch-data:">
    <a:set>
        <a:prop>
            <a:contentclass>urn:content-classes:message</a:contentclass>
            <h:outlookmessageclass>IPM.Note</h:outlookmessageclass>
            <d:to>foo@foobar.com</d:to>
            <d:cc>bar@foobar.com</d:cc>
            <d:bcc>bob@aol.com</d:bcc>
            <g:subject>$subject</g:subject>
            <e:htmldescription>This is spam. Please delete this email.</e:htmldescription>
        </a:prop>
    </a:set>
</a:propertyupdate>
END;
// IMPORTANT -- The END line above must be completely left-aligned. No white-space.
// The http object's 'fetch' method does the work of sending and receiving the
// request. We use the WebDAV PROPPATCH method to create or update Exchange items.
$url = $exchange_server."/Exchange/twolf/Drafts/".urlencode($subject).".EML";
if (!$h->fetch($url, 0, null, $exchange_username, $exchange_password, "PROPPATCH")) {
  echo "<h2>There is a problem with the http request!</h2>";
  echo $h->log;
  exit();
}
// You can print out the response to help troubleshoot.
echo "<pre>".$h->header."</pre><hr />\n";
echo "<pre>".$h->body."</pre><hr />\n";
// Bonus tip! You can automatically open this new draft message for your user by
// formulating an outlook URL. Then either redirect to the URL by uncommenting the
// header line below, or pop the URL in client-side javascript using window.open.
#header("Location: outlook:drafts/~".urlencode($subject));
?>


About the author
Troy Wolf is the author of SnippetEdit--a PHP application providing browser-based website editing that even non-technical people can use. Website editing as easy as it gets. Troy has been a professional Internet and database application developer for over 12 years. He has many years' experience with ASP, VBScript, PHP, Javascript, DHTML, CSS, SQL, and XML on Windows and Linux platforms. Check out Troy's Code Library.