2012年7月30日 星期一

使用Javascript 檢查檔案大小

HTML:


    
    上傳


    
圖片:
Javascript:



轉貼來源:http://www.dotblogs.com.tw/cross/archive/2010/09/21/17840.aspx

2012年7月29日 星期日

PHP 清除快取


 
//變成Function
function nocache_headers() {
@ header('Expires: Thu, 01 Jan 1970 00:00:01 GMT');
@ header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
@ header('Cache-Control: no-cache, must-revalidate, max-age=0');
@ header('Pragma: no-cache');
}
nocache_headers();

2012年7月24日 星期二

curl 登入 xuite (研究中...)

目前還是失敗的.. 還在研究為什麼= =

$url = "http://xuite.net/members/miniLogin.php?final=http://xuite.net";

$login_url = "https://member.xuite.net/HiReg/multiauthentication";
$uid = "uid";
$pw = "pw";

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
$content = curl_exec($ch);
$start=strpos($content,"src")+5;
$end=strpos($content,"'",$start);

$url = substr($content,$start,$end-$start);
curl_setopt($ch, CURLOPT_URL, $url);
$content = curl_exec($ch);
curl_close ($ch); 
// 為了模擬登入時, post 的資料, 所以先取得這些資料
$version = find_input_value("version",$content);
$curl = find_input_value("curl",$content);
$siteid = find_input_value("siteid",$content);
$sessionid = find_input_value("sessionid",$content);
$channelurl = find_input_value("channelurl",$content);
$others = find_input_value("others",$content);
$checksum = find_input_value("checksum",$content);
$service_type = find_input_value("service_type",$content);
$cp_reg_info = find_input_value("cp_reg_info",$content);
$reg_url = find_input_value("reg_url",$content);
$finish_channelurl = find_input_value("finish_channelurl",$content);
$formtype = find_input_value("formtype",$content);
$sso = find_input_value("sso",$content);
$cssurl = find_input_value("cssurl",$content);

$post_data = array(
 "uid"=>$uid,
 "pw"=>$pw,
 "version"=>$version,
 "curl"=>$curl,
 "siteid"=>$siteid,
 "sessionid"=>$sessionid,
 "channelurl"=>$channelurl,
 "others"=>$others,
 "checksum"=>$checksum,
 "service_type"=>$service_type,
 "cp_reg_info"=>$cp_reg_info,
 "reg_url"=>$reg_url,
 "finish_channelurl"=>$finish_channelurl,
 "formtype"=>$formtype,
 "sso"=>$sso,
 "cssurl"=>$cssurl,
);
// var_dump($post_data);

// cURL($url, $header=NULL, $p=NULL)
// 對 login_url 發送剛剛記錄的資料 & 帳號密碼 (記錄cookie)
$a= cURL ($login_url,false,$post_data);
// 因為有使用剛剛記錄 cookie, 所以直接導回 xuite 即可
echo cURL("http://xuite.net", false, null);


function find_input_value($name,$content){
 $start = strpos($content, "name=\"$name");
 $start=strpos($content,"value",$start)+7; // +7 是因為 value=" 長度為7
 $end=strpos($content,"\"",$start);
 $value = substr($content,$start,$end-$start);
 return $value;
}

function cURL($url, $header=NULL, $p=NULL)
{
    $ch = curl_init();
 $cookie_file = './cookie.txt';
    curl_setopt($ch, CURLOPT_HEADER, $header);
    // curl_setopt($ch, CURLOPT_NOBODY, $header);
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
    // curl_setopt($ch, CURLOPT_COOKIE, $cookie);
 // 將 cookie 儲存
    curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_file);
 // 使用這個 cookie
    curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_file);
    curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $p);
    $result = curl_exec($ch);
    if ($result) {
        return $result;
    } else {
        return curl_error($ch);
    }
    curl_close($ch);
}

2012年7月18日 星期三

用PHP+cURL傳送Request (GET,POST或上傳檔案)至另一個網頁

