今天會想到寫這篇的原因,主要在於我在前公司擔任MIS一職時,曾接手處理智冠科技的儲值流程ServerTalk程式,從接收資料到認證回傳一共五道手續,製作內容就不能提了,在程式的習慣上,在我早期不懂事時,我總認為變數直接定義宣告,SQL資料直接拉出來處理就好,頁面上看不到錯誤也就算成功了,後來在處理我很早寫的一支太陽線獎金計算程式時,因為運算越來越慢,我多方查訪才知道原來是變數在宣告上的問題,頁面上雖然不顯示,但是SERVER端的httpd Log會不斷的產生錯誤記錄,當計算達數十萬次時,會造成SYSLOG的Loading而致運算緩慢,這裡我可以做個範例說明為什麼.....

<?php
if ($_POST['action']) {
$aaa = "123";
do another things;
}
?>

這是一個表單接收最常用的例子,頁面顯示一定沒有問題,但是在LOG裡會出現以下的錯誤訊息....

Notice: Undefined index: action 

這個錯誤在一般頁面看不見,但是在設定嚴謹的主機上,會不斷的被記錄下來,不知不覺間造成錯誤,這個原因很簡單,只是警告該變數尚未定義而已,不是什麼大錯誤,有人可能會說,那就在主機設定裡把LEVEL調低就好,少幾個動作不要緊,不過這真的是程式設計師該作的事嗎?? 會造成什麼問題呢....讓我們再接著看下去....

回到一開始提的發現這種錯誤後,我以後在寫任何一支程式時,我一定會在我的Library內加上以下宣告,讓所有錯誤全部浮現,寫出完全無錯誤的程式 ...

ini_set('display_errors', '1');
error_reporting(E_ALL);


所以之前有錯誤的程式我會改變寫法, 比如在取得POST時,我會改寫成...

<?php
$PD = sys_quotes($_POST);
$PD['action'] = isset($PD['action']) ? $PD['action'] : 0;
$PD['action'] = isEmpty($PD['action'])? 0 : $PD['action'];

if (!isEmpty($PD['action'])) {
do something;
}
?>

註:
sys_quotes 是去除跳脫字元或一些特殊字元的function,isEmpty是用來判斷各種不同的空值更嚴謹的函式...
當然遇到大量的資料就改用array來處理...

好了,我這樣寫就萬無一失了,回到前頭,當我使用這種方法很嚴格的判斷每一個接收送出的變數,事情就在我離職後發生了....

某一天,智冠的人員告訴我,為什麼你以前公司的儲值在帳號登入時會失敗,這樣許多儲完值的會員會變成無法正確的儲入點數造成他們很大的困擾,當然我離了職我也不管太多,但基於雞婆,我也是偷偷的了解狀況,首先聽到的是:"某人看了你的程式說你寫的有問題,程式太古老了,所以不能儲值",他再找時間重寫,我開始覺得納悶....

什麼是程式太古老!?

喔!! 原來,程式有古老跟新潮之分,而且古老的程式可以先運行,過了兩個月就因為太古老而老死了,我學了這麼久只有聽過修正或新增語法函式,程式有太古老的我還是頭一次聽見,可能是我學識太淺,孤陋寡聞;但是..我小小的查一下的結果,應該只是有人把我為了查會員資料所做的SQL View表的使用者權限刪掉了而已,因為就算是網站儲值程式,與本身網站運行無關者,我都習慣把需要用到的一兩個表做成View表,只給予select的權限,以確保安全,這個應該是跟程式古老不古老無關吧!! 算了,反正讓他們去弄,我無權過問,只是被人家推拖,我有點不太爽而已....

事實證明,他也沒能力重寫,只說要花很長時間重寫,後來智冠等不了下了通碟,再突然又好了...真是她XX的囧....

到這還是跟前面說的嚴謹沒有關係,因為我太會拖戲了,所以現在才道出最近感受到的無力感.....

最近好不容易有一間公司要我,因為我學歷低常被打槍,就算我有各種技能,看到學歷第一封信一定是收到"閣下條件頗為優良,但很抱歉"等等的字眼,我一進公司就接手公司在全球的數個網站維護之責,當工作了兩三週,我又感到一件事...

如果你現在不好好的把程式規畫好...
你未來就會在不知不覺中搞死別人...

