Archive for the ‘Uncategorized’ Category

Posted: 2017 年 11 月 30 日 in Uncategorized

給OOP初學者的建議:

先搞懂「資料跟行為在一起」就好,其它的慢慢來

初學者接觸OOP,幾乎都會有以下疑惑:
我到底為什麼要學OOP?OOP解決了什麼問題?書上這些範例就算不用OOP也寫得出來吧?
然後覺得「繼承」、「多型」、「介面」、「抽象類別」等等的名詞很難,覺得OOP很難。
其實這些名詞雖然重要,但對新手來說,本來就很難在一開始就搞懂。
建議先搞懂「資料跟行為在一起」是什麼,以及它的好處在哪,就可以了,其它的慢慢來。
什麼叫做「資料跟行為在一起」?
假設我們在開發一個「中英文互助學習網」,鼓勵中文人士與英語人士登入討論。
這個系統的貼文、留言功能會顯示「發文日期」。
發文日期要根據使用者的註冊身份(台灣人、英語人士)顯示不同格式(台灣格式、西方格式)。
下面就以這個日期格式的功能舉例說明「資料跟行為在一起」是什麼意思。
作法一:直接硬寫(不OOP、資料跟行為混在一起)
初學者通常會用最簡單、也最直覺的作法,直接硬寫出來,像這樣:
<? php

# 假設資料庫取出來的發文日期長這樣
$postDate = '2016-06-02';

if (/* 判斷是否顯示台灣格式 */) {
# 轉換成這樣 2016.6.2
$arr = explode('-', $postDate);
$year = $arr[0];
$month = $arr[1];
$day = $arr[2];
echo "$year.$month.$day";
} else { // 西方格式
# 轉換成這樣 6/2/2016
$arr = explode('-', $postDate);
$year = $arr[0];
$month = $arr[1];
$day = $arr[2];
echo "$month/$day/$year";
}

這種寫法的資料(日期)跟行為(轉換成各種格式)混在一起。
它的優點是寫起來很簡單,缺點則有兩個:
* 日期格式的邏輯會重複出現在很多地方,整段code會到處重複出現
* 整段code大概會塞在

或是的裡面,導致它跟HTML混在一起,很亂
作法二:自訂函數(不OOP、資料跟行為沒混在一起)
為了解決作法一遇到的問題,聰明的初學者很快就想到可以用「自訂函數」!就像這樣:
<? php
function localFormat($date){
$arr = explode(‘-‘, $date);
$year = $arr[0];
$month = $arr[1];
$day = $arr[2];
return “$year.$month.$day";
}

function englishFormat($date)
{
$arr = explode(‘-‘, $date);
$year = $arr[0];
$month = $arr[1];
$day = $arr[2];
return “$month/$day/$year";
}

$postDate = ‘2016-06-02’; # 假設資料庫取出來的發文日期長這樣

if (/* 判斷是否為台灣人身份 */) {
echo localFormat($postDate);
} else { // 英語人士身份
echo englishFormat($postDate);
}

這種寫法將行為(轉換成各種格式)用自訂函數給獨立出來,也大幅改善了作法一遇到的問題。
對小型的網頁程式來說,這招非常好用,不但開發快速、簡單,還漂亮地將資料跟行為拆開。
但是程式規模變大之後,為了將各種行為拆出來,會寫出很多自訂函數,類似這樣:
<? php
function localFormat($param)
{
// blah blah …
}
function englishFormat($param)
{
// blah blah …
}
function someTask($param)
{
// blah blah …
}
function anotherTask($param)
{
// blah blah …
}
function otherTask($param)
{
// blah blah …
}
//…