筆記分二大部份:PHP傳送GET、POST、上傳檔案至另一個網址,以及PHP如何接收及處理上傳的檔案。正常來講PHP程式通常是接收端,但有些時候也會扮演傳送端,把資料送到同一個或另一個伺服器,或者讀取某個網頁資料,這時可以用fopen、fsockopen或者cURL,後者功能強大且使用起來很便利、程式碼也很美觀直覺,相當推薦使用。


簡易的使用語法(GET):


$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://SomeDomain/SamplePath?SomeVar=test");
curl_exec($ch);
curl_close($ch);

Get參數可以直接在網址傳遞,但是一旦資料量很大,用POST送還是比較適合


$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://SomeDomain/SamplePath");
curl_setopt($ch, CURLOPT_POST, true); // 啟用POST
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query( array( "a"=>"123", "b"=>"321") )); 
curl_exec($ch); 
curl_close($ch);

CURLOPT_POSTFIELDS參數即為POST的內容,而 http_build_query() 效果是將array併成 a=123&b=321 型式的字串,POST內容會在header中標示以application/x-www-form-urlencoded型式傳送,如果不用字串而直接給array也可以,傳送方式則會變成multipart/form-data,但是封包會變大,且可能不被某些Server接受,通常是傳送檔案時才用。cURL有很多參數可以設置,詳細用法見PHP官網

進階的POST範例,參數設置還可以用array的方式取代:



$toURL = "http://SomeDomain/SamplePath?SomeVar=XX";
$post = array(
  "a"=>"123",
  "b"=>"321",
);
$ch = curl_init();
$options = array(
  CURLOPT_URL=>$toURL,
  CURLOPT_HEADER=>0,
  CURLOPT_VERBOSE=>0,
  CURLOPT_RETURNTRANSFER=>true,
  CURLOPT_USERAGENT=>"Mozilla/4.0 (compatible;)",
  CURLOPT_POST=>true,
  CURLOPT_POSTFIELDS=>http_build_query($post),
);
curl_setopt_array($ch, $options);
// CURLOPT_RETURNTRANSFER=true 會傳回網頁回應,
// false 時只回傳成功與否
$result = curl_exec($ch); 
curl_close($ch);
echo $result;


如果要挾帶檔案,和一般的POST動作一樣,只需注意二點:
  1. 以multipart/form-data模式傳送
  2. array內容前面加個@符號,後面接檔案的「絕對路徑」
cURL會自動去讀檔和計算大小,相當方便!

POST檔案範例:

$toURL = "http://SomeDomain/SamplePath?SomeVar=XX";
$post = array(
  "a"=>"123",
  "userfile"=>"@C:/XXX/OOO/oxox.doc",
  //檔案若和程式在同一目錄或相對目錄, 可以用getcwd(), 如:
  // "userfile"=>"@".getcwd()."/oxox.doc",
  // 另外還可以在檔名後面加上分號指定mimetype(較新版的PHP才能使用)
  // (預設的 mimetype 為application/octet-stream)
  // "userfile"=>"@".getcwd()."\\somePic.png;type=image/png"
);
$ch = curl_init();
$options = array(
  CURLOPT_URL=>$toURL,
  CURLOPT_POST=>true,
  CURLOPT_POSTFIELDS=>$post, // 直接給array
);
curl_setopt_array($ch, $options);
curl_exec($ch); 
curl_close($ch);


想挾帶多個檔案也可以,只要在array中增加即可。上段程式碼等同於在如下的HTML form中送出資料:


因為是HTML標準所以接收端不限於PHP,任何語言都可以,若接收端為PHP時,一樣是處理$_FILES變數,例如下面的程式碼:


