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

2014-12-22

PHP 遇到 Cannot send session cache limiter - headers already sent

PHP 專案在本機正常,到了正式機就鬼打牆,「本機沒事啊」,這應該是工程師最常講得一句話吧。

出現以下的錯誤:
headers already sent (output started at ...config.php:1) in ...config.php on line 5
程式看了半天,session_start() 也搬到不能再前面了,還是爛去。

Google 了半天,最後,還是它 xxx 的 Windows 問題,比爾先生,您為何要造這麼多孽呢?

我的 config.php 沒問題,上到正式機,PM 打開 config.php 修改設定後,就會出現以上的問題。

問題在,PM 是用記事本編輯的,然後多事的 Windows 就在檔案最前面加上 BOM,懶得去瞭解這是什麼鬼。

BOM 在大部分的 php 功能裡不會有什麼傷害,直到用了 header(...) 就爆了!

因為 BOM 是純文字,看不到的純文字,會直接輸出,然後 php 用 header(...) 時就有意見了,在呼叫 header(...) 之前,不可以有任何輸出,否則就是上面那段錯誤訊息出來說嗨。

兩個解法:

第一,修改 php 設定,允許 header(...) 之前輸出,加上 output_buffering = 4096 ,再重起 Apache,就可以了。

第二,用比較厲害的文字編輯器,我是用 EditPlus,開啟然後另存,可以在 Encoding 選項裡看到 UTF-8 與 UTF-8 + BOM,選 UTF-8 就沒事了。


2013-11-15

No HTML/CSS/Javascript Editors in Eclipse ADT (Eclipse for Android) !!!

一般在 Android 開發 App 不太會遇到 HTML, CSS 或者 Javascript 之類的 Web 檔案,但是在遇到 Phonegap 之後就有這個需求了!

可是 Eclipse ADT(adt-bundle-windows-x86-20131030.zip)沒有內建 Web Editor,這真的有點傷腦筋。

Google 沒結果,不是安裝了官方的 plugin 之後出現找不到 JSF class 的問題,就是要安裝 3rd party 的 plugin。

今天運氣不錯,一下子就解決了!

Eclipse > Help > Install New Software...

Work With 選 Juno - http://download.eclipse.org/releases/juno

下方勾選 Web, XML, Java EE and OSGi Enterprise Development 下的 Eclipse Web Developer Tools 和 JavaScript Development Tools 就可以了。

事實上,之前的 PHP Eclipse 也是這麼做的,網路下載的 PHP Eclipse 很多問題,後來是用 Eclipse Standard 版,然後再安裝 PHP 功能搞定的。

2012-07-17

Java 腦袋學 PHP Date

日期時間有兩種存在方式,秒數與字串,或者說是數值與字串,或者說是給電腦看的或給人看的。

存到資料庫的用數值,頁面呈現的用字串。

2012-06-20

處理 PHP 上傳檔案

共用程式如下:
class Photo {

  public static $TABLE = 'bx_photo';
  public static $FIELDS = array(
  array('uuid','string'),
  array('name','name'),
  array('mime','mime'));

  public $id;
  public $uuid;
  public $name;
  public $mime;
  // transient
  public $tmp_name;

  public static function create($array) {
    // 將 $_FILE 裡的資訊讀入
    $p = new Photo();
    $p->mime = $array['type'];
    $p->name = $array['name'];
    $p->uuid = md5(uniqid());
    $p->tmp_name = $array['tmp_name'];
    return $p;
  }

