bestlong 怕失憶論壇

標題: 當 ECShop 2.7.x 遇上 PHP 5.3 or 5.4 需要自行維護修改的程式地雷 [打印本頁]

作者: bestlong    時間: 2013-6-24 22:02     標題: 當 ECShop 2.7.x 遇上 PHP 5.3 or 5.4 需要自行維護修改的程式地雷

PHP 持續在進展 5.3 >> 5.4 >> 5.5
目前網路主機商可能都還維持在 PHP 5.2.x 的版本
再怎麼能撐也會有極限的時候
雖然看起來 ECShop 2.7.3 正在進行中,但是不確定是否會解決這方面的問題
所以若此時想用 ECShop 建立購物網站的人還真的要考慮一下

自己先將開發環境開始轉換到 WampServer 2.2E 所提供的 PHP 5.3 的版本
也開始展開踩地雷的磨練
遇到什麼狀況會在這裡記錄一下
作者: bestlong    時間: 2013-6-24 22:06

程式 admin/goods_batch.php
  1. /*------------------------------------------------------ */
  2. //-- 取得商品
  3. /*------------------------------------------------------ */

  4. elseif ($_REQUEST['act'] == 'get_goods')
  5. {
  6.     $filter = &new stdclass;

  7.     $filter->cat_id = intval($_GET['cat_id']);
  8.     $filter->brand_id = intval($_GET['brand_id']);
  9.     $filter->real_goods = -1;
  10.     $arr = get_goods_list($filter);

  11.     make_json_result($arr);
  12. }
複製代碼
請將其中的一行

$filter = &new stdclass;

修改成

$filter = new stdclass;

作者: bestlong    時間: 2013-6-29 00:29

運行環境是 WampServer 2.2E 來源網址是 http://www.wampserver.com/en/
也不確定這個問題是否是 PHP 5.3.13 的問題

進入 ECShop 後台的商店設置功能

在 Firefox 得到:
內容編碼錯誤
您嘗試檢視的頁面無法顯示,因為其中使用了無效或不支援的壓縮類型

在 Chrome 得到:
這個網頁無法使用
錯誤 330 (net::ERR_CONTENT_DECODING_FAILED): 未知的錯誤

在 IE10 得到:
Internet Explorer 無法顯示網頁
You are not connected to the Internet. Check your Internet connection

追蹤程式到 admin/init.php 的最後段落
  1. /* 判断是否支持gzip模式 */
  2. if (gzip_enabled())
  3. {
  4.     ob_start('ob_gzhandler');
  5. }
  6. else
  7. {
  8.     ob_start();
  9. }
複製代碼
確認是執行到 ob_start('ob_gzhandler'); 這一行出現問題,只要註解掉就可以出現畫面
該開的 extension 都確認過了

能夠排除問題的方式有兩個:
1. 修改 php.ini 設定 output_buffering = Off 來關掉緩衝能力,不過這會影響到整個伺服器牽扯範圍太大
2. 在執行 ob_start('ob_gzhandler'); 之前先執行 ob_flush(); 先出清緩衝區的殘餘資料

想必大家都會選擇第 2 個方式,所以程式就改成
  1. /* 判断是否支持gzip模式 */
  2. if (gzip_enabled())
  3. {
  4.     ob_flush();
  5.     ob_start('ob_gzhandler');
  6. }
  7. else
  8. {
  9.     ob_start();
  10. }
複製代碼
但是案情並不簡單
因為 ob_flush(); 確實出清了某些資料,卻造成 http header 也送出了
變成在其他功能上得到了另一個錯誤

Warning: Cannot modify header information - headers already sent by ....後略

這下可有趣了,明日再戰
Orz...
作者: bestlong    時間: 2013-6-29 22:47

持續在 WampServer 2.2E (PHP 5.3.13) 環境測試了很久
終於發現是先前改變錯誤報告的設定所造成
我將 admin/includes/init.php 開頭的設定

error_reporting(E_ALL);

修改成

error_reporting(E_ALL | E_STRICT);

想要得到更嚴謹的警告訊息來改善程式品質
看來也間接影響到處理輸出壓縮機制

參考 PHP 官方文件
關於 E_STRICT 常數有備註 Since PHP 5 but not included in E_ALL until PHP 5.4.0
說明了 PHP 5 時代 E_ALL 並不包含 E_STRICT
直到了 PHP 5.4 版本開始就是 E_ALL 就包含 E_STRICT

