2016年3月31日 星期四

若只單純變更aspx,不需重新編譯發行網站

第一行部分修改

CodeFile="aspname.aspx.vb" Inherits="yufoadmin"

改成

inherits="aspname, App_Web_xxxxxxxx"

xxxxxxx 表示為網站根目錄[bin]下的檔案,以App_Web_亂數.dll的檔名呈現

可能會有一個以上,所以要選對

imageimage

2016年3月30日 星期三

佈置網站出現無法載入檔案組件

(轉載自:http://jimmy0222.pixnet.net/blog/post/36120777-%E7%84%A1%E6%B3%95%E8%BC%89%E5%85%A5%E6%AA%94%E6%A1%88%E6%88%96%E7%B5%84%E4%BB%B6'xxx'%E6%88%96%E5%85%B6%E7%9B%B8%E4%BE%9D%E6%80%A7%E7%9A%84%E5%85%B6%E4%B8%AD%E4%B9%8B)

最近在佈署專案時遇到了這個問題,為了避免忘記,作個筆記。

未命名.png

因為原本在其他電腦可以正常運作的網站架在風的電腦就掛掉了,
所以組件本身應該是正常的,try了一些設定後才知道,
原來是因為風的電腦是64bit,而這library是32bit的dll,所以載入時會錯誤!!

解決方法有幾種:

1. 如果有原始碼,就重新編譯就好。(廢話!!)
2. 如果因為種種原因無法重新編譯,那就要去IIS中設定啟用32位元應用程式。
  位置為:IIS -> 應用程式集區 -> 選擇作用中的AppPool -> 進階設定 -> 「啟用32位元應用程式」。

2011-08-25_142701.png

無法發行本機網站

錯誤: 無法建立網站 'http://127.0.0.1/'。若要存取本機 IIS 網站,您必須安裝下列 IIS 元件:

      IIS 6 Metabase 和 IIS 6 設定相容性
      ASP.NET
      Windows 驗證

此外,您必須在系統管理員帳戶的內容中執行 Visual Studio。

如需詳細資訊,請按 F1。
========== 組建: 2 成功或最新狀態、0 失敗、0 略過 ==========
========== 發行: 0 成功、1 失敗、0 略過 ==========

若要存取wwwroot的檔案設定

imageimage

Compilation Error

今日發行aspx網站後發現網站無法開啟,經測試後是所有的aspx程式都無法執行,等了一段時間後,該網頁出現錯誤訊息如下:

 

Server Error in '/yufonew' Application.

Compilation Error

Description: An error occurred during the compilation of a resource required to service this request. Please review the following specific error details and modify your source code appropriately.
Compiler Error Message: BC31007: Unable to open module file 'C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files\yufonew\0782566d\700ef1d8\App_Web_1.aspx.cdcab7d2.zdehka3v.0.vb': System Error &Hc0000005& (Visual Basic internal compiler error)
Source Error:

[No relevant source lines]

Source File: C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files\yufonew\0782566d\700ef1d8\App_Web_1.aspx.cdcab7d2.zdehka3v.0.vb :    Line: 0

Show Detailed Compiler Output:


Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.1

解決方式:

1.把IIS管理員中的 “DefaultAppPool"->內容->身份識別,先改成"本機系統"

2.再次執行該 .aspx

3.改回原來的"網路服務"

imageimage

2016年3月21日 星期一

ASP.NET 網站架構模式速談(轉)

(文章來源:http://www.kangting.tw/2011/06/aspnet.html)
ASP.NET 網站架構模式速談

ASP.NET彈性相當大,從個人小網站到超大型全球性網路服務,只要有錢有人都可以開發的出來,要具備這麼強大的能力,她的複雜度是可想而知的,不過正因為彈性,對於入門者或是有經驗的開發人員,都可以在使用 ASP.NET 的學習與開發過程中獲得滿足,無論是成就感或是滿足感,甚至賺到錢的飽足感。
這裏分享一下自己的 ASP.NET 經驗,從簡單到複雜,快速的來看看ASP.NET 幾種開發設計的架構模式。

  • 最簡單

以這種模式建構網站最簡單,拉好控制項,完成設定,寫一些程式碼,一個網站就完成了,這是吸引初學者投入 ASP.NET 最有效的方式,也因此寫書時最喜歡拿這個炫耀給讀者看,證明一般人不需要多辛苦就可以成為一名 ASP.NET 網站程式設計師,帶大家一起跳火坑。

  • 稍微像樣的模型

一旦開始真正下海開發 ASP.NET 網站,你就會發現用最簡單的方式來開發行不通的,然後會嘗試將其中一些程式碼切割出來,程式量就開始大了起來,不過還算單純,只要學好 C# ,會設計類別就不會有太大的問題。

  • 像樣不夠還要好維護

從網頁抽離出來的程式碼愈來愈多,接下來會就變得很難維護,在這種情形下,針對這些程式碼,再進一步作切割的動作,而最明快的作法是直接分成兩種,一種是與資料庫直接存取有關的程式碼,也就是與 CRUD(新增、查詢、修改、刪除)功能有關的程式再抽離出來,這一堆程式碼集中在一起變成資料層,剩下的就是邏輯層,邏輯層不牽涉資料的存取,重點放在提供網站各種運算服務邏輯所需的程式碼。

  • 彈性是大型程式設計的真理

網站規模一旦開始成長,就必須考慮到彈性的問題,特別是資料的抽換與擴充,要達到這個目的當然就從資料存取的相關程式碼開刀,至於怎麼下刀,一個很簡單的原則,不要直接存取資料庫,再建立一個虛擬層對應至資料庫,然後再次抽離包含 CRUD 的程式碼,只針對這層虛擬層進行存取,而關於底層資料結構的變動,則直接由這一層虛擬層來負責。

  • 不要讓彈性成為效率的殺手

一般來說,網站成長到需要建立對應資料庫的虛擬層,通常已經很大了,而其中的維護工作相當費力,當然很厲害的台灣老板還是可以用非常精簡的人力進行開發維護的工作,苦命工程師們如果不想爆肝只有兩條路,一是老板增加人力,當然這是只是理論,原理很簡單卻窒礙難行,另外一條路就是從架構上再動手腳,以工具取代人工維護虛擬層運作,因此網站進一步導入 ORM 技術,也就是 Entity Framework。

  • 面子裏子都要
內涵有了,要吸引人最快的方式當然就是一張漂亮的臉蛋,漂亮也不見得成得了巨星,想要影史留名,朝演技派前進是必經之路,ASP.NET 網頁儘管可以作得很漂亮,但就是缺少了生動的靈魂,所以 Silverlight 、 Flash 就這麼進駐為單純的網頁改頭換面。
  • 說好的溝通呢

當系統發展到這裏,該追求的維護效率與開發彈性也都差不多了,只是系統膨脹到這種規模無可避免的,接下來就會產生溝通的問題,從伺服器資料庫到最前端的網頁介面,資料不可能如同一開始只有兩層時,直接在兩端來回傳送,因此進一步導入了各種溝通的機制,Web 服務、WCF 等技術根據需求被融入設計當中。
沒有最完美的架構,只有不斷演進的設計,網站就如同一個巨大的有機體,只要運作的一天,就會有維護與改進的需求,所以建構網站的技術一再的翻新,有用的沒有的技術不斷的出現,這是一條沒有盡頭的漫漫長路,所以認命吧,直到真正退休的一刻,學習都不會停止。

2016年3月19日 星期六

為什麼飯店都要放 4 個枕頭,90%的人都不知道...

為什麼飯店都要放 4 個枕頭,90%的人都不知道...

(示意圖:帝京酒店)

為什麼酒店要放 4個枕頭?

99%的人都不知道!

絕大多數人睡覺都用枕頭,要怎麼“枕”才無憂?

假如你也不知道原因,接下去看看...

(贊助商連結...)

古人說“高枕無憂”,
但現代醫學認為,枕頭太高或太低,
對頸椎都不好,墊錯位置更會出問題,
短期可能酸痛不舒服,長期則難逃挨刀大手術。
還有很多人習慣不墊枕頭,
睡覺時頭會向後仰,
頸椎承受的壓力比向前仰時還高出一倍,
長期下來,一定會出問題。

看完下圖和解說,
你就明白了為什麼酒店通常都要放4個枕頭:

枕頭的高度要適中,最重要是 舒緩脊椎壓力

(一)下巴應該保持水平

睡眠時如何正確的墊枕頭非常重要,
枕頭一定要墊到脖子處。
大家可自我測試,當躺下時,
下巴最低處若朝天,

就表示枕頭太低,
若下巴往下壓,
即枕頭太高,
下巴應該保持水平,
才是舒服且正確的枕頭高度。


(二)少睡硬板床

睡眠佔人生的三分之一時間,
姿勢不可不慎。
像有些家長以為讓孩子睡硬板床,
骨頭才會長得正。

其實人體臀部、腰部、肩膀三處的肉多少不同,
硬板床會讓身體曲線處不能貼到床面,
以致不能放鬆休息,不舒服也不健康。


(三)隨年紀調整枕頭高低

還有很多人習慣不墊枕頭,
睡覺時頭會向後仰,
頸椎承受的壓力比向前仰時還高出一倍,
長期下來,一定會出問題。

至於枕頭的高低,年輕人可稍低,
年紀大後要稍高些,
因為頸椎的柔軟度會隨年齡改變,
愈老愈僵硬,就需要更多的支持。


(四)避免趴睡

平睡(仰姿)時,
枕頭要剛好從整個頭部一直墊到脖子,
不能墊到肩膀,更不能只墊到後腦一半之處,
膝下最好安置一個小枕頭;
側睡時高度要加高一倍,
兩膝間也要夾個小枕頭;

趴睡最好避免,
因為頸椎會承受過大壓力;
起床時則要記得先側姿,
手扶著起來,再下床,
不要直接仰臥著就坐直起身。

不論姿勢再怎麼正確,
固定太久都不宜,
久了一定要換一換,
睡覺要翻身,
坐久要站起來動一動,
脊椎才能保養好。

現在清楚 枕頭的正確用處了,

別再睡錯姿勢,才能睡得又香又甜喔~

2016年3月16日 星期三

vs2008的設計檢視頁面不見時,還原方法(轉)

vs2008的設計檢視頁面不見時,還原方法

摘要:vs2008的設計檢視頁面不見時,還原方法

當vs2010移掉了,若發現vs2008出現一些問題時,例如aspx網頁

無法使用設計檢視畫面時,可以使用下列方式,就可還原

1.運行VS2008的 cmd視窗,

2.在彈出的命令行Cmd中輸入Devenv/ResetSkipPkgs

3. 注意輸入命令行之前,最好將打開的的VS關閉。

4.輸入以上命令後, VS會重新啟動,即可解決問題。

以上先記下來,若以後不見了,可以再用些方法復原。

原文:https://dotblogs.com.tw/yangxinde/2010/10/18/18421

2016年3月15日 星期二

ASP.NET 使用資料庫動態產生功能表(Menu)

網頁內容如下:

<%@ Master Language="VB" CodeFile="MasterPage.master.vb" Inherits="MasterPage" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <link href="css/jquery.mcdropdown.css" rel="stylesheet" type="text/css" />
    <script src="Scripts/jquery-1.4.1-vsdoc.js" type="text/javascript"></script>
    <script src="Scripts/jquery-1.4.1.js" type="text/javascript"></script>
    <style type="text/css">
        .menu
        {
            width: 913px;
            font-family: verdana, Segoe UI;
            margin: 0 auto;
            border: 1px solid #B34C00;
            border-radius: 4px;
        }
        .menu ul
        {
            padding: 10px;
            background-color: #FF6600;
            float: left;
            margin: 0px;
            list-style: none;
        }
        .menu ul li        {
            display
inline-block;
            float: left;
            position: relative;
            cursor: pointer;
        }
        .menu ul li a        {
            cursor:
ointer;
            display: block;
            padding: 10px;
            float: left;
            color: #fff;
            text-decoration: none;
        }
        .menu ul li ul
        {
            display: none;
            margin-top: 10px;
        }
        .menu ul li:hover ul
        {
            display: block;
            width: 200px;
            position: absolute;
            left: 0px;
            top: 25px;
            background: #FF6600;
            border: 1px solid #B34C00;
            border-top: none;
            color: #fff;
        }
        .menu ul li:hover ul li
        {
            padding: 5px;
            float: none;
            display: block;
        }
        .menu ul li:hover ul li a
        {
            padding: 5px;
        }
    </style>
</head>
<body>
    <form id="form1" runat="server">
    <div class="menu">
        <asp:Panel ID="Panel1" runat="server" Width="913px" Style="margin: 0px">
        </asp:Panel>
    </div>
    </form>
    <p>
    </p>
</body>
</html>

程式內容如下:


Imports System.Collections.Generic
Imports System.Linq
Imports System.Web
Imports System.Web.UI
Imports System.Web.UI.WebControls
Imports System.Web.UI.HtmlControls
Imports System.Data.SqlClient
Imports System.Data

Public Partial Class _Default
    Inherits System.Web.UI.Page
    Private con As New SqlConnection("Data Source=(local);Initial Catalog=master;uid=sa; pwd=Micr0s0ft")
    Protected Sub Page_Load(sender As Object, e As EventArgs)
        Dim da As New SqlDataAdapter("Select TechnologyID, TechnologyName, TechnologyURL from Technology", con)
        Dim dttc As New DataTable()
        da.Fill(dttc)
        Dim main As HtmlGenericControl = UList("Menuid", "menu")
        For Each row As DataRow In dttc.Rows
            da = New SqlDataAdapter("select TechnologyCategoryID,TechnologyCategoryName,TechnologyCategoryURL from TechnologyCategory where TechnologyID=" + row("TechnologyID").ToString(), con)
            Dim dtDist As New DataTable()
            da.Fill(dtDist)
            If dtDist.Rows.Count > 0 Then
                Dim sub_menu As HtmlGenericControl = LIList(row("TechnologyName").ToString(), row("TechnologyID").ToString(), row("TechnologyURL").ToString())
                Dim ul As New HtmlGenericControl("ul")
                For Each r As DataRow In dtDist.Rows
                    ul.Controls.Add(LIList(r("TechnologyCategoryName").ToString(), r("TechnologyCategoryID").ToString(), r("TechnologyCategoryURL").ToString()))
                Next
                sub_menu.Controls.Add(ul)
                main.Controls.Add(sub_menu)
            Else
                main.Controls.Add(LIList(row("TechnologyName").ToString(), row("TechnologyID").ToString(), row("TechnologyURL").ToString()))
            End If
        Next
        Panel1.Controls.Add(main)
    End Sub
    Private Function UList(id As String, cssClass As String) As HtmlGenericControl
        Dim ul As New HtmlGenericControl("ul")
        ul.ID = id
        ul.Attributes.Add("class", cssClass)
        Return ul
    End Function
    Private Function LIList(innerHtml As String, rel As String, url As String) As HtmlGenericControl
        Dim li As New HtmlGenericControl("li")
        li.Attributes.Add("rel", rel)
        li.InnerHtml = (Convert.ToString("<a href=" + String.Format("
http://{0}", url) + ">") & innerHtml) + "</a>"
        Return li
    End Function
End Class

nginx ddos攻擊測試Enter a post title

nginx ddos攻擊測試

Posted on 2014 年 05 月 17 日, 05:06:15 By Tony

使用的軟體是Http attack version 3.6 設定如圖

image

image

nginx.config的設定

image

修改網站預設的設定檔default如下

image

限制每個ip超過20個連線數,然後顯示503的錯誤畫面 測試壓測的情況查詢大約19xx連線

連線數

測試情況大量連線的ip會出現503的頁面,但另一個ip連線仍然是正常的

image

主要用到的是Nginx中提供的兩個limit模組:

ngx_http_limit_conn_module  

ngx_http_limit_req_module

一、白名單

首先這兩個模組是支援白名單的,就是可能有某些IP位址,我們是不需要進行限制的,比如可能會是搜尋引擎啦什麼的或者自己的IP,因此需要設置一個白名單,不需要的可跳過本步。具體方法:

在HTTP段中插入如下格式內容,聲明白名單IP

http{

.......

geo $limited{

default 1;

#公司    

119.123.5.0/24 0;

}

.........

}

geo指令定義了一個白名單$limited變數,預設值為1,如果用戶端IP在上面的範圍內,$limited的值為0。

然後緊跟在上面內容後使用map指令映射搜尋引擎用戶端的ip為空串,如果不是白名單IP就顯示本身真實的IP,這樣搜尋引擎iIP就不能存到limit模組的記憶體session中,所以不會限制白名單的IP訪問。

map $limited $limit {

1 $binary_remote_addr;

0 "";

}

二、訪問頻率限制

訪問頻率限制使用到的是ngx_http_limit_req_module,需要在兩個地方配置,首先在HTTP段中,聲明好這個模組一些參數,如果有設置白名單,設置如下

http{

...

limit_req_zone $limit zone=one:10m rate=20r/m; ##平均20r/m 每分鐘20個請求    

...

}

如果沒有配置白名單,所有來訪IP都會限制,配置如下

http{

...

limit_req_zone $binary_remote_addr zone=one:10m rate=20r/m; ##平均20r/m 每分鐘20個請求  

...

}

解釋一下上面的參數,第一個代表的是需要限制的ip群,這個很好理解,第二個zone=one表示這個limit_zone的名字叫做one,後面的使用中可以用這個one來進行指代,後面的15m,代表為這個zone分配10m的記憶體,1m可以保存16000的$binary_remote_addr。最後一個是頻率,如果要按秒來算可以設置20r/s這樣。

最後是配置到Nginx的php的解析段

location ~ \.php$ {

...

limit_req zone=one burst=5 nodelay;

...

}

指定了使用名字為one的zone,然後緩衝佇列為5,無延遲,如果不設置無延遲,訪問會卡住。

三、訪問連接限制

訪問連接限制使用到的是ngx_http_limit_conn_module,也是需要在兩個地方配置,首先在HTTP段中,聲明好這個模組一些參數,如果有設置白名單,設置如下

http{

...

limit_conn_zone $limit zone=addr:10m;

...

}

如果沒有配置白名單,所有來訪IP都會限制,配置如下

view sourceprint?http{

...

limit_conn_zone $binary_remote_addr zone=addr:10m;

...

}

參數的意思跟上面的差不多也就不多解釋了。後面的就是在server段中進行設置了,可以具體到某個目錄什麼的了

server {

location /download/ {

limit_conn addr 5;

}

大功告成,打完收工,記得要nginx -s reload一下

原文:http://netsecurity.51cto.com/art/201306/400210.htm

用TfGen 產生流量測試你的頻寬

用TfGen 產生流量測試你的頻寬

Posted on 2014 年 05 月 17 日, 05:22:29 By Tony

tfgen是一款優秀的網路設備,線路或者伺服器最大流量的壓力測試軟體
測試交換機或線路的方法:::
1.線路兩端或交換機上的兩台PC之間配同一個子網的ip位址(路由器的話你應該知道如何把網路設通)
2.兩台交換機關閉防火牆,並允許ping
3.兩台pc都打開tfGen, 設置目標位址以及流量大小, 互相發包
4.兩台pc都裝上類似DuMeter的軟體觀測即時流量
5.兩台pc之間再互相ping, 看延時和丟包率
就可以完美的檢查線路或交換機最大頻寬或者檢查線路的健康程度.

image

下載檔案:http://hack.twgg.org/phpbb/viewtopic.php?f=44&t=661&sid=421c89c4d25d4592435ad0faf7802163

2016年3月14日 星期一

網路壓力測試工具Iperf(轉自-江湖一片葉)

IT學習筆記~包含了網路、資安、系統等的心得與筆記~

2009年12月29日 星期二

網路壓力測試工具Iperf

最近公司代理了Firewall產品,產品有VPN與NAT功能,特別是結合在一起時,效能問題倍受疑慮。
還好我們客戶用了一個工具來檢視之後(雖然是震憾教育),但學到很多^^
這個工具就是Iperf,可以在這個地方下載:
http://www.noc.ucf.edu/Tools/Iperf/iperf.exe
有Linux版與Windows版,我們以Windows版本為例,簡單說明使用方式與參數。
使用方式:
這於這個工具是Server Client架構,所以需要在兩台電腦上測試,中間經過什麼東西,
就是想測試效能的設備,比如Firewall,VPN,SSL-VPN,Wireless AP...,所以先找兩台電腦,
一台當Server,一台當Client:
Step.1 下載: 到http://www.noc.ucf.edu/Tools/Iperf/iperf.exe 將程式下載,之後將程式copy到想存放的地方,比如說D:/之下。
Step.2 開啟dos視窗: 執行->cmd
Step.3 執行Server: 從comandline輸入 D:/iperf.exe -s (其它參數)
Step.4 執行Client: 從comandline輸入 D:/iperf.exe -c serverip (其它參數)
參數參考:
Client端/Server端 都可用的參數:
-f, --format [kmKM] 以什麼方式顯示: Kbits, Mbits, KBytes, MBytes
-i, --interval # 每隔多少秒顯更新頻寬資訊
-l, --len #[KM] 設定讀寫的緩衝區長度 (預設 8 KB)
-m, --print_mss 顯示TCP/IP標頭的MTU(最大segment)大小
-o, --output 將report或錯誤訊息輸出到這個檔案裡
-p, --port # 設定server與client的溝通port
-u, --udp 使用UDP代替TCP測試
-w, --window #[KM] TCP的window大小(socket buffer size)
-B, --bind bind某,結合某介面或multicast的位址用
-C, --compatibility 與舊版本比較用,不送任何封包
-M, --mss # 設定TCP最大segment大小 (MTU - 40 bytes)
-N, --nodelay 設定無TCP延遲,取消Nagle's演算法
-V, --IPv6Version 設定為IPv6格式
Server端參數:
-s, --server 執行Server模式
-D, --daemon 執行Server背景模式
-R, --remove 移除服務
Client 端參數:
-b, --bandwidth #[KM] UDP參數,以bits/sec傳送(預設 1 Mbit/sec, implies -u)
-c, --client 執行Client模式,並連線到Server的IP:
-d, --dualtest 同時執行雙向的模擬測試
-n, --num #[KM] 傳輸多少bytes封包 (取代-t)
-r, --tradeoff 單獨執行雙向的模擬測試
-t, --time # 每隔幾秒傳輸一次 (預設10 秒)
-F, --fileinput 選取某檔案傳輸測試
-I, --stdin 將鍵盤輸入的資料進行傳輸測試
-L, --listenport # 進行雙測試時,接收回應的port
-P, --parallel # 同時執行多少個Client連線
-T, --ttl # 進行Multicat的time-to-live(預設為 1)
其它參數:
-h, --help 顯示help 資訊
-v, --version 顯示版本
範例:
1. Server端:

iperf -s -u -i 1 -l 1024 -p 5001

設置Server只接收UDP封包,每隔1秒更新顯示一次,進行讀寫的緩衝區大小為1020k,進行監聽的port為5001
2.Client端:
iperf -c 192.168.4.88 -u -i 1 -l 1024 -p 5001 -t 200 -b 1m

設置Client端,連向ServerIP為192.168.4.88,以UDP傳送,每隔1秒更新顯示一次,進行寫的緩衝區大小為1020k,從5001port丟封包出去,每隔200秒丟一次1M的封包

Ubuntu 系統目錄 (資料夾) 介紹(轉)

2012-12-17

Ubuntu 系統目錄 (資料夾) 介紹

標籤: 檔案 FHS Linux Ubuntu

阿舍玩 Linux 和 Ubuntu 不少年了,但是,始終都沒有好好的去瞭解 Linux / Ubuntu 的各個資料夾的用途,尤其是近來的 Ubuntu 已經不用像以前那樣要自己分割硬碟空間了,所以,阿舍就更加的給它沒有去注意哩 ! 不過,心中還是覺得應該是要好好的瞭解一下,不然,就覺得好像沒有很厲害的樣子哩 ! 呵呵 !

每一個資料夾幾乎都有特定用途


今天想了一下,好吧 ! 就花點時間來看一下吧 ! 應該不是什麼難事,然後,就一邊看一邊把它寫下來,這樣,阿舍以後自己要查的時候,也會方便些哩 ! 以下就是 Ubuntu 的檔案結構,其實,就是各個內建資料夾的用途哩 !
/
這是 Linux / Ubuntu 系統的根目錄,Linux / Ubuntu 系統上的東西就是由這裡開始的。
/bin
這個資料夾存放 Linux / Ubuntu 系統啟動和運行時會使用到的執行檔。
/boot
這個資料夾就是 Linux 核心和 RAM disk Image 存放的地方,同時,也是啟動選單設定檔存放的地方。
/dev
所有 Linux 核心有認識的設備和裝置的資訊都會放在這個資料夾。
/etc
所有會影響到系統運作的設定檔都會放到這個資料夾。
/home
系統上的所有使用者的家目錄都會放在這個資料夾下的資料夾。
/lib
這個資料夾是存放 Linux / Ubuntu 系統會使用到的程式庫及核心模組,使用 Ubuntu 的 64bit 的版本時,還會出現 lib32 和 lib64 二個資料夾。
/lost+found
如果你的 Ubuntu 的檔案系統不幸掛掉了,然後,在回復後,所有無法正確回復的資料就會被放到這個資料夾。
/media
做為像隨身碟或 CD 之類的可移除裝置的掛載點 (Mount Point)。
/mnt
早期的 Linux 版本所使用的可移除裝置的掛載點 (Mount Point),在 Ubuntu 上用來專門做為掛載暫時性的檔案系統用。
/opt
無法透過套件安裝的軟體會將程式安裝在這個資料夾。
/proc
這是一個虛擬的檔案系統,裡面放的是系統正在運行的程序 (Process),Linux 核心透過這個資料夾裡的檔案來傳送訊息給執行中的程序。
/root
這是 root 帳號的家目錄。
/sbin
這個資料夾裡的檔案大多是超級使用者或 root 可以使用的管理用的指令程式。
/tmp
系統、軟體和程式用來存放暫時性檔案的地方。
/usr/bin
不論是 Ubuntu 預載的或是使用者自己安裝的程式和軟體,都會被安裝到這個資料夾,所以,這個資料夾裡的檔案數量通常不會太少哩 !
/usr/lib
這個資料夾是用來存放 /usr/bin 的程式會用到的程式庫。
/usr/local
通常,透過自己編譯和安裝的程式會被放到這個資料夾下哩 !
/usr/share
這個資料夾是用來存放 /usr/bin 的程式的共用資料。
/usr/share/doc
所有軟體的說明文件會放在這裡。
/var
用來存放系統上的動態資料,像是網站、日誌 (Log) 和郵件這類型的資料。
/selinux
這個資料夾是用來存放 SELinux 套件的,不過,預設並沒有安裝,所以,是空的。
/srv
為了相容於 FHS 標準,所以,會需要把像是架網站或 FTP Server 等的網路服務改放到這個資料夾哩 !
/sys
這個資料夾和 /proc 一樣是個虛擬的檔案系統,用途是提供目前系統的各項資訊。
以上是阿舍寫的說明,如果有錯,再請告知一下囉 ! 多謝!^^=
參考資料:
https://wiki.ubuntu.com/SELinux
http://ubuntuforums.org/showthread.php?t=1425726
http://www.ubuntugeek.com/linux-or-ubuntu-directory-structure.html
https://help.ubuntu.com/community/LinuxFilesystemTreeOverview
https://lists.ubuntu.com/archives/ubuntu-users/2009-March/176259.html
https://help.ubuntu.com/12.10/installation-guide/powerpc/directory-tree.html
[+] Ubuntu 指令新手會用到的35個技法 - 這是以阿舍的使用經驗編寫出來的電子書,三天內應該就看的完,學的起來哩 ! 有空就參考一下囉 ! ... ^^=

Read more: http://www.arthurtoday.com/2012/12/ubuntu-file-system-tree-directories.html#ixzz42voxFovn

出國旅行 會這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!"

執行程式碼之後的結果:

  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 
金錢

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.