  /*
   * 存檔:先存圖片檔到 FileSystem,再存到資料庫
  public static function sync($obj) {
    try {

      // 檢查 FileSystem 目錄
      if (!is_dir(BaseConfig::$PHOTO_PATH)) {
        mkdir(BaseConfig::$PHOTO_PATH);
      }

      // 存檔路徑
      $newPath = BaseConfig::$PHOTO_PATH.$obj->uuid;

      // 存檔
      if (move_uploaded_file($obj->tmp_name, $newPath)) {
        // 存檔成功
        // 更新到資料庫
        $con = Base::get();
        $con->beginTransaction();
        if (isset($obj->id)) {
          $st = $con->prepare(Base::createSql(self::$TABLE, self::$FIELDS, false));
        }
        else {
          $st = $con->prepare(Base::createSql(self::$TABLE, self::$FIELDS, true));
        }
        $st->execute(Base::setParams(self::$FIELDS, $obj));
        $con->commit();
      }
      else {
        // 存檔失敗
        echo "Can't move the uploaded file!";
      }
    }
    catch (Exception $e) {
      echo 'Database error: '.$e->getMessage();
      $con->rollback();
    }
  }
}
實際引用:
$photo = Photo::create($_FILES['upload']);
// 也許可以做些處理,然後再存檔
Photo::sync($photo);

在 CKEditor 加入上傳圖片的功能

在官方網頁提到有這功能,可以上傳也可以瀏覽伺服器端的圖片庫。
CKEDITOR.replace( 'editor1',
    {
        filebrowserBrowseUrl : '/browse.php',
        filebrowserUploadUrl : '/upload.php'
    });
範例講得很簡單,但是怎麼就找不到 browse.php 與 upload.php,搞半天,原來這兩隻後端程式要自己寫。

在動手之前,先搞清楚 CKEditor 有三個地方可以上傳或瀏覽。
  • 連結
  • 圖片
  • Flash

執行時停用 magic_quotes_gpc?

今天終於遇到這個問題,用 CKEditor 上傳圖片後,到前台看不到圖片,只看到一些亂亂的字元,先確認資料是否有進到資料庫,發現資料裡的 html 變得一團亂,當下直覺應該是這個 Magic Quotes 搞的鬼。

本機測試沒事,正式環境才會出錯,所以去 phpinfo() 看看,果然,正式機的 magic_quotes_gpc 被打開了。

但這是共用的環境,不能隨便修改 php.ini,就想到用 ini_set 在執行時做修改,但沒效,後來想想也對,當程式進到 php 頁面時,$_GET 等變數都已經就定位了,所以設了也沒用。

2012-06-17

Apache Alias, Directory, Options, AllowOverride, Order, Allow, Deny 設定

Apache mod_alias 提供好幾個 directives:
  • Alias
  • AliasMatch - Regular Expression 版的 Alias
  • Redirect
  • RedirctMatch - Regular Expression 版的 Redirect
  • RedirectPermanent、RedirectTemp、ScriptAlias、ScriptAliasMatch
今天只想知道 Alias,將特定 url 指向非 Apache 預設的目錄,就是 DocumentRoot 以外的目錄,這是很合理的需求,畢竟每個專案不會想都放在 Apache 的目錄裡。

2012-06-14

使用 Mediawiki zhconverter 進行 PHP 網頁簡繁互轉

簡繁互轉用的是 Mediawiki 與 Mediawiki zhconverter,再搭配 PHP 特有的 ob_xxx 就可以辦到了。

先下載 Mediawiki1.13.3,目前知道最新版 1.19 在搭配 Mediawiki zhconverter 會有問題,所以不介意的用了舊版的 1.13.3。

再去下載 Mediawiki zhconverter,只有一隻 PHP,就是 mediawiki-zhconverter.inc.php。

將 Mediawiki1.13.3 與 mediawiki-zhconverter.inc.php 放到合適的位置後,就可以開始寫程式了。

2012-06-08

動態修改 php.ini 設定值(ini_set)

想要用 error_log 吐出除錯訊息,但是測試環境的 error_log 沒有設定。

可以在 php 一開始,或者在呼叫 error_log 之前,執行:
ini_set('error_log', 'php_errors.log');
問題就解決了,更棒的是,影響的範圍僅止於該 php 檔案,不會影響他其他 php 檔案,也在執行結束後自動復原。

2012-06-07

PHP 中文變亂碼了

在本機表單輸入中文都沒有問題,上傳到測試環境就變成 ???。

依照在 Java 的經驗,頭開始痛起來。

幸好問題不難找,先到 phpmyadmin 直接輸入一筆資料看看,哇,亂碼,運氣真好,兇手是資料庫。

在 PHP 遇到「Cannot modify header information - headers already sent by」的錯誤

在本機實做時沒有問題,一上傳到測試環境光開登入畫面進行登入就出現「Cannot modify header information - headers already sent by」這樣的錯誤。

原來 login.php 裡在 <?php ... ?> 之前有空白行,而且 login.php include 的 base.php 裡在 <?php ... ?> 之後也有空白行,所以當登入成功後,使用 header 進行 redirect 時,PHP 就報錯。

PHP 規定在 header 進行 redirect 之前不可以有任何 output,所以我的空白行就是兇手之一,保險的作法就是拿掉 redirect 之前所有的空白行。

2012-06-06

使用 PHPMailer 寄送需要驗證的 SMTP Mail - 以 Gmail 為例

PHP 內建的 mail() 不支援 SMTP 驗證,若使用 PEAR 的 Mail 又需要額外的權限,這時 PHPMailer 就是一個不錯的選項。

先去下載 PHPMailer,目前版本是 5.1,解壓縮後,複製 class.phpmailer.php 與 class.smtp.php 到專案裡。

2012-06-05

啟用 Windows 版本 Apache 2.2.15 的 SSL

先安裝 httpd-2.2.15-win32-x86-openssl-0.9.8m-r2.msi。

啟用過程分成三部份:修改設定檔、建立目錄與檔案、以及產生憑證。

修改設定檔

有三個檔案要做修改,分別為 conf/httpd.conf、conf/extra/https-ssl.conf 與 conf/openssl.cnf。

從哪進入這一頁?

PHP 用 $_SERVER['HTTP_REFERER'],Javascript 用 document.referrer。
要小心若是沒有 $_SERVER['HTTP_REFERER'],像是首頁,或是來自我的最愛,要先用 isset() 判斷,否則會出錯。
// Javascript
alert(document.referrer);
// PHP
alert('<?php echo $_SERVER['HTTP_REFERER'] ?>');
// java
alert('<%= request.getHeader("referer") %>');

2012-06-02

Java 腦袋學 PHP Web Form Page

form.php


<?php include 'inc/base.php' ?>

<?php
// PHP 自動提供 $_GET、$_POST、$_ENV、$_COOKIE、$_SERVER、$_FILES 等多個 global 陣列
// 不要用 register_globals 將上述陣列的 key/value 轉為 global 變數,很危險的
// 盡量用明確的 $_GET 或 $_POST,不要偷懶用 $_REQUEST
// $_REQUEST 依照 variables_order 定義的順序,依序將 $_GET、$_POST、$_ENV、$_COOKIE、$_SERVER 多個陣列整合成單一陣列

2012-05-29

在 PHP 使用 mysql_connect()

第一次嘗試使用 mysql_connect()。
echo mysql_connect('localhost', 'root', 'root');
結果得到以下的錯誤訊息:
Fatal error: Call to undefined function mysql_connect() in ....php on line 3
Google 結果發現沒有啟用 php_mysql.dll,到 php.ini 啟用。
extension=php_mysql.dll
拿掉前面的分號,重起 Apache 再試一次,得到另一個錯誤訊息:
Warning: mysql_connect() [function.mysql-connect]: [2002] 連線嘗試失敗,因為連線對象有一段時間並未正確回應,或是連線建立失 (trying to connect via tcp://localhost:3306) in....php on line 3
再 Google 一下,這次問題比較難找,最後發現是 hosts 裡沒有以下這筆對應紀錄:
127.0.0.1 localhost
加上這筆對應就可以了,也可以在 mysql_conncect() 改用 127.0.0.1。

在 Apache 與 PHP 遇到 403 Forbidden

啟動 Apache 輸入網址 http://localhost/install/,得到以下的錯誤訊息:
Forbidden
You don't have permission to access /install/ on this server.
先檢查 PHP 在 httpd.conf 裡的設定:
Alias /install/ "D:/Web/install/"

    Options FollowSymLinks
    AllowOverride None
    Order allow,deny
    Allow from all
應該沒有錯。

Google 後發現錯在 DirectoryIndex,沒有設預設的檔案名稱。

    DirectoryIndex index.html
在 index.html 後面加上 index.php 就可以了。

    DirectoryIndex index.html index.php
當然也可以不修改,在網址明確輸入 /install/index.php 也行得通。

2012-05-28

Java 腦袋學 PHP OOP

PHP Object-oriented programming 在 5 以後的版本增強不少,對 Java 腦袋來說已經很接近了,尤其 OOP 用的 keyword 幾乎和 Java 的一樣,最大的闕漏在還沒有 package。

2012-05-24

Java 腦袋學 PHP Function

PHP 是解析完整個檔案後才開始執行,所以 function 的呼叫可以在定義之前。

PHP function 的參數傳遞:
  • 物件參數:Passed by reference
  • 物件以外的參數:Passed by value
誰不是物件:字串、數值、日期以及最容易搞錯的陣列。

2012-05-23

Java 腦袋學 PHP Variables

依照變數的狀態可以區分成 set 與 unset 兩種,set 變數依照值可以再區分成兩類,值為 true 或為 false。
  • set - 有值的變數。
    • true - 可以視為 false 以外的值皆可視為 true,包括字串"00"以及空白字元" "。
    • false - 可以視為 false 的值有 0、0.0、空字串、字元 0、false、空的陣列、無屬性的物件以及 NULL。
  • unset - 無值的變數,被 unset 或者設為 null。