這裡又一樣牽扯到程式嚴謹的問題,每個老程式設計,通常都會有自己的一套函式庫,不管是Javascript || PHP || DB,每種如果要做成套件,就一定要有嚴謹的規畫,像我的設定值,我一定會放在同一支設定檔裡,其餘的設定值就會放在SQL資料庫裡,至於include檔案,我則會在 config.inc.php 裡宣告好網站目錄,但是呢? 別人總不是如此,總是求快,把自己的一套再混進去,多做一個設定檔,當你接到一個過三手的網站時,你就死了......!!

我們用習慣來舉個例,我看到有些人的總是用很簡單的函式來處理SQL執行..

include('../../config.php');
$sql = new sql();
$sql->select($url, $user,  $pass, "SQL Column", "SQL Table", "SQL Conditions", $db);

有時遇到用function處理的..還會看到這樣...

function dosome($arg) {
include('../../config.php');
$sql xxxxxxxxx;
do something;
}

說實在的,我對class的用法沒概念,但是,把這種東西寫在這裡到底有什麼好處呢??...我在說那裡,我在說帳密跟DB名稱之類的東西啦....ㄠ嗚....

你有include config.php是還好,但是當有人混了另一套,用的又是不同變數宣告跟function呢,是不是造成同一個頁面會出現兩個 SQL Connection Link呢?.....我是該去說是誰的錯呢...其實應該都是我自己的錯....因為我居然想把他整合起來.....

以下是我的本來的作法....

在config.inc.php裡:
<?php
#---Define Global Parameters
$Gcfg['SiteRoot'] = $_SERVER['DOCUMENT_ROOT'];
// 其它變數也一併放入 $Gcfg 陣列裡 
#---Define DB Parameters
$DBcfg = array(
"dsn" => "127.0.0.1",
"db" => "dbase",
"name" => "user",
"passwd" => "password",
"prefix" => "sf_"
);
?> 

我在用function時會這樣:

function dosome($arg = "") {
global $Gcfg, $DBcfg;
$query = "SQL QUERY";
getCur($query);
do somethings;
}

這裡可能有人問,怎麼不直接定義全域變數就好了,其實,我是沒用過而且也不知道安全性,所以還是沿用我原先的習慣,可能我以上的用法,有人還有更好的意見指教,但是相信這樣的作法對未來我的接手人,應該會讓他高興的暗爽到好幾天都打混吧....可惜我沒有那個命...

現在...我除了加入了我的用法,還改了好多讓我很無力的東西...

新的config.inc.php:

<?php
#---Define Global Parameters
$Gcfg['SiteRoot'] = $_SERVER['DOCUMENT_ROOT'];
// 其它變數也一併放入 $Gcfg 陣列裡 
#---Define DB Parameters
$DBcfg = array(
"dsn" => "127.0.0.1",
"db" => "dbase",
"name" => "user",
"passwd" => "password",
"prefix" => "sf_"
);

require_once "{$Gcfg['SiteRoot']}/xxxx.php";  <---不再出現好幾層後找不到檔案的錯誤
#---Old Setting #1
$hostname = $DBcfg['dsn'];
$username = $DBcfg['name'];
$passwd = $DBcfg['passwd'];
$basename = $DBcfg['db'];

#---Old Setting #2
$url = $DBcfg['dsn'];
$user = $DBcfg['user'];
$pass = $DBcfg['passwd'];
$base = $DBcfg['db'];

#---Old Setting #3
$db_url = $DBcfg['dsn'];
$db_user = $DBcfg['user'];
$db_pass = $DBcfg['passwd'];
$db_name = $DBcfg['db'];
?>  

改成這樣以後,從此天下太平,你問我怎麼會有三組設定值,我告訴你,你沒看錯,就是有三組,當然之後還要做很多優化,比如把多個不同SQL連線用同一個較優的全部取代,檢查是否有重覆include的檔案,這樣就可以大大的加快網站的執行速度,我也將不再混入我的函式庫,直接找其中一組作法來用,因為要知道,如果沒有用AJAX,PHP網頁是要在主機執行完才會被送出,你多做了多少事,多幾個SQL連線,都會造成主機的負擔,如果網站是一個人氣網站,那可能會造成無謂的浪費,明明頻寬充足,網頁顯示卻異常的慢,作了這些優化,你不但可以省下大量的伺服器硬體昇級支出,也可以節省目前已日漸用盡的網路吧...

程式嚴謹孰是孰非,相信在大家心中都已經有一個自己的定數了...

一個好的程設,是要對自己負責而不是對付錢給你的人....
千萬不要有推拖的心理,趕時間的理由,後面收尾的動作可能會搞死自己,除非你只是一直想寫一些沒有人氣流量的網站...