所以就先還原成
error_reporting(E_ALL);
然後重新思考該如何適當處理了
作者: bestlong    時間: 2013-6-29 23:53

剛去下載 xampp-win32-1.8.2-0-VC9 來測試
有一段時間沒用新版了
發現已經是進入 PHP Version 5.4.16

將 ECShop 程式與資料庫都搬遷好,然後啟動進入前台首頁:

Strict Standards: Only variables should be passed by reference in D:\xampp-1.8.2\htdocs\ecshop\includes\lib_main.php on line 1321

Strict Standards: Only variables should be passed by reference in D:\xampp-1.8.2\htdocs\ecshop\includes\cls_template.php on line 406

喔,遇上了 Strict Standards 訊息,屬於函數參數的傳入型態問題

lib_main.php 出現一次,而 cls_template.php 出現很多次

那就先來解決最多的 cls_template.php 錯誤,就是這一行

$tag_sel = array_shift(explode(' ', $tag));

我改成

$tag_exp = explode(' ', $tag);
$tag_sel = array_shift($tag_exp);

反正就是不要直接用函數回傳值當函數參數
所以要用變數接回傳值,再當參數傳入
要小心的選擇變數名稱,最好先搜尋確認一下,可別影響原本的程式運作

直覺上好像多了變數增加執行負擔,或許會影響效能
不過應該會在 compiler 上做些特別的最佳化處理

至於 lib_main.php 部分的修改,其實觀念都是一樣就不再獻醜了
作者: bestlong    時間: 2013-6-30 00:11

Strict Standards: Non-static method cls_image::gd_version() should not be called statically in D:\xampp-1.8.2\htdocs\ecshop\includes\lib_base.php on line 354

在 lib_base.php
  1. function gd_version()
  2. {
  3.     include_once(ROOT_PATH . 'includes/cls_image.php');

  4.     return cls_image::gd_version();
  5. }
複製代碼
用呼叫靜態方法的程式碼 return cls_image::gd_version();
但是 cls_image.php 內的 gd_version() 並沒有宣告為靜態方法

所以修改 cls_image.php 的

function gd_version()

加上靜態修飾子

static function gd_version()


作者: bestlong    時間: 2013-6-30 17:08

先前有提到進入後台商店設置有問題,那時是在 WampServer (PHP 5.3.13)環境執行
現在轉換到 XAMPP (PHP 5.4)的環境也是一樣的狀況

所以先停用了 php 的壓縮處理,看看有什麼狀況藏在後面
也就是在 admin/includes/init.php 的最後部分
將 ob_start('ob_gzhandler'); 先改成 ob_start();
就可以進入商店設置功能了
此時就有了看到兩個警告

Strict Standards: mktime(): You should be using the time() function instead in D:\xampp-1.8.2\htdocs\ecshop\admin\sms_url.php on line 31

Strict Standards: mktime(): You should be using the time() function instead in D:\xampp-1.8.2\htdocs\ecshop\admin\shop_config.php on line 32

看來影響 ob_start 壓縮的主因應該就是這兩個,因為在 ob_start() 之前就送出了資訊
找到對應的程式行 $auth = mktime(); 都改成 $auth = time();
存檔後再次執行訊息都不見了看來沒問題

再將 PHP 輸出緩衝的壓縮處理給改回來就過關了
作者: bestlong    時間: 2013-7-2 00:01

接下來就是在後台

admin/payment.php?act=list 付款方式

出現超級多的問題,相同的錯誤都取第一個

Strict Standards: Redefining already defined constructor for class alipay in D:\xampp-1.8.2\htdocs\ecshop\includes\modules\payment\alipay.php on line 88

Deprecated: Function ereg_replace() is deprecated in D:\xampp-1.8.2\htdocs\ecshop\includes\modules\payment\smilepayatm.php(2) : eval()'d code(1) : eval()'d code on line 1

歸納起來就以上兩種
第一種幾乎所有付款方式都有,屬於建構式重複定義的問題
第二種大約有 8 項,就是 ereg_replace() 該退休了

該怎麼改呢?
改日有空檔再想吧




歡迎光臨 bestlong 怕失憶論壇 (http://www.bestlong.idv.tw/) Powered by Discuz! X1.5