如果你看到下列一段標籤,你覺得它會不會向伺服器做要求的動作呢?
<img src=””/>
答案是會的,但沒有src屬性,它要向伺服器要求什麼東西?實際上就是這個標籤所在的頁面,例如,如果它存在index.html,那麼伺服器的存取記錄除了會有一筆get index.html記錄之外,還會額外有一筆get index.html的記錄。也就是說這index.html因為img標籤的空白src屬性而重複存取了一次。
這重複的存取,而且人無法主觀察覺的,會造成什麼影響呢?對於那些以頁為單位進行資料庫操作,例如insert、update、delete,或者是擷取$_POST到$_SESSION裡,在這種情況下就會有出乎意料的狀況發生。
在資料庫操作方面,因為update和delete經常伴隨著特定條件,按理說,即便存取兩次應該也是針對相同的記錄,但麻煩的就是在於變更的資料是否正確,例如如果資料來自$_POST,在第二次存取的時候$_POST的資料是空值,因為可能就會導致update資料成為空值,而delete則可能因為特定條件在第一次存取即刪掉資料,第二次可能也因為特定條件是空值,而不會執行成功。至於insert,如果新增的資料並沒有限制在唯一值,那麼insert很顯然會執行兩次,但第二次可能新增的是空白記錄,如果有唯一值的限制而且第二次仍然有值,那麼第二次自然無法執行成功。
而如果該頁面進行的是從$_POST擷取資料到$_SESSION或COOKIE裡,第二次的存取因為$_POST是空值,所以$_SESSION或COOKIE就會被清空。
所以綜合以上發現,我們針對img的src屬性最好是能夠給予一個預設值,在它可能是空白的情況下補上,其次是針對擷取$_POST資料,一定要養成習慣先判別它確定是有資料的才繼續操作。
而針對能夠發現瀏覽器針對空白src屬性的此一特殊行為,我想也順便補充一下關於針對非程式語言的除錯作法。實際上這個特殊狀況和程式語言完全無關,所以先前針對語法的除錯完全是沒有意義的,但會發生問題其實一定是有原因的,所以這時候用刪除法是很有用的,也就是善用註解來找出發生問題的敘述。
很有趣的是,我在找到這個問題的原因時,因為是使用樣版物件templatePower,而且也發現就是在將樣版輸出時產生的問題,所以一度以為是樣版的關係。當然這也完全還是在針對程式在除錯的作法。當發現是輸出的html語法時,我還是以為可能是因為頁面上可能有ajax向伺服器做查詢才導致$_SESSION消失,但找了半天都沒發現相關的語法,最後再藉由逐段、逐層註解掉html標籤,最後發現問題是出自於<img src=””/>,最後再搭配檢查apache的存取記錄才發現這個特別的行為。
在此之前,我完全不知道<img src=””/>會讓瀏覽器有這種特別的行為,也不知道是否有編輯器會針對這個狀況來做提醒,而現在發現這個狀況之後,而且用人工除錯的角度來檢討,我想如果一開始就能以刪除法來找出問題發生的片段,再來進一步針對該片段進行除錯,效率可能會大幅提升,而不要一味的從程式語法上檢查。