歡迎來到小豬圈!

2009-04-29

在 Google App Engine 上執行 PHP

  • 執行 PHP 是我申請 Google App Engine 的主要目的,利用 Quercus 執行簡單腳本是沒有問題。但麻煩的是 Datastore 的部份,不但沒辨法用 PDO 存取,而且 Datastore 也跟關聯式資料庫差很多,存取資料庫的部份基本上得要重寫。
  • 另一個麻煩是,我在 Java 5 發行之前就沒有再接觸 Java 了,熊熊看不懂 JDO Annotations 跟 JPA 這些 Java 5 以後的新功能(囧),不過還算是小事就是了。
  1. Caucho Technology » Blog Archive » Quercus on the Google App Engine
  2. Annotations (The Java™ Tutorials > Learning the Java Language > Classes and Objects)
  3. Introduction to the Java Persistence API - The Java EE 5 Tutorial

2009-04-28

申請到了 Google App Engine 試用

  • 日前在看到 Google App Engine 支援 Java 的消息同時,才知道這世界上有人實作 PHP in JAVA,一個叫 Quercus 的東西。雖然是個詭異的產品,不過這種情況(GAE不支援PHP)還真的派的上用場。
  • 雖然我申請時沒辨法收到 Google 的認證簡訊 (SMS),不過再回報後兩天還是成功啟用。
  1. Scribe's N.E.W. Studio://Blogger: Google App Engine supports Java
  2. Caucho Resin : Reliable, Open-Source Application Server
  3. http://appengine.google.com/waitlist/sms_issues

2009-04-25

用字串索引存取陣列要加上引號

  • 陣列的索引是字串型態的話,一定要加上引號,雖然不加引號也可以執行,但 PHP 會先嘗試以常數去解譯,所以可能產生預料外的結果。而如果沒有對應到的常數,再嘗試以字串解譯,並同時會輸出 E_NOTICE 影嚮效能。
  • 整數的索引也可以用字串(加引號)的方式取存,但用整數存取速度比較快。
  • 在建立陣列或其項目時,索引是十進位的數字的話會自動轉成整數。
  • 
    <?php
    define('string_index''unexpected');
    
    $a = array(
      'string_index' => 'string_index',
      'unexpected' => 'unexpected');
    $b = array(
      '-1'  => 0,
      '1'   => 1,
      '02'  => 2,
      '0x3' => 3
    );
    
    
    echo $a['string_index']; // output: string_index
    echo $a[string_index];   // output: unexpected
    
    var_dump($b);
    /* output
    array (
      -1 => int 0
      1 => int 1
      '02' => int 2
      '0x3' => int 3
      )
    */
    ?>
    
    
  1. PHP: Arrays - Manual
  2. 数组非数字键名引号的必要性 | 风雪之隅

2009-04-22

將字串分割為字元陣列

  • PHP 支援用陣列的方式存取字串的字元 $string[1] ,但不能直接將字串用在迴圈上。
  • 上述方式與 str_split() 會有中文斷字的問題,preg_split() 沒有加 u (utf-8 mode)修飾字符也會有一樣問題。
  • 這種情況下 mb_split 派不上用場,雖然支援 regular expression 但不能用空的 pattern (不用 start/end delimiter)。
  • 兩個解決方案之一是用 mb_* 自已寫函式處理,另一個就是用 preg_split() 加上 u 修飾字符,見範例:
    
    <?php
    function string_to_array ($string) {
      $array = array();
      $strlen mb_strlen($string);
      for ($i=0$i<$strlen$i++) {
        $array[] = mb_substr($string$i1'UTF-8');
      }
      return $array;
    }
    
    $string '中文字測試';
    
    str_split($string);
    
    preg_split("//"$string);
    
    mb_split(""$string); // Warning: mb_split(): Empty regular expression
    
    preg_split("//u"$string); //This modifier is available from PHP 4.1.0/Unix and from PHP 4.2.3/win32
    
    var_dump(string_to_array($string));
    ?>
    
    