於是又衍生出三個問題:
1. 像localFormat、englishFormat這樣的函數名稱意義模糊,看不出是處理日期、人名,還是什麼東西的格式
2. 這些自訂函數各有不同的行為,全部放在一起顯得很亂,應該要想辦法分類、整理這些函數
3. 像localFormat、englishFormat這樣的函數,只吃特定格式的參數,最好能跟某種資料的形式綁在一起,以後要改程式時,能讓相關的資料跟行為一起被看到
問題1很好解決,只要替函數名稱加前綴字變成dateLocalFormat、dateEnglishFormat就行了。
問題2也很好解決,只要多開幾個檔案,把相關的函數放進同一個檔案就行了。
問題3就很棘手,資料跟行為拆開之後,如何在概念上又找方法整理在一起?
作法三:使用class(OOP、資料跟行為在一起)
正是這些處理資料、整理行為的問題,導致了OOP的誕生:
<? php
class Date
{
public $year;
public $month;
public $day;
public function __construct($date)
{

$arr = explode(‘-‘, $date);
$this->year = $arr[0];
$this->month = $arr[1];
$this->day = $arr[2];

}

public function localFormat()
{
return $this->year . ‘.’ .$this->month . ‘.’ . $this->day;
}

public function englishFormat()
{
return $this->month . ‘/’ .$this->day . ‘/’ . $this->year;
}
}

$postDate = ‘2016-06-02’; # 假設資料庫取出來的發文日期長這樣

$date = new Date($postDate);

if (/* 判斷是否為台灣人身份 */) {
echo $date->localFormat();
} else { // 英語人士身份
echo $date->englishFormat();
}

OOP的寫法,一次解決了前述三個問題:
問題1 => 現在從類別名稱就可以知道底下方法的意義了
問題2 => 現在相關的函數都整理進同一個類別底下成為方法了
問題3 => 現在資料的形式都統一在constructor處理一次,之後不管新增多少方法都不用處理資料了
這就是所謂的「資料跟行為在一起」,也正是OOP的核心概念。
利用這種方式整理程式碼、寫出一個又一個的類別,可以大幅提昇程式碼的品質。
結論
上述的作法一跟作法二並沒那麼糟糕,但確實會帶來一些問題。
對於小型的網頁程式來說,可能還算夠用。
但是隨著程式規模變大,如果將概念上相關的資料跟行為整理在一起,會很有幫助。
實務上也可以先從作法二開始寫起,直到發現某些資料跟行為關係密切,再拉出來整理成類別即可。
至於很多OOP教學會提到的「繼承」、「多型」、「介面」、「抽象類別」等等名詞,一時搞不懂沒有關係,你可能實務上也暫時用不到。之後找時間慢慢搞懂它們的用途就好。
光是知道「將資料跟行為放在一起」的技巧,就能夠開始寫OOP程式碼了。

正則表達式 範例

Posted: 2017 年 09 月 13 日 in Uncategorized

幾種基本的數字正則表達式

