顯示具有 php 標籤的文章。 顯示所有文章
顯示具有 php 標籤的文章。 顯示所有文章

2015年4月1日 星期三

[引用]PHP上處理utf-16le檔案

來源出處: http://www.jikker.net/2010/11/phputf-16le.html


只有utf-8允許可以沒有bom,utf-16, utf-32都是一定要有bom的,因為牽涉到little endian跟big endian的問題

function utf8_to_utf16($utf8_filename,$utf16_filename){ $file = fopen($utf8_filename,"r"); $write = fopen($utf16_filename,"w+"); if($file){ $buffer=chr(255).chr(254); //加入BOM fwrite($write,$buffer); while(($buffer = fgets($file)) != false){ $buffer=iconv('UTF-8','UTF-16LE',$buffer); fwrite($write,$buffer); } } } function utf16_to_utf8($utf16_filename,$utf8_filename){ $write = fopen($utf8_filename,"w+"); $buffer=mb_convert_encoding( file_get_contents( $utf16_filename ), 'UTF-8', 'UTF-16LE' ); fwrite($write,$buffer); }

為什麼2種轉法不一樣呢?
因為utf-8轉utf-16時會佔用比較多的記憶體,一次轉的話容易造成記憶體不足,所以分行轉,utf-16就沒這個問題,此外utf-8轉utf-16花的時間也比utf-16轉utf-8多,我測試轉一個12m的檔案,8轉16要花23秒,16轉8只要1秒...

另外,用這個方式轉出來的utf-8是有bom的,要去除的話請自己來 XD

2012年11月20日 星期二

[php][引用] 透過 CURL 去 POST XML file

引用來源:http://www.phpmind.com/blog/2009/08/how-to-post-xml-using-curl/

透過CURL 去模擬XML file post 的行為.

  <?php $xml_data ='<AATAvailReq1>'. '<Agency>'. '<Iata>1234567890</Iata>'. '<Agent>lgsoftwares</Agent>'. '<Password>mypassword</Password>'. '<Brand>phpmind.com</Brand>'. '</Agency>'. '<Passengers>'. '<Adult AGE="" ID="1"></Adult>'. '<Adult AGE="" ID="2"></Adult>'. '</Passengers>'. '<HotelAvailReq1>'. '<DestCode>JHM</DestCode>'. '<HotelCode>OGGSHE</HotelCode>'. '<CheckInDate>101009</CheckInDate>'. '<CheckOutDate>101509</CheckOutDate>'. '<UseField>1</UseField>'. '</HotelAvailReq1>'. '</AATAvailReq1>'; $URL = "https://www.yourwebserver.com/path/"; $ch = curl_init($URL); curl_setopt($ch, CURLOPT_MUTE, 1); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: text/xml')); curl_setopt($ch, CURLOPT_POSTFIELDS, "$xml_data"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); $output = curl_exec($ch); curl_close($ch); ?>

2012年8月14日 星期二

[PHP] 批量移除utf8 bom

有時候碰上bom 的問題, 會讓人家摸不著頭緒. 來源網站 <?php if (isset($_GET['dir'])){ //config the basedir $basedir=$_GET['dir']; }else{ $basedir = '.'; } $auto = 1; checkdir($basedir); function checkdir($basedir){ if ($dh = opendir($basedir)) { while (($file = readdir($dh)) !== false) { if ($file != '.' && $file != '..'){ if (!is_dir($basedir."/".$file)) { echo "filename: $basedir/$file ".checkBOM("$basedir/$file")." <br>"; }else{ $dirname = $basedir."/".$file; checkdir($dirname); } } } closedir($dh); } } function checkBOM ($filename) { global $auto; $contents = file_get_contents($filename); $charset[1] = substr($contents, 0, 1); $charset[2] = substr($contents, 1, 1); $charset[3] = substr($contents, 2, 1); if (ord($charset[1]) == 239 && ord($charset[2]) == 187 && ord($charset[3]) == 191) { if ($auto == 1) { $rest = substr($contents, 3); rewrite ($filename, $rest); return ("<font color=red>BOM found, automatically removed.</font>"); } else { return ("<font color=red>BOM found.</font>"); } } else return ("BOM Not Found."); } function rewrite ($filename, $data) { $filenum = fopen($filename, "w"); flock($filenum, LOCK_EX); fwrite($filenum, $data); fclose($filenum); } ?>

2012年5月10日 星期四

[引用]用 PHP 抓取下星期二的 Timestamp - strtotime()



引用來源: Tsung 's Blog
日期的轉換只要把日期轉成 Timestamp, 就可以使用 date() 轉成自己想要的格式.
strtotime() 很常用, 通常都是把 "2012-02-12 22:11:10" 丟進去, 轉成 Timestamp.
最近想要抓某個日期, 或者是上週、下週、上個星期一、下個星期二.. 等等的時間, 才發現 strtotime() 強的很過份. XD

PHP strtotime() function 的使用範例


<?php
echo strtotime('Monday this week'), "\n";
echo strtotime("10 September 2000"), "\n";
echo strtotime("+1 day"), "\n";
echo strtotime("+1 week"), "\n";
echo strtotime("+1 week 2 days 4 hours 2 seconds"), "\n";
echo strtotime("next Thursday"), "\n";
echo strtotime("last Monday"), "\n";
?>


  • $ php -a
    php > echo strtotime("10 September 2000"), "\n";
    968515200
    php > function d($t) {
    php { echo date('Y-m-d', $t);
    php { }
    php > echo d(strtotime("10 September 2000"));
    2000-09-10
    php > echo d(strtotime("+1 day"));
    2012-03-08
    php > echo d(strtotime("+1 week"));
    2012-03-14
    php > echo d(strtotime("-1 week"));
    2012-02-29
    php > echo d(strtotime("next Thursday"));
    2012-03-08
    php > echo d(strtotime("Monday this week"));
    2012-03-05
    php > echo d(strtotime("-5 week"));
    2012-02-01
    php > echo d(strtotime("Sunday -5 week"));
    2012-02-05
    php > echo d(strtotime("2012-03-05"));
    2012-03-05
    php > echo d(strtotime("Sunday 2012-03-07"));
    2012-03-11
    php > echo d(strtotime("last Sunday 2012-03-07"));
    2012-03-04

相關網頁

2012年4月19日 星期四

[PHP] <? 與 <?php 差異與設定

若是發生<? 不能跑, 但是 <?php 卻可以.
這問題常常會發生在 新的php5 的版本.
那就是要去改php.ini 的設定了.

找到將數值設成 On:
short_open_tag = On

On 表示允許用&lt?
Off 表示只能用&lt?php

2012年1月3日 星期二

[引用] PHP RESTful 測試

用php 模擬 RESTful 的使用 來源網站: http://studio.zeuik.com/?p=1044 class RESTful { const IS_GET = "get"; const IS_POST = "post"; const IS_PUT = "put"; const IS_DELETE = "delete"; public static function get($key, $default_value = "") { return isset($_GET[$key])?$_GET[$key]: $default_value; } public static function post($key, $default_value = "") { return isset($_POST[$key])?$_POST[$key]: $default_value; } public static function method() { return isset($_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE']) ?$_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'] : $_SERVER['REQUEST_METHOD']; } public static function data($key = "", $default_value = "") { $method = strtolower(self::method()); switch($method) { case self::IS_GET: case self::IS_POST: return self::$method($key, $default_value); break; case self::IS_PUT: case self::IS_DELETE: return file_get_contents('php://input'); break; } } } echo RESTful::method() ."\n"; /* * GET : curl -G -d "text=123" "http://localhost/test/php-restful/index.php" * POST: curl -d "text=123" "http://localhost/test/php-restful/index.php" */ echo RESTful::data("text")."\n"; /* * PUT : curl -X PUT -d "text=123" http://localhost/test/php-restful/index.php * DELETE: curl -X DELETE -d "text=123" http://localhost/test/php-restful/index.php */ echo RESTful::data()."\n";

2011年10月17日 星期一

[引用]PHP 使用 CURL 同步抓取多個網頁

引用來源:Tsung's Blog
一般 CURL 抓網頁的方法, 是一頁一頁抓, 假設要抓 4頁, 所費時間各別是 5,10,7,5 秒, 那全部總合所花的時間就是 5 + 10 + 7 + 5 = 27 秒.
若能同時間去抓取多個網頁, 所花費的時間 5,10,7,5 秒, 全部總合所花的時間是 10 秒.(花費最多時間的秒數)
於 JavaScript 可使用 AJAX 的 async(YAHOO.util.Connect.asyncRequest) 來達成, 於 PHP 可以用 CURL 來達成此 Multi-Threading 的效果.

程式(async.php)

function async_get_url($url_array, $wait_usec = 0)
{
    if (!is_array($url_array))
        return false;

    $wait_usec = intval($wait_usec);

    $data    = array();
    $handle  = array();
    $running = 0;

    $mh = curl_multi_init(); // multi curl handler

    $i = 0;
    foreach($url_array as $url) {
        $ch = curl_init();

        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // return don't print
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);
        curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)');
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); // 302 redirect
        curl_setopt($ch, CURLOPT_MAXREDIRS, 7);

        curl_multi_add_handle($mh, $ch); // 把 curl resource 放進 multi curl handler 裡

        $handle[$i++] = $ch;
    }

    /* 執行 */
    /* 此種做法會造成 CPU loading 過重 (CPU 100%)
    do {
        curl_multi_exec($mh, $running);

        if ($wait_usec > 0) // 每個 connect 要間隔多久
            usleep($wait_usec); // 250000 = 0.25 sec
    } while ($running > 0);
    */

    /* 此做法就可以避免掉 CPU loading 100% 的問題 */
    // 參考自: http://www.hengss.com/xueyuan/sort0362/php/info-36963.html
    do {
        $mrc = curl_multi_exec($mh, $active);
    } while ($mrc == CURLM_CALL_MULTI_PERFORM);

    while ($active and $mrc == CURLM_OK) {
        if (curl_multi_select($mh) != -1) {
            do {
                $mrc = curl_multi_exec($mh, $active);
            } while ($mrc == CURLM_CALL_MULTI_PERFORM);
        }
    }

    /* 讀取資料 */
    foreach($handle as $i => $ch) {
        $content  = curl_multi_getcontent($ch);
        $data[$i] = (curl_errno($ch) == 0) ? $content : false;
    }

    /* 移除 handle*/
    foreach($handle as $ch) {
        curl_multi_remove_handle($mh, $ch);
    }

    curl_multi_close($mh);

    return $data;
}
?>

使用

$urls = array('http://example1.com', 'http://example2.com');
print_r(async_get_url($urls)); // [0] => example1, [1] => example2
?>

測試

sleep.php # 看時間延長取得的效果

sleep(intval($_GET['time']));
echo intval($_GET['time']);
?>

$url_array = array(
        'http://example.com/sleep.php?time=5',
        'http://example.com/sleep.php?time=10',
        'http://example.com/sleep.php?time=7',
        'http://example.com/sleep.php?time=5',
        );
print_r(async_get_url($url_array));
// 總花費時間會是 10 秒, 並印出 [0] => 5, [1] => 10, [2] => 7, [3] => 5
?>

2011年9月22日 星期四

檢查get_magic_quotes_gpc 將 POST 的資料再重組成 URL

檢查是否有 get_magic_quotes_gpc 函數. 若是有則 加個 stripslashes 去過濾該值. if(function_exists('get_magic_quotes_gpc')) { $get_magic_quotes_exits = true; } foreach ($_POST as $key => $value) // Handle escape characters, which depends on setting of magic quotes { if($get_magic_quotes_exists == true && get_magic_quotes_gpc() == 1) { $value = urlencode(stripslashes($value)); } else { $value = urlencode($value); } $req .= "&$key=$value"; }

2011年9月21日 星期三

php 取代 htmlspecialchars 函數 xml 中會用到.

取代 htmlspecialchars 函數 . 因為若是重複置換 & 每次都會被置換成 &amp; 所以 原本 < 變成 &lt; , 再經一次轉換就變成 &amp;lt; 在第二次就變成 &amp;amp;lt; function html_for_xml ($str){ $str = str_replace('<','&lt;',$str); $str = str_replace('>','&gt;',$str); $str = str_replace('"','&quot;',$str); $str = str_replace('\'','&#039;',$str); return preg_replace('/&(?!lt;|gt;|quot;|#039;|amp;)/eis','&amp;',$str); } 將&amp; 全部還原成 & 的 function function html_for_xml2 ($str){ $str = str_replace('&amp;','&',$str); if (stristr($str,"&amp;") != false) { $str = html_for_xml2($str); } return $str; }

2011年9月9日 星期五

[PHP]免費簡易Task程式 -> mytinytodo

一直以來都使用Google行事曆中tasks,
缺點就是無法分類,於是找到了簡單的todo List程式
http://www.mytinytodo.net

1.簡潔的AJAX介面,支援MySQL與SQLite
2.可設定公開瀏覽的分類
3.有行動裝置版本UI




















附註:Mobile UI需要在網址後帶入pda參數,如果想要自動判斷可以在index.php中加入下面的自動轉頁


if(isset($_SERVER['HTTP_USER_AGENT'])){ $l=array('Android','iPhone','iPad'); foreach($l as $item){ if(stripos($_SERVER['HTTP_USER_AGENT'],$item)!==false &amp;&amp; !isset($_GET['pda'])){ header('location: ?pda'); exit; } } }

2011年9月8日 星期四

用 PHP 讀取和編寫 XML DOM






有許多技術可用於用 PHP 讀取和編寫 XML。本文提供了三種方法讀取 XML:使用 DOM 庫、使用 SAX 解析器和使用正則表達式。還介紹了使用 DOM 和 PHP 文本模板編寫 XML。
用 PHP 讀取和編寫可擴展標記語言(XML)看起來可能有點恐怖。實際上,XML 和它的所有相關技術可能是恐怖的,但是用 PHP 讀取和編寫 XML 不一定是項恐怖的任務。首先,需要學習一點關於 XML 的知識 —— 它是什麼,用它做什麼。然後,需要學習如何用 PHP 讀取和編寫 XML,而有許多種方式可以做這件事。
本文提供了 XML 的簡短入門,然後解釋如何用 PHP 讀取和編寫 XML。
什麼是 XML?
XML 是一種數據存儲格式。它沒有定義保存什麼數據,也沒有定義數據的格式。XML 只是定義了標記和這些標記的屬性。格式良好的 XML 標記看起來像這樣:
Jack Herrington
這個 標記包含一些文本:Jack Herrington。
不包含文本的 XML 標記看起來像這樣:

用 XML 對某件事進行編寫的方式不止一種。例如,這個標記形成的輸出與前一個標記相同:

也可以向 XML 標記添加屬性。例如,這個 標記包含 firstlast 屬性:

也可以用 XML 對特殊字符進行編碼。例如,& 符號可以像這樣編碼:
&
包含標記和屬性的 XML 文件如果像示例一樣格式化,就是格式良好的,這意味著標記是對稱的,字符的編碼正確。清單 1 是一份格式良好的 XML 的示例。


清單 1. XML 圖書列表示例
  

Jack Herrington
PHP Hacks
O'Reilly

Jack Herrington
Podcasting Hacks
O'Reilly

清單 1 中的 XML 包含一個圖書列表。父標記 包含一組 標記,每個 標記又包含 </code> 和 <code><publisher></code> 標記。</p> <p>當 XML 文檔的標記結構和內容得到外部模式文件的驗證後,XML 文檔就是正確的。模式文件可以用不同的格式指定。對於本文來說,所需要的只是格式良好的 XML。</p> <p>如果覺得 XML 看起來很像超文本標記語言(HTML),那麼就對了。XML 和 HTML 都是基於標記的語言,它們有許多相似之處。但是,要著重指出的是:雖然 XML 文檔可能是格式良好的 HTML,但不是所有的 HTML 文檔都是格式良好的 XML。換行標記(<code>br</code>)是 XML 和 HTML 之間區別的一個好例子。這個換行標記是格式良好的 HTML,但不是格式良好的 XML:</p> <code><p>This is a paragraph<br /><br /> With a line break</p> </code> <p>這個換行標記是格式良好的 XML 和 HTML:</p> <code><p>This is a paragraph<br /><br /> With a line break</p> </code> <p>如果要把 HTML 編寫成同樣是格式良好的 XML,請遵循 W3C 委員會的可擴展超文本標記語言(XHTML)標準(參見 <a href="http://www.ibm.com/developerworks/cn/opensource/os-xmldomphp/#resources">參考資料</a>)。所有現代的瀏覽器都能呈現 XHTML。而且,還可以用 XML 工具讀取 XHTML 並找出文檔中的數據,這比解析 HTML 容易得多。</p><br /><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" /><br /><img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" /></td></tr></tbody></table><table class="no-print" align="right" cellpadding="0" cellspacing="0"><tbody><tr align="right"><td><img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" /><br /><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td valign="middle"><br /></td><td align="right" valign="top"><br /></td></tr></tbody></table></td></tr></tbody></table><br /><br /><p><a name="N100E0"><span class="atitle">使用 DOM 庫讀取 XML</span></a></p> <p>讀取格式良好的 XML 文件最容易的方式是使用編譯成某些 PHP 安裝的文檔對象模型 (DOM)庫。DOM 庫把整個 XML 文檔讀入內存,並用節點樹表示它,如圖 1 所示。</p> <br /><br /><a name="N100EB"><b>圖 1. 圖書 XML 的 XML DOM 樹</b></a><br /><img alt="圖書 XML 的 XML DOM 樹" src="http://www.ibm.com/developerworks/cn/opensource/os-xmldomphp/figure1.gif" height="227" width="392" /><br /><p>樹頂部的 <code>books</code> 節點有兩個 <code>book</code> 子標記。在每本書中,有 <code>author</code>、<code>publisher</code> 和 <code>title</code> 幾個節點。<code>author</code>、<code>publisher</code> 和 <code>title</code> 節點分別有包含文本的文本子節點。</p> <p>讀取圖書 XML 文件並用 DOM 顯示內容的代碼如清單 2 所示。</p> <br /><br /><a name="N10122"><b>清單 2. 用 DOM 讀取圖書 XML</b></a><br /><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td class="code-outline"><pre class="displaycode"> <?php $doc = new DOMDocument(); $doc->load( 'books.xml' );<br /><br /> $books = $doc->getElementsByTagName( "book" );<br /> foreach( $books as $book )<br /> {<br /> $authors = $book->getElementsByTagName( "author" );<br /> $author = $authors->item(0)->nodeValue;<br /><br /> $publishers = $book->getElementsByTagName( "publisher" );<br /> $publisher = $publishers->item(0)->nodeValue;<br /><br /> $titles = $book->getElementsByTagName( "title" );<br /> $title = $titles->item(0)->nodeValue;<br /><br /> echo "$title - $author - $publisher\n";<br /> }<br /> ?><br /> </pre></td></tr></tbody></table><br /><p>腳本首先創建一個 <code>new DOMdocument</code> 對象,用 <code>load</code> 方法把圖書 XML 裝入這個對象。之後,腳本用 <code>getElementsByName</code> 方法得到指定名稱下的所有元素的列表。</p> <p>在 <code>book</code> 節點的循環中,腳本用 <code>getElementsByName</code> 方法獲得 <code>author</code>、<code>publisher</code> 和 <code>title</code> 標記的 <code>nodeValue</code>。<code>nodeValue</code> 是節點中的文本。腳本然後顯示這些值。</p> <p>可以在命令行上像這樣運行 PHP 腳本:</p> <code>% php e1.php<br />PHP Hacks - Jack Herrington - O'Reilly<br />Podcasting Hacks - Jack Herrington - O'Reilly<br />%</code> <p>可以看到,每個圖書塊輸出一行。這是一個良好的開始。但是,如果不能訪問 XML DOM 庫該怎麼辦?</p><br /><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" /><br /><img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" /></td></tr></tbody></table><table class="no-print" align="right" cellpadding="0" cellspacing="0"><tbody><tr align="right"><td><img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" /><br /><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td valign="middle"><br /></td><td align="right" valign="top"><br /></td></tr></tbody></table></td></tr></tbody></table><br /><br /><p><a name="N10167"><span class="atitle">用 SAX 解析器讀取 XML </span></a></p> <p>讀取 XML 的另一種方法是使用 XML Simple API(SAX)解析器。PHP 的大多數安裝都包含 SAX 解析器。SAX 解析器運行在回調模型上。每次打開或關閉一個標記時,或者每次解析器看到文本時,就用節點或文本的信息回調用戶定義的函數。</p> <p>SAX 解析器的優點是,它是真正輕量級的。解析器不會在內存中長期保持內容,所以可以用於非常巨大的文件。缺點是編寫 SAX 解析器回調是件非常麻煩的事。清單 3 顯示了使用 SAX 讀取圖書 XML 文件並顯示內容的代碼。</p> <br /><br /><a name="N10177"><b>清單 3. 用 SAX 解析器讀取圖書 XML </b></a><br /><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td class="code-outline"><pre class="displaycode"> <?php $g_books = array(); $g_elem = null; function startElement( $parser, $name, $attrs ) { global $g_books, $g_elem; if ( $name == 'BOOK' ) $g_books []= array(); $g_elem = $name; } function endElement( $parser, $name ) { global $g_elem; $g_elem = null; } function textData( $parser, $text ) { global $g_books, $g_elem; if ( $g_elem == 'AUTHOR' || $g_elem == 'PUBLISHER' || $g_elem == 'TITLE' ) { $g_books[ count( $g_books ) - 1 ][ $g_elem ] = $text; } } $parser = xml_parser_create(); xml_set_element_handler( $parser, "startElement", "endElement" ); xml_set_character_data_handler( $parser, "textData" ); $f = fopen( 'books.xml', 'r' ); while( $data = fread( $f, 4096 ) ) { xml_parse( $parser, $data ); } xml_parser_free( $parser ); foreach( $g_books as $book ) { echo $book['TITLE']." - ".$book['AUTHOR']." - "; echo $book['PUBLISHER']."\n"; } ?><br /> </pre></td></tr></tbody></table><br /><p>腳本首先設置 <code>g_books</code> 數組,它在內存中容納所有圖書和圖書信息,<code>g_elem</code> 變量保存腳本目前正在處理的標記的名稱。然後腳本定義回調函數。在這個示例中,回調函數是 <code>startElement</code>、<code>endElement</code> 和 <code>textData</code>。在打開和關閉標記的時候,分別調用 <code>startElement</code> 和 <code>endElement</code> 函數。在開始和結束標記之間的文本上面,調用 <code>textData</code>。</p> <p>在這個示例中,<code>startElement</code> 標記查找 <code>book</code> 標記,在 <code>book</code> 數組中開始一個新元素。然後,<code>textData</code> 函數查看當前元素,看它是不是 <code>publisher</code>、<code>title</code> 或 <code>author</code> 標記。如果是,函數就把當前文本放入當前圖書。</p> <p>為了讓解析繼續,腳本用 <code>xml_parser_create</code> 函數創建解析器。然後,設置回調句柄。之後,腳本讀取文件並把文件的大塊內容發送到解析器。在文件讀取之後,<code>xml_parser_free</code> 函數刪除解析器。腳本的末尾輸出 <code>g_books</code> 數組的內容。</p> <p>可以看到,這比編寫 DOM 的同樣功能要困難得多。如果沒有 DOM 庫也沒有 SAX 庫該怎麼辦?還有替代方案麼?</p><br /><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" /><br /><img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" /></td></tr></tbody></table><table class="no-print" align="right" cellpadding="0" cellspacing="0"><tbody><tr align="right"><td><img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" /><br /><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td valign="middle"><br /></td><td align="right" valign="top"><br /></td></tr></tbody></table></td></tr></tbody></table><br /><br /><p><a name="N101D2"><span class="atitle">用正則表達式解析 XML</span></a></p> <p>可以肯定,即使提到這個方法,有些工程師也會批評我,但是確實可以用正則表達式解析 XML。清單 4 顯示了使用 <code>preg_</code> 函數讀取圖書文件的示例。</p><br /><br /><a name="N101E3"><b>清單 4. 用正則表達式讀取 XML</b></a><br /><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td class="code-outline"><pre class="displaycode"> <?php $xml = ""; $f = fopen( 'books.xml', 'r' ); while( $data = fread( $f, 4096 ) ) { $xml .= $data; } fclose( $f ); preg_match_all( "/\<book\>(.*?)\<\/book\>/s",<br /> $xml, $bookblocks );<br /><br /> foreach( $bookblocks[1] as $block )<br /> {<br /> preg_match_all( "/\<author\>(.*?)\<\/author\>/",<br /> $block, $author );<br /> preg_match_all( "/\<title\>(.*?)\<\/title\>/",<br /> $block, $title );<br /> preg_match_all( "/\<publisher\>(.*?)\<\/publisher\>/",<br /> $block, $publisher );<br /> echo( $title[1][0]." - ".$author[1][0]." - ".<br /> $publisher[1][0]."\n" );<br /> }<br /> ?><br /></pre></td></tr></tbody></table><br /><p>請注意這個代碼有多短。開始時,它把文件讀進一個大的字符串。然後用一個 <code>regex</code> 函數讀取每個圖書項目。最後用 <code>foreach</code> 循環,在每個圖書塊間循環,並提取出 author、title 和 publisher。</p> <p>那麼,缺陷在哪呢?使用正則表達式代碼讀取 XML 的問題是,它並沒先進行檢查,確保 XML 的格式良好。這意味著在讀取之前,無法知道 XML 是否格式良好。而且,有些格式正確的 XML 可能與正則表達式不匹配,所以日後必須修改它們。</p> <p>我從不建議使用正則表達式讀取 XML,但是有時它是兼容性最好的方式,因為正則表達式函數總是可用的。不要用正則表達式讀取直接來自用戶的 XML,因為無法控制這類 XML 的格式或結構。應當一直用 DOM 庫或 SAX 解析器讀取來自用戶的 XML。</p> <br /><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" /><br /><img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" /></td></tr></tbody></table><table class="no-print" align="right" cellpadding="0" cellspacing="0"><tbody><tr align="right"><td><img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" /><br /><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td valign="middle"><br /></td><td align="right" valign="top"><br /></td></tr></tbody></table></td></tr></tbody></table><br /><br /><p><a name="N101FB"><span class="atitle">用 DOM 編寫 XML</span></a></p> <p>讀取 XML 只是公式的一部分。該怎樣編寫 XML 呢?編寫 XML 最好的方式就是用 DOM。清單 5 顯示了 DOM 構建圖書 XML 文件的方式。</p><br /><br /><a name="N10208"><b>清單 5. 用 DOM 編寫圖書 XML</b></a><br /><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td class="code-outline"><pre class="displaycode"> <?php $books = array(); $books [] = array( 'title' => 'PHP Hacks',<br /> 'author' => 'Jack Herrington',<br /> 'publisher' => "O'Reilly"<br /> );<br /> $books [] = array(<br /> 'title' => 'Podcasting Hacks',<br /> 'author' => 'Jack Herrington',<br /> 'publisher' => "O'Reilly"<br /> );<br /><br /> $doc = new DOMDocument();<br /> $doc->formatOutput = true;<br /><br /> $r = $doc->createElement( "books" );<br /> $doc->appendChild( $r );<br /><br /> foreach( $books as $book )<br /> {<br /> $b = $doc->createElement( "book" );<br /><br /> $author = $doc->createElement( "author" );<br /> $author->appendChild(<br /> $doc->createTextNode( $book['author'] )<br /> );<br /> $b->appendChild( $author );<br /><br /> $title = $doc->createElement( "title" );<br /> $title->appendChild(<br /> $doc->createTextNode( $book['title'] )<br /> );<br /> $b->appendChild( $title );<br /><br /> $publisher = $doc->createElement( "publisher" );<br /> $publisher->appendChild(<br /> $doc->createTextNode( $book['publisher'] )<br /> );<br /> $b->appendChild( $publisher );<br /><br /> $r->appendChild( $b );<br /> }<br /><br /> echo $doc->saveXML();<br /> ?><br /></pre></td></tr></tbody></table><br /><p>在腳本的頂部,用一些示例圖書裝入了 <code>books</code> 數組。這個數據可以來自用戶也可以來自數據庫。</p> <p>示例圖書裝入之後,腳本創建一個 <code>new DOMDocument</code>,並把根節點 <code>books</code> 添加到它。然後腳本為每本書的 author、title 和 publisher 創建節點,並為每個節點添加文本節點。每個 <code>book</code> 節點的最後一步是重新把它添加到根節點 <code>books</code>。</p> <p>腳本的末尾用 <code>saveXML</code> 方法把 XML 輸出到控制台。(也可以用 <code>save</code> 方法創建一個 XML 文件。)腳本的輸出如清單 6 所示。</p> <br /><br /><a name="N10238"><b>清單 6. DOM 構建腳本的輸出</b></a><br /><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td class="code-outline"><pre class="displaycode"> % php e4.php<br /> <?xml version="1.0"?><br /> <books><br /> <book><br /> <author>Jack Herrington</author><br /> <title>PHP Hacks
O'Reilly


Jack Herrington
Podcasting Hacks
O'Reilly


%

使用 DOM 的真正價值在於它創建的 XML 總是格式正確的。但是如果不能用 DOM 創建 XML 時該怎麼辦?







用 PHP 編寫 XML
如果 DOM 不可用,可以用 PHP 的文本模板編寫 XML。清單 7 顯示了 PHP 如何構建圖書 XML 文件。


清單 7. 用 PHP 編寫圖書 XML
   'PHP Hacks',
'author' => 'Jack Herrington',
'publisher' => "O'Reilly"
);
$books [] = array(
'title' => 'Podcasting Hacks',
'author' => 'Jack Herrington',
'publisher' => "O'Reilly"
);
?>



<?php echo( $book['title'] ); ?>





腳本的頂部與 DOM 腳本類似。腳本的底部打開 books 標記,然後在每個圖書中迭代,創建 book 標記和所有的內部 titleauthorpublisher 標記。
這種方法的問題是對實體進行編碼。為了確保實體編碼正確,必須在每個項目上調用 htmlentities 函數,如清單 8 所示。


清單 8. 使用 htmlentities 函數對實體編碼



<?php echo( $title ); ?>
 



這就是用基本的 PHP 編寫 XML 的煩人之處。您以為自己創建了完美的 XML,但是在試圖使用數據的時候,馬上就會發現某些元素的編碼不正確。







結束語
XML 周圍總有許多誇大之處和混淆之處。但是,並不像您想像的那麼難 —— 特別是在 PHP 這樣優秀的語言中。在理解並正確地實現了 XML 之後,就會發現有許多強大的工具可以使用。XPath 和 XSLT 就是這樣兩個值得研究的工具。


參考資料
學習

2011年7月21日 星期四

[引用]PHP 縮圖、截圖、翻轉的程式

引用來源

PHP 縮圖、截圖、翻轉 程式

有個 Open Source 的專案, 把這些都寫成一個物件, 可以很方便的操作使用.

2011年6月16日 星期四

[PHP] call_user_func_array () 呼叫function and Class

call_user_func_array() 神奇的PHP 內建函數.


function foobar($arg, $arg2) {
echo __FUNCTION__, " got $arg and $arg2\n";
}
class foo {
function bar($arg, $arg2) {
echo __METHOD__, " got $arg and $arg2\n";
}
}


// Call the foobar() function with 2 arguments
call_user_func_array("foobar", array("one", "two"));

// Call the $foo->bar() method with 2 arguments
$foo = new foo;
call_user_func_array(array($foo, "bar"), array("three", "four"));

結果:
foobar got one and two
foo::bar got three and four

2011年6月1日 星期三

[引用]PHP 將 文字 轉換成 &#xxxxx; UNICODE 碼

將中文字轉換成 &#xxxxx; UNICODE 碼, 主要的用途在於, 不用擔心有顯示不出來的文字.

引用來源


<?php
$str = '我';

/* 將 '我' 轉換成 '25105' 或 '&#25105;' */
// 使用 iconv
$unicode_html = base_convert(bin2hex(iconv('UTF-8', 'UCS-4', $str)), 16, 10); // 25105

// 使用 mb_convert_encoding
$unicode_html = base_convert(bin2hex(mb_convert_encoding($str, 'ucs-4', 'utf-8')), 16, 10); // 25105

// 補上 &#xxxxx;
$unicode_html = '&#' . base_convert(bin2hex(iconv("utf-8", "ucs-4", $str)), 16, 10) . ';'; // &#25105;

// 將 &#25105 轉回 '我'
$str = mb_convert_encoding($unicode_html, 'UTF-8', 'HTML-ENTITIES'); // '我', $unicode_html = '&#25105'

?>

2011年4月7日 星期四

[PHP] call_user_func_array 介紹

使用 call_user_func_array 來call 自己設定的function .


helper_call_custom_function('test');

function helper_call_custom_function( $p_function, $p_args_array ) {
$t_function = 'custom_function_override_' . $p_function;

if( !function_exists( $t_function ) ) {
$t_function = 'custom_function_default_' . $p_function;
}

return call_user_func_array( $t_function, $p_args_array );
}

function custom_function_default_test($p_args_array , $xxx = CUSTOM_VALUE){
xxx....
}

2011年3月1日 星期二

ReadBeanPHP

RedBeanPHP 是一種直接透過程式去管理資料庫的一個函數, 不得不對他的使用方法感到新奇.


//引用

require("rb.php");


//設定, 預設 sqllite
R::setup();  


SQLite platform independent
R::setup("sqlite:database.txt"); 


//MySQL 設定
R::setup("mysql:host=localhost;dbname=oodb",$user,$pass);


//PostgreSQL設定
 R::setup("pgsql:host=localhost dbname=oodb",$user,$pass);



整合 Codeigniter 

2011年2月17日 星期四

[PHP] 刪除路徑下所有檔案與目錄, 模擬 rm -rf

當你php 無法執行 exec('rm -rf') 指令去刪除目錄下所有檔案與目錄時, 只好靠程式啦~

$log = '/home/logs/2011';
SureRemoveDir($log , true); // 第二個參數: true 連 2011 目錄也刪除
function SureRemoveDir($dir, $DeleteMe) {
if(!$dh = @opendir($dir)) return;
while (false !== ($obj = readdir($dh))) {
if($obj=='.' || $obj=='..') continue;
if (!@unlink($dir.'/'.$obj)) SureRemoveDir($dir.'/'.$obj, true);
}
if ($DeleteMe){
closedir($dh);
@rmdir($dir);
}
}

來源:PHP官網

2011年2月11日 星期五

[引述]PHP程式使用 Windows Server AD 認證身份

來源
Windows Server AD 說穿了就是一個 LADP 伺服器,可讓您將資訊儲存在目錄服務中,在資料庫中進行查詢,並可以使用他來作為身份的認證授權。

使用PHP撰寫程式難免會遇到需要作身份認證的問題,除了自行撰寫這部份程式的選擇外,PHP 的函式庫中亦提供了標準的 LDAP 函式,如果公司組織中已經有架設 Windows 2K/2003 網域的環境 ,將身份認證的工作交由 Windows AD 亦是一個不錯的選擇。

案例環境說明:
1.公司組織內有一個Windows 網域,名稱為: domain.com。
2.domain.com 的網域有兩部網域主控站(DC)分別為:dc.domain.com、dc2.domain.com。
3.PHP版本:5.1.4

PHP程式碼範例:
以下的程式範例為精簡版,帳號和密碼不可為空的


<?php

$domain = 'domain.com'; //設定網域名稱
$user = 'user'; //設定欲認證的帳號名稱
$password = 'password'; //設定欲認證的帳號密碼

// 使用 ldap bind
$ldaprdn = $user . '@' . $domain; // ldap rdn or dn
$ldappass = $password; // 設定密碼

// 連接至網域控制站
$ldapconn = ldap_connect($domain) or die("無法連接至 $domain");

// 如果要特別指定某一部網域主控站(DC)來作認證則上面改寫為
// $ldapconn = ldap_connect('dc.domain.com) or die("無法連接至 dc.domain.com");
// 或
// $ldapconn = ldap_connect('dc2.domain.com)or die("無法連接至 dc2.domain.com");

//以下兩行務必加上,否則 Windows AD 無法在不指定 OU 下,作搜尋的動作
ldap_set_option($ldapconn, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($ldapconn, LDAP_OPT_REFERRALS, 0);

if ($ldapconn) { // binding to ldap server
$ldapbind = @ldap_bind($ldapconn, $ldaprdn, $ldappass);
// verify binding
if ($ldapbind) {
$filter = "(sAMAccountName=$user)";
$result = @ldap_search($ldapconn, $dn, $filter);

if($result==false) echo "認證失敗";
else {
echo "認證成功...";
//取出帳號的所有資訊
$entries = ldap_get_entries($ldapconn, $result);
}
} else {
echo "認證失敗...";
}
}
?>

2011年1月28日 星期五

[引用]PHP: pcntl_signal

PHP: pcntl_signal - Manual
Note: Currently, this module will not function on non-Unix platforms (Windows).
來源

<?php
// tick use required as of PHP 4.3.0
declare(ticks = 1);

function sig_handler($signo) // signal handler function
{
switch ($signo)
{
case SIGTERM: // handle shutdown tasks, kill, kill -15
print "SIGTERM\n";
break;
case SIGHUP: // handle restart tasks, kill -1
print "SIGHUP\n";
break;
case SIGUSR1:
print "SIGUSR1\n";
break;
case SIGINT: // ctrl + c
print "SIGINT\n";
break;
default: // handle all other signals
print "Other:$signo\n";
}
}

echo "Installing signal handler...\n";

// setup signal handlers
pcntl_signal( SIGTERM , "sig_handler" ); // kill or kill -15
pcntl_signal( SIGHUP , "sig_handler" ); // kill -1
pcntl_signal( SIGUSR1 , "sig_handler" ); // self
pcntl_signal( SIGINT , "sig_handler" ); // ctrl+c

//echo"Generating signal SIGTERM to self...\n";

while( 1 )
{
echo ".";
sleep( 1 );
}

// send SIGUSR1 to current process id
//posix_kill(posix_getpid(), SIGUSR1);

echo "Done\n"

?>

執行前需留意,上述程式已經擷取 ctrl+c 的訊號,在 Unix 環境中,需使用 kill -9 的訊號來終止他:

$ php t.php

接著在 Unix 上可以用 pa aux | grep 'php t.php' 查看剛剛那隻的 pid,接著可以用 kill 指令去操控他囉!

簡單用 awk 處理,可自行把 system( "kill " $2 ) 更新為 system( "kill -9 " $2 ) 等模式

$ ps aux | grep 'php t.php' | awk 'match( $11,"php" ) && match( $12 , "t.php" ) {system( "kill " $2 )}'

依序用 Ctrl+C , kill -1, kill -15, kill -9 的訊號

$ php t.php
Installing signal handler...
....^CSIGINT
.....SIGHUP
....SIGTERM
...已砍掉

2011年1月25日 星期二

[PHP]讀取多筆 RSS feed

來源網站

<?php
//RSS源地址列表數組
$rssfeed = array("http://www.blog-dragon.com/feed",
"http://rss.sina.com.cn/news/allnews/sports.xml",
"http://ent.163.com/special/00031K7Q/rss_toutiao.xml",
"http://tech.163.com/special/00091JPQ/techimportant.xml");

//設置編碼為UTF-8
header('Content-Type:text/html;charset= UTF-8');

for($i=0;$i<sizeof($rssfeed);$i++){//分解開始
$buff = "";
$rss_str="";
//打開rss地址,並讀取,讀取失敗則中止
$fp = fopen($rssfeed[$i],"r") or die("can not open $rssfeed");
while ( !feof($fp) ) {
$buff .= fgets($fp,4096);
}
//關閉文件打開
fclose($fp);

//建立一個 XML 解析器
$parser = xml_parser_create();
//xml_parser_set_option -- 為指定 XML 解析進行選項設置
xml_parser_set_option($parser,XML_OPTION_SKIP_WHITE,1);
//xml_parse_into_struct -- 將 XML 數據解析到數組$values中
xml_parse_into_struct($parser,$buff,$values,$idx);
//xml_parser_free -- 釋放指定的 XML 解析器
xml_parser_free($parser);

foreach ($values as $val) {
$tag = $val["tag"];
$type = $val["type"];
$value = $val["value"];
//標籤統一轉為小寫
$tag = strtolower($tag);

if ($tag == "item" && $type == "open"){
$is_item = 1;
}else if ($tag == "item" && $type == "close") {
//構造輸出字符串
$rss_str .= "<a href='".$link."' target=_blank>".$title."</a><br />";
$is_item = 0;
}
//僅讀取item標籤中的內容
if($is_item==1){
if ($tag == "title") {$title = $value;}
if ($tag == "link") {$link = $value;}
}
}
//輸出結果
echo $rss_str."<br />";
}
?>