if ($_FILES["userfile"]["error"] > 0)
{
  echo "Error: ".$_FILES["userfile"]["error"]."
";
}
else
{
  echo "檔名: ".$_FILES["userfile"]["name"]."
";
  echo "Type: ".$_FILES["userfile"]["type"]."
";
  echo "Size: ".($_FILES["userfile"]["size"]/1024)." Kb
";
  echo "暫存位置: ".$_FILES["userfile"]["tmp_name"];
轉貼來源:http://blog.roodo.com/esabear/archives/16358749.html

2012年7月9日 星期一

Blogger加掛SyntaxHighlighter,顯示漂亮的彩色程式碼

Syntax Highlighting是一種讓程式碼更容易閱讀的方法,透過不同色彩及字體的標示,讓閱讀者更容易分辨變數、保留字、函式等關鍵字。


以PHP來說,最常用的Syntax Highlighting工具就是老牌的GeSHi,它支援的程式語言種類之多,讓人冒出驚嘆號!而且直到最近它一直都有在維護、改良,我在一個星期前發現它新版不能正確解析Scheme程式語言的程式碼,把bug提交給GeSHi開發者的Issue Tracker,結果很快就釋出改正的新版本。


然而GeSHi需要在伺服器端做處理,如果是自己架設的部落格,要整合GeSHi並不難,而且通常都有現成的外掛可用。


但是以Blogger這種放別人家的網誌服務,就沒辦法用簡單的方法整合GeSHi。

幸好有syntaxhighlighter的出現,僅靠瀏覽器端執行的JavaScript就可以達到相同效果。

最新的syntaxhighlighter版本已經移到這裡「SyntaxHighlighter 3.0.83」,目前仍有在持續維護。雖然支援的程式語言種類沒有GeSHi那樣包山包海,但對於常見的程式語言來說(如下列表),已經相當夠用了。

AS3, Bash, ColdFusion, CSharp, Cpp, Css, Delphi, Diff, Erlang, Groovy, JScript, Java, JavaFX, Perl, Php, Plain, PowerShell, Python, Ruby, Scala, Sql, Vb, Xml

使用SyntaxHighlighter對網頁的SEO也是有幫助的,因為程式碼在HTML原始碼中是完整的呈現,像Pastebin.com用JavaScript的方式內嵌,實際網頁原始碼根本沒有包含程式碼;同時,在最後輸出給瀏覽器的HTML中,...


之間是原始的程式碼文字,並不會被加入額外的HTML標籤。所以瀏覽者在搜尋時,關鍵字若出現在網誌提供的程式碼中,文章就會更有機會被找到。


讓人興奮的是,SyntaxHighlighter有提供公開的Hosted Version,這意味著純粹使用Blogger寫網誌,而沒有申請其他檔案寄存服務的使用者,並不用再麻煩地去註冊一個空間來放所需的檔案,也不必偷偷使用別人的連結。設定的步驟相當簡單,請參考以下設定步驟。


SyntaxHighlighter預設已有不錯的行號顯示:
在Blogger的後台,打開「設計」、「修改HTML」。

先找到標籤,在此標籤前加入以下代碼。





完成修改後,儲存。

接著在編輯網誌文章時,使用「修改HTML」模式,使用
標籤來呈現程式碼,而class屬性則設為「brush: 程式語言代碼」,程式語言代碼請參考在文章開頭的SyntaxHighlighter已支援程式語言列表。
println 'Hello World'
println 1 + 2 + 3
另一個議題是,當我們要放的程式碼文字,包含了HTML的特殊字元,例如大於>、小於<等,這時候就需要用HTML編碼工具先轉換好,否則Blogger會認為文章包含不合法的HTML標籤。

jQuery .end()

在 jQuery 的語法中,有提供一個 .end() 的方法,最近才開始有使用到,覺得其重要性其實蠻高的,所以稍微紀錄一下自己的心得。


jQuery 的陳述句,具有串鏈(chaining)的特性,譬如說:


$("p").find("span").find(".read")


這語法,是先找出目前頁面上所有
的標籤,假設有10個,
接著在從目前的篩選結果中找出有的標籤,可能只有5個,
最後,在從這剩下的結果中找出 class=read的項目,可能只剩下2個了。
透過串鏈的好處,可以讓我們一層一層去篩選我們想要的結果,但有沒有想過,這一串 jQuery 語法,雖然可以幫我找到想要的結果,但如果我想同時去處理兩種以上的結果時,該怎麼辦呢?從上面的例子中,我最後是要找從中找出 class name 等於 read 的項目,但如果我也想同時在一個 jQuery 中處理 class name 等於 write 的項目時,可行嗎?

在 jQuery 裡,為了解決上述的疑問,他提供了 .end() 的語法,其意義就好比告訴人家,從這裡開始,回到上一層篩選結果。我們每執行一次具有破壞篩選結果的語法時,就會影響到存放目前篩選結果的堆疊。譬如上述例子,執行了 $("p"),存放在結果堆疊裡一共有10個值,但當你接著執行 .find("span") 之後,堆疊結果加進了第二次的5個查詢結果。最後一次執行了 .find("read"),則堆疊中加入了2個查詢結果。


當你執行了 .end(),則會從結果堆疊中 pop 最上層的結果,也就是把第三次的篩選結果移除,而接著要處理的項目就是 $("p").find("span") 的篩選結果了。所以,如果你想要進一步找出 class name 等於 write 的項目時,則只要在 .end()之後,加上 .find(".write")。


另外一個值得注意的是,由上圖可知,你執行一次 .end() 就會將結果堆疊 pop 一次,那是否可以執行 2 次呢?也就是,可以執行 .end().end() 嗎?可以的,由上圖可知,若您連續兩次的 .end().end() ,就會連續 pop 兩次,則結果堆疊就會只剩下  $("p") 。那如果連續 .end().end().end() 三次呢?看來你的劣根性跟我一樣,如果這樣玩的話,jQuery 就會....回傳空值了,而你的結果堆疊也就被清空了。


上面所提及的「具有破壞篩選結果的語法」,在 jQuery 說明文件中,列舉了以下語法都是具有破壞篩選結果的語法:
 add(),andSelf(),children(),closes(),filter(),find(),map(),next(),nextAll(),not(),parent(),parents(),prev(),prevAll(),siblings(),slice(),clone(),appendTo(),prependTo(),insertBefore(),insertAfter(),replaceAll()


可能會覺得奇怪,為何一定要這麼麻煩,將兩個查詢結果全部寫在一句 jQuery,分兩次寫不可以嗎?原先上面的查詢語法是:


$("p").find("span").find(".read").end().find("write")


難道不能寫成:


$("p").find("span").find(".read")
$("p").find("span").find(".write")


這樣嗎?


這種寫法,我完全同意,但當我讀了 finalevil 的一篇 [jQuery]jQuery Chaining(鏈式語法) 文章後,深深覺得 .end() 的價值排名提昇了不少。因為瀏覽器會將網頁分析後產生 Dom Tree,而 jQuery 的查詢就是針對這個 Dom Tree 去搜尋。只要是 Tree 的搜尋,都是會花時間的。如果一次可以尋訪完,你分了好幾次,當你的 jQuery 查詢次數變多時,或是 Dom Tree 是個非常大的一棵樹,想必您對效能的體會應該會更高些。以上心得,與有緣人共勉之~




參考連結:
01.A Complete Guide To jQuery – Learning The Basics
02.[jQuery]jQuery Chaining(鏈式語法)



2012年7月4日 星期三

在 Linux 下使用 find 指令查詢目錄與檔案的速查筆記

在 Linux 平台下找檔案不外乎使用威力強大的 find 命令,威力強大的背後就是有一點點學習曲線,不過整體上來說還算簡單,因此想寫一篇文章留下備忘,讓自己日後可以快速查閱參考。



【 基本語法 】
查詢檔案名稱 ( 也可以查詢「目錄名稱」,其中 * 是萬用字元 )
find $HOME -name '*.mp3'
   註1: $HOME 是 Linux 下的一個環境變數,預設指向執行帳號的 HOME 目錄
查詢檔案名稱 (不區分大小寫)
find /etc -iname 'Network'
指定只要搜尋「檔案」名稱
find /var/log -iname '*.log' -type f
指定只要搜尋「目錄」名稱
find /etc -iname 'apache2' -type d
   補充說明:可用的 –type 參數值如下
b      block (buffered) special
c      character (unbuffered) special
d      directory ( 一般目錄 )
p      named pipe (FIFO)
f      regular file ( 一般檔案 )
l      symbolic link
s      socket
D      door (Solaris)
找尋檔案內容含有 objhot.php 的檔案
find . -name "*.php" | xargs grep --color=auto "objhot.php"
『.』 表示尋找『目前目錄』
『*.php』表示尋找範圍為『*.php』

找尋所有檔案大小大於 50MB 的檔案
find /var -type f -size +50M
   註1: 不加上 –name 參數即代表搜尋所有檔案
找尋所有檔案大小小於 50MB 的檔案
find /var -type f -size -50M
尋找超過 7 天沒有被存取或修改過的檔案 (判斷檔案存取時間)
find $HOME -type f -atime +7
尋找曾經在 7 天內被存取或修改過的檔案 (判斷檔案存取時間)
find $HOME -type f -atime -7
尋找超過 10 分鐘沒有被存取或修改過的檔案 (判斷檔案存取時間)
find $HOME -type f -amin +10
尋找曾經在 10 分鐘內被存取或修改過的檔案 (判斷檔案存取時間)
find $HOME -type f -amin -10
尋找檔案建立時間已超過 30 天的檔案
find $HOME -type f -ctime +30
尋找特定使用者的檔案 ( 以帳號名稱 tom 為例 )
find $HOME -type f -user tom

【 進階應用 】
刪除 30 天以上未經存取過的暫存檔案 ( 注意: 以下指令最後一個分號(;)前一定要加上反斜線 )
find /tmp -type f -atime +30 -print -exec rm -f '{}' \;
   註1: 加上 –print 是為了讓被刪除的檔案檔名一併顯示在畫面上,這個參數可以省略    註2: 使用 –exec 會讓查詢到的每一個檔案路徑代入 ‘{}’ 位置,一個檔案會執行一遍 rm 命令
刪除 30 天以上未經存取過的暫存檔案 ( 使用 xargs 當成單一命令的參數 )
find /tmp -type f -print0 | xargs -0 rm -v
   註1: 加上 –print0 是為了讓輸出的結果不以「斷行字元」分隔,而改以 null 為結果的分隔字元    註2: 使用 xargs 命令加上 –0 是為了讓傳入的資料以 null 字元當成參數的分隔
   註3: 使用 rm 命令加上 –v 是為了能顯示出被刪除的檔案名稱,這個參數可以省略 
   註4: 使用 xargs 會將所有 find 命令查到的檔案轉換成 rm 的參數列,如果檔案過多可能會執行失敗!
   註5: 使用 xargs 可確保後面的程式 ( rm ) 只執行一次,所以理論上執行速度較快!

相同參數需輸入多筆並且以「或」邏輯運算時要用 –o 參數串接起來
例1:同時找兩種檔名樣式的檔案
find $HOME -name '*.mp3' -o -user '*.ogg'
例2:同時找兩個擁有者的檔案
find /usr/local -user user1 -o -user user2

【 注意事項 】
  • 使用萬用字元時務必加上單引號( ' )

    !!以下是錯誤示範!!
  • [user1@server ~]# find $HOME -name *.txt
    find: paths must precede expression
    Usage: find [path...] [expression]

相關連結

2012年7月2日 星期一

mysql_fetch_array() 與 mysql_fetch_assoc() 與 mysql_fetch_row() 的差異

當需要從DB讀取資料時,我們常會使用下列的語法:
while ($row = mysql_fetch_array($result)){
    $xxx = $row[ ___ ];  //底線部份的陣列索引值可以是數字(即數字索引)或字串(即關聯索引)
}

但是,有時候也會看到mysql_fetch_array()被mysql_fetch_assoc()或mysql_fetch_row()代替,其實只有一點差別...


mysql_fetch_array()從資料集取得的陣列,索引值可以是數字(數字索引)或字串(關聯索引)。
$a=$row[0]; 或 $a=$row["a"];

mysql_fetch_assoc()從資料集取得的陣列,索引值只能是字串(關聯索引)。
$a=$row["a"];

mysql_fetch_row()從資料集取得的陣列,索引值只能是數字(數字索引)。
$a=$row[0];



引用至:
http://seanphpbook.blogspot.tw/2010/05/php-mysqlfetcharray-mysqlfetchassoc.html