只能輸入1個數字
表達式 ^/d$
描述 匹配一個數字
匹配的例子 0,1,2,3
不匹配的例子
只能輸入n個數字 
表達式 ^/d{n}$ 例如^/d{8}$
描述 匹配8個數字
匹配的例子 12345678,22223334,12344321
不匹配的例子
只能輸入至少n個數字 
表達式 ^/d{n,}$ 例如^/d{8,}$
描述 匹配最少n個數字
匹配的例子 12345678,123456789,12344321
不匹配的例子
只能輸入m到n個數字 
表達式 ^/d{m,n}$ 例如^/d{7,8}$
描述 匹配m到n個數字
匹配的例子 12345678,1234567
不匹配的例子 123456,123456789
只能輸入數字 
表達式 ^[0-9]*$
描述 匹配任意個數字
匹配的例子 12345678,1234567
不匹配的例子 E,
只能輸入某個區間數字 
表達式 ^[12-15]$
描述 匹配某個區間的數字
匹配的例子 12,13,14,15
不匹配的例子
只能輸入0和非0打頭的數字 
表達式 ^(0|[1-9][0-9]*)$
描述 可以為0,第一個數字不能為0,數字中可以有0
匹配的例子 12,10,101,100
不匹配的例子 01,
只能輸入實數 
表達式 ^[-+]?/d+(/./d+)?$
描述 匹配實數
匹配的例子 18,+3.14,-9.90
不匹配的例子 .6,33s,67-99
只能輸入n位小數的正實數 
表達式 ^[0-9]+(.[0-9]{n})?$以^[0-9]+(.[0-9]{2})?$為例
描述 匹配n位小數的正實數
匹配的例子 2.22
不匹配的例子 2.222,-2.22,
只能輸入mn位小數的正實數 
表達式 ^[0-9]+(.[0-9]{m,n})?$以^[0-9]+(.[0-9]{1,2})?$為例
描述 匹配m到n位小數的正實數
匹配的例子 2.22,2.2
不匹配的例子 2.222,-2.2222,
只能輸入非0的正整數 
表達式 ^/+?[1-9][0-9]*$
描述 匹配非0的正整數
匹配的例子 2,23,234
不匹配的例子 0,-4,
只能輸入非0的負整數 
表達式 ^/-[1-9][0-9]*$
描述 匹配非0的負整數
匹配的例子 -2,-23,-234
不匹配的例子 0,4,
只能輸入n個字符 
表達式 ^.{n}$ 以^.{4}$為例
描述 匹配n個字符,注意漢字只算1個字符
匹配的例子 1234,12we,123清,清清月兒
不匹配的例子 0,123,123www,
只能輸入英文字符 
表達式 ^.[A-Za-z]+$為例
描述 匹配英文字符,大小寫任意
匹配的例子 Asp,WWW,
不匹配的例子 0,123,123www,
只能輸入大寫英文字符 
表達式 ^.[AZ]+$為例
描述 匹配英文大寫字符
匹配的例子 NET,WWW,
不匹配的例子 0,123,123www,
只能輸入小寫英文字符 
表達式 ^.[az]+$為例
描述 匹配英文大寫字符
匹配的例子 asp,csdn
不匹配的例子 0,NET,WWW,
只能輸入英文字符+數字 
表達式 ^.[A-Za-z0-9]+$為例
描述 匹配英文字符+數字
匹配的例子 1Asp,W1W1W,
不匹配的例子 0,123,123,www,
只能輸入英文字符/數字/下劃線 
表達式 ^/w+$為例
描述 匹配英文字符或數字或下劃線
匹配的例子 1Asp,WWW,12,1_w
不匹配的例子 3#,2-4,w#$,
密碼舉例 
表達式 ^.[a-zA-Z] /w{m,n}$
描述 匹配英文字符開頭的mn位字符且只能數字字母或下劃線
匹配的例子
不匹配的例子
驗證首字母大寫 
表達式 /b[^/Wa-z0-9_][^/WA-Z0-9_]*/b
描述 首字母只能大寫
匹配的例子 Asp,Net
不匹配的例子
驗證網址(帶?id=中文)VS.NET2005無此功能 
表達式 ^http:////([/w-]+(/.[/w-]+)+(//[/w- .///?%&=/u4e00-/u9fa5]*)?) ?$
描述 驗證帶?id=中文
匹配的例子 ,
http://blog.csdn.net?id=清清月兒
不匹配的例子
驗證漢字 
表達式 ^[/u4e00-/u9fa5]{0,}$
描述 只能漢字
匹配的例子 清清月兒
不匹配的例子
驗證QQ號 
表達式 [0-9]{5,9}
描述 5-9位的QQ號
匹配的例子 10000,123456
不匹配的例子 10000w,
驗證電子郵件(驗證MSN號一樣)
表達式 /w+([-+.´]/w+)*@/w+([-.]/w+)*/./w+([-.]/w+)*
描述 注意MSN用非hotmail.com郵箱也可以
匹配的例子 aaa@msn.com
不匹配的例子 111@1.
驗證身份證號(粗驗,最好服務器端調類庫再細驗證) 
表達式 ^[1-9]([0-9]{16}|[0-9]{13})[xX0-9]$
描述
匹配的例子 15或者18位的身份證號,支持帶X的
不匹配的例子
驗證手機號(包含159,不包含小靈通) 
表達式 ^13[0-9]{1}[0-9]{8}|^15[9]{1}[0-9]{8}
描述 包含159的手機號130-139
匹配的例子 139XXXXXXXX
不匹配的例子 140XXXXXXXX,
驗證電話號碼號(很複雜,VS.NET2005給的是錯的)
表達式(不完美) 方案一((/(/d{3}/)|/d{3}-)|(/(/d{4}/)|/d{4}-))?(/d{8}|/ d{7})
方案二(^[0-9]{3,4}/-[0-9]{3,8}$)|(^[0-9]{3,8}$)|( ^/([0-9]{3,4}/)[0-9]{3,8}$)|(^0{0,1}13[0-9]{9}$) 支持手機號但也不完美
描述 上海:02112345678 3+8位
上海:021-12345678
上海:(021)-12345678
上海:(021)12345678
鄭州:03711234567 4+7位
杭州:057112345678 4+8位
還有帶上分機號,國家碼的情況由於情況非常複雜所以不建議前台做100%驗證,到目前為止似乎也沒有誰能寫一個包含所有的類型 如果誰有更好 的驗證電話的請留言,其實有很多情況本身就是矛盾的。
匹配的例子
不匹配的例子
驗證護照 
表達式 (P/d{7})|G/d{8})
描述 驗證P+7個數字和G+8個數字
匹配的例子
不匹配的例子
驗證IP 
表達式 ^(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9 ]{1}|[1-9])/.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}| [1-9]{1}[0-9]{1}|[1-9]|0)/.(25[0-5]|2[0-4][0-9]|[0- 1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)/.(25[0-5]|2 [0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9] )$
描述 驗證IP
匹配的例子 192.168.0.1 222.234.1.4
不匹配的例子
驗證域
表達式 ^[a-zA-Z0-9]+([a-zA-Z0-9/-/.]+)?/.(com|org|net|cn|com.cn|edu.cn|grv.cn |)$
描述 驗證域
匹配的例子 csdn.net baidu.com it.com.cn
不匹配的例子 192.168.0.1
驗證信用卡
表達式 ^((?:4/d{3})|(?:5[1-5]/d{2})|(?:6011)|(?:3[68]/d{2})|( ?:30[012345]/d))[ -]?(/d{4})[ -]?(/d{4})[ -]?(/d{4}|3[4,7]/ d{13})$
描述 驗證VISA卡,萬事達卡,Discover卡,美國運通卡
匹配的例子
不匹配的例子
驗證ISBN 國際標準書號
表達式 ^(/d[- ]*){9}[/dxX]$
描述 驗證ISBN國際標準書號
匹配的例子 7-111-19947-2
不匹配的例子
驗證GUID 全球唯一標識符
表達式 ^[A-Z0-9]{8}-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0- 9]{12}$
描述 格式8-4-4-4-12
匹配的例子 2064d355-c0b9-41d8-9ef7-9d8b26524751
不匹配的例子
驗證文件路徑和擴展名
表達式 ^([a-zA-Z]/:|//)//([^//]+//)*[^//:*?"<>|]+/.txt(l)?$
描述 檢查路徑和文件擴展名
匹配的例子 E:/mo.txt
不匹配的例子 E:/ , mo.doc, E:/mo.doc ,
驗證Html顏色值
表達式 ^#?([af]|[AF]|[0-9]){3}(([af]|[AF]|[0-9]){3})?$
描述 檢查顏色取值
匹配的例子 #FF0000
不匹配的例子

 

php _server

Posted: 2017 年 09 月 13 日 in Uncategorized

網路上抓下來的

$_SERVER[‘PHP_SELF’] #當前正在執行腳本的文件名,與 document root相關。
$_SERVER[‘argv’] #傳遞給該腳本的參數。
$_SERVER[‘argc’] #包含傳遞給程序的命令行參數的個數(如果運行在命令行模式)。
$_SERVER[‘GATEWAY_INTERFACE’] #服務器使用的 CGI 規範的版本。例如,「CGI/1.1」。
$_SERVER[‘SERVER_NAME’] #當前運行腳本所在服務器主機的名稱。
$_SERVER[‘SERVER_SOFTWARE’] #服務器標識的字串,在響應請求時的頭部中給出。
$_SERVER[‘SERVER_PROTOCOL’] #請求頁面時通信協議的名稱和版本。例如,「HTTP/1.0」。
$_SERVER[‘REQUEST_METHOD’] #訪問頁面時的請求方法。例如:「GET」、「HEAD」,「POST」,「PUT」。
$_SERVER[‘QUERY_STRING’] #查詢(query)的字符串。
$_SERVER[‘DOCUMENT_ROOT’] #當前運行腳本所在的文檔根目錄。在服務器配置文件中定義。
$_SERVER[‘HTTP_ACCEPT’] #當前請求的 Accept: 頭部的內容。
$_SERVER[‘HTTP_ACCEPT_CHARSET’] #當前請求的 Accept-Charset: 頭部的內容。例如:「iso-8859-1,*,utf-8」。
$_SERVER[‘HTTP_ACCEPT_ENCODING’] #當前請求的 Accept-Encoding: 頭部的內容。例如:「gzip」。
$_SERVER[‘HTTP_ACCEPT_LANGUAGE’]#當前請求的 Accept-Language: 頭部的內容。例如:「en」。
$_SERVER[‘HTTP_CONNECTION’] #當前請求的 Connection: 頭部的內容。例如:「Keep-Alive」。
$_SERVER[‘HTTP_HOST’] #當前請求的 Host: 頭部的內容。
$_SERVER[‘HTTP_REFERER’] #鏈接到當前頁面的前一頁面的 URL 地址。
$_SERVER[‘HTTP_USER_AGENT’] #當前請求的 User_Agent: 頭部的內容。
$_SERVER[‘REMOTE_ADDR’] #正在瀏覽當前頁面用戶的 IP 地址。
$_SERVER[‘REMOTE_HOST’] #正在瀏覽當前頁面用戶的主機名。
$_SERVER[‘REMOTE_PORT’] #用戶連接到服務器時所使用的端口。
$_SERVER[‘SCRIPT_FILENAME’] #當前執行腳本的絕對路徑名。
$_SERVER[‘SERVER_ADMIN’] #管理員信息
$_SERVER[‘SERVER_PORT’] #服務器所使用的端口
$_SERVER[‘SERVER_SIGNATURE’] #包含服務器版本和虛擬主機名的字符串。
$_SERVER[‘PATH_TRANSLATED’] #當前腳本所在文件系統(不是文檔根目錄)的基本路徑。
$_SERVER[‘SCRIPT_NAME’] #包含當前腳本的路徑。這在頁面需要指向自己時非常有用。
$_SERVER[‘REQUEST_URI’] #訪問此頁面所需的 URI。例如,「/index.html」。
$_SERVER[‘PHP_AUTH_USER’] #當 PHP 運行在 Apache 模塊方式下,並且正在使用 HTTP 認證功能,這個變量便是用戶輸入的用戶名。
$_SERVER[‘PHP_AUTH_PW’] #當 PHP 運行在 Apache 模塊方式下,並且正在使用 HTTP 認證功能,這個變量便是用戶輸入的密碼。
$_SERVER[‘AUTH_TYPE’] #當 PHP 運行在 Apache 模塊方式下,並且正在使用 HTTP 認證功能,這個變量便是認證的類型。