imagecreate()
, imagettftext()
, imagesetpixel()
這些 PHP functions。聽說這支程式「曾經」是可以 work 的,不過在我手上就不 work,為了證明不是人品問題,一定要把這個 bug 修掉!一開始我傻傻的在程式碼裡面翻找,但這樣實在太沒效率了,身為一個專業的....呃...雜工,一定要懂得善用工具!所以我用了..... command line php.....
$ php image.php > /dev/null
對啦,只不過是測試環境從 apache 換到 command line 底下了,這樣是有比較強嗎?有喔~因為我的測試環境有裝 xdebug,只要有 enable 就可以在 command line 底下看到 debugging messages,不用特別打開 stack trace。至於最後面把 standard output 導向 /dev/null
是為了不想看到他輸出的那張不完整的圖,那會干擾畫面。首先第一步,我忘記詳細的訊息了,大意是說
imagecreate() is undefined
等等,這時候當然要去找找這函式有沒有需要什麼相依的 library 啊!找了一下發現,這些函式是由 PHP 的 GD module 所提供的,所以我迅速的安裝了 GD 模組...$ sudo apt-get install php5-gd
接著,才是重頭戲的開始....裝好 GD 模組之後,那些 function 都可以使用了,但是我卻一直收到這個錯誤訊息....
PHP Warning: imagettftext(): Could not read font .....(後略)
當然這訊息也是伴隨著 stack trace 的,看看傳進去的字型參數,用的是相對路徑 include/font/font.ttf
,當下懷疑是不是找不到檔案,用 realpath()
來幫忙看看...echo realpath($font_path);
但是,咦,怎麼什麼都沒出現?大概花了 30 秒我才發現我做了蠢事....我已經把 standard output 丟掉了啊XD 上網找了一下「php stderr」立刻找到應該要這樣做file_put_contents('php://stderr', realpath($font_path));
印出來之後,發現我給他的路徑是正確的,怎麼會這樣呢?苦惱許久,才想到要去查查 imagettftext() 的 manual,發現了驚人的事情!原來,某些版本的 GD 會在你給他的路徑是相對路徑時,使用環境變數
GDFONTPATH
當作前綴,並且在最後補上 .ttf
。另外,版本低於 2.0.18 的 GD 還不允許路徑裡面有空白字元。檢查了一下...嗯,路徑沒有空白字元,那會不會是路徑問題?參考官方 manual 提供的 sample code:<?php
// Set the enviroment variable for GD
putenv('GDFONTPATH=' . realpath('.'));
// Name the font to be used (note the lack of the .ttf extension)
$font = 'SomeFont';
?>
我自己設定好了正確的 GDFONTPATH
也把後面的 .ttf
拿掉,依然不 work....到這裡我已經快崩潰了....即使我發瘋似的交叉測試拿掉或加上 .ttf
、更改路徑、使用絕對路徑等等,都還是失敗。接著我又開始想,會不會是別的原因?來看看檔案權限好了....
$ ls -l include/font/font.ttf
很好,檔案權限是 644 (rw-r--r--
),應該沒問題吧?算了,死馬當活馬醫,改成 777!!$ chmod 777 include/font/font.ttf
可想而知,還是炸了.....在網路上找來找去,碰到類似問題的人大多是這幾種狀況:
- 路徑錯誤 (前面提到的相對路徑問題)
- 檔案從 windows 傳到 un*x 上就無法 work 了 (因為 un*x 對檔名是 case-sensitive 的)
- 把
ttf
寫成tff
(這是他自己耍笨了...)
$ php -i
...
gd
GD Support => enabled
GD Version => 2.0
FreeType Support => enabled
FreeType Linkage => with freetype
FreeType Version => 2.4.8
T1Lib Support => enabled
GIF Read Support => enabled
GIF Create Support => enabled
JPEG Support => enabled
libJPEG Version => unknown
PNG Support => enabled
libPNG Version => 1.2.46
WBMP Support => enabled
Directive => Local Value => Master Value
gd.jpeg_ignore_warning => 0 => 0
...
就沒問題嘛 orz我已經確定我的路徑是完全正確的,而且也是絕對路徑,檔案權限也確定是可以讀取的,GD module 看起來沒有什麼錯,那到底是什麼問題?心灰意冷之際,我想說不然拿現有的其他字型來試試看好了。事實上該專案裡本來有好幾個字型檔,我早就試過幾個都不 work,結果沒想到改成用自己系統本來有的字型,就成功了!太崩潰了!!! 可是還是很高興,立馬回到本來的程式上,加上剛剛使用的字型的絕對路徑,一切都搞定了!(超開心)
所以總結而言,我一開始的環境沒辦法正確執行這個程式,只有兩個原因
- 缺少 php-gd
- 字型檔有某種錯誤
file
去看他還是個正常的 True Type font 啊....$ file font.ttf
font.ttf: TrueType font data
會不會跟編碼有關係呢?可是我用的只是一個 "1"
耶.....好吧,雖然還是帶著懷疑,不過主要的問題算是解決了,結案!!!
搜索到这里,同样的问题。最后发现,是FTP的上传编码问题,字体文件必须使用ASCII模式上传。
回覆刪除感謝你 :) 由於事情久遠,我也無法回去確認了。不過說不定真的是我上傳的時候把字體給搞壞了....
刪除謝謝您的文章~
回覆刪除