寫 PHP 要注意的事項 效能篇

  • 用 isset 取代 strlen 檢查字串最小長度,見 PHP: Strings - Manual 中 String access and modification by character 一節。
    
    <?php
    $string 'aaabbb';
    $string2 'aaabbbcccddd';
    var_dump((strlen($string) > 9) ?true:false);//false
    var_dump((strlen($string2) > 9)?true:false);//true
    var_dump((isset($string[9]))   ?true:false);//false
    var_dump((isset($string2[9]))  ?true:false);//true
    ?>
    
    
  • 字串用單引號 (') 標示比雙引號 (") 快,但在嵌入超過一、二個變數以上時,情況就相反了。
    
    <?php
    $string '中文字測試';
    $string '中文字' $string '測試';
    
    $string "中文字測試";
    $string "中文字{$string}測試";
    ?>
    
    
  • 在相同結果的情況下,儘量使用字串類函式取代 Regular Expressions 函式
  • 在存取整個檔案時 file_get_contents/file_put_contents 比自已用 fopen 快,remote 的情況似乎相反。
  • is_file 比 file_exists 快四、五倍,不過似乎要注意在大量執行緒下的情況。
  • 用 ++$i 比 $i++ 快,但我測試的結果差距非常小。
  • 優先使用內建常數,再找內建函式,再來才考慮自行運算
    • 用 PHP_VERSION 取代 phpversion(),而用 version_compare() 比較版本。
    • 用 M_PI 取代 pi() ,以及其它 M_* 開頭預先計算好的值。
    • DATE_ATOM 及其它 DATE_* 常數。
  • 陣列的索引是字串型態的話,一定要加上引號,雖然不加引號也可以執行,但會產生 E_NOTICE 影嚮效能。整數的索引也可以用字串(加引號)的方式取存,但用整數比較快,參見:用字串索引存取陣列要加上引號
  • 類別建構式(Class constructor)使用 PHP4 版,跟類別同名的函式,比用 PHP5 版 __construct 快約兩倍,這是我在測試版本相容性時發現的,原因不明。
  1. 榨乾 PHP,不得不轉的一篇PHP使用技巧! - 應用討論區 - PHPChina | 中國開源之路 PHPChina|php論壇|Zend中國 - Powered by Discuz!

2009-04-21

查注音函式

  • 利用 xcin 的表格做查詢注音符號的依據。
    
    <?php
    function findZhuyins($word$cinTable 'bopomofo.cin') {
      static $data null;
      static $keyMap null;
      $result = array();
      if (!$data) {
        $data file_get_contents($cinTable);
        $pattern "/%keyname\s+begin\s+(.+?)\s+%keyname\s+end/uis"//找出按鍵對應字根的區段
        preg_match($pattern$data$matches);
        $pattern "/(.)\s+(.)\s+/ui";
        preg_match_all($pattern$matches[1], $matches );
        $keyMap $matches;
      }
      $pattern "/\n(.+)\s+{$word}/ui";
      preg_match_all($pattern$data$matches );
      foreach ($matches[1] as $key => $value) {
        $ary str_split($value);
        $result[$key] = '';
        foreach ($ary as $value2) {
          $idx array_search($value2$keyMap[1]);
          $result[$key] .= $keyMap[2][$idx];
        }
      }
      return $result;
    }
    var_dumpfindZhuyins("得"));
    ?>
    
    
  • 注音符號的 cin 表格可以到 OXIM 專案的 FTP(ftp://ftp.opendesktop.org.tw/odp/others/OXIM/cin_tables/)下載,cin 表格清單
  • 中文轉注音(PHP)

2009-04-18

寫 PHP 要注意的事項

程式可攜性

  • 使用內建常數 DIRECTORY_SEPARATOR
    
    <?php
    include dirname(__FILE__) . DIRECTORY_SEPARATOR 'some.php';
    ?>
    
    
    大部份情況下直接使用 / 就可以了,除了在展開由系統取得的路徑時,如:
    
    <?php
    var_dumpexplode(DIRECTORY_SEPARATORgetcwd()) );
    ?>
    
    
  • 使用內建常數 PATH_SEPARATOR
    
    <?php
    $path '/usr/lib/pear';
    set_include_path(get_include_path() . PATH_SEPARATOR $path);
    ?>
    
    
  • 使用下列兩種 PHP 標籤 (PHP: Escaping from HTML - Manual):
    
    <?php echo phpversion(); ?>
    
    <script language="php"> echo phpversion(); </script>
    
    
    不要用簡短及 ASP 風格的 PHP 標籤:
    <? echo phpversion(); ?>
    
    <?= phpversion(); ?>
    
    <% echo phpversion(); %>
    
    <%= phpversion(); %>
    
    
  • 以零開頭的整數進位制,見 PHP: Integers - Manual
    
    <?php
    $a 1234// decimal number
    $a = -123// a negative number
    $a 0123// octal number (equivalent to 83 decimal)
    $a 0x1A// hexadecimal number (equivalent to 26 decimal)
    ?>
    
    
  • 在迴圈中使用參照 (reference) 要注意離開迴圈後參照還是有效。
    
    <?php
    $array = array( 'aaa''bbb''ccc');
    foreach($array as &$value) {
      $value $value 'ddd';
    }
    $value 'test';
    var_dump($array); // $array[2] = 'test'
    
    
    $array2 = array( 'aaa''bbb''ccc');
    foreach($array2 as $key => $item) {
      $array2[$key] = $item 'ddd';
    }
    $item 'test';
    var_dump($array2);
    ?>
    
    

2009-04-16

Google Maps 應用實例

2009-04-08

強制下載及預設檔名 HTTP-Header: Content-Disposition

  • 加入 Content-Disposition 這項 header 即可。
  • <?php
    $filename = 'test.htm';
    header("Content-type: text/plain");
    header("Content-Disposition: attachment; filename=$filename");
    readfile($filename);
    ?>

標籤分類

Blog Archive

Labels

Google Analytics Tracking Code

About Me

My photo
Keelung, R.O.C, Taiwan
一個不學無術、混吃等死的傢伙…