官方原本要在 2018/12 中止對 PHP 5.x 的支援,但 2019/01 還是發布了 5.6 的更新,自動內容大致如下:
- GD library 的 security fix
- mbstring 的 bug fix
- Phar 的 security fix
- xmlrpc 的 security fix
軟體開發、伺服器和生活瑣事
官方原本要在 2018/12 中止對 PHP 5.x 的支援,但 2019/01 還是發布了 5.6 的更新,自動內容大致如下:
以前大多用 3rd-party library 來拼拼湊湊出自己要使用的功能,近一年狀況比較特殊,幾乎所有東西都要自幹:
$ cd /project/root/src
$ du -sh
148K .
一年的 code 就 150 KB,算是自開始寫程式以來的個人記錄了吧。
希望這 150 KB 的程式是好的程式,而不是垃圾。
今天是測試 Memcache::connect() 踩到的問題。
先來看看文件上的說明:
所以我的程式就這樣寫:
$c = new Memcache();
$stat = $c->connect('localhost');
if (false === $stat) {
echo 'connection failed';
} else {
echo 'connected to cache server';
}
測試時把 Memcached shutdown 來看看是否會偵測到連線失敗。執行時卻噴了一堆錯誤訊息:
Warning: Memcache::connect(): Can't connect to localhost:11211, Connection refused (111) in /home/u/he5702/tmp/asd.php on line 4
Call Stack:
0.0001 355600 1. {main}() /home/u/he5702/tmp/asd.php:0
0.0001 355640 2. Memcache->connect() /home/u/he5702/tmp/asd.php:4
connection failed
文件上面並沒有提到 library 除了回傳 false 以外,還會噴一堆錯誤訊息。萬一這隻是 JSON API 就一定會導致 client parse error。
所以應變方法用「@」來隱藏錯誤訊息:
$stat = @$c->connect('localhost');
寫程式真的很怕遇到 undefine behavior,如果文件上都寫清楚的話,在 dev / staging 上都可以事先檢查、防範。但連文件都沒有寫,就只能等個被廣大的客戶客訴到死 ….。
我還以為 PHP SPL 的類別應該實作上應該有比較嚴謹,但 … 我錯了 QQ
先來看一下 SplPriorityQueue 的官方文件定義:
priority 和我預期的不一樣,原本以為只能放數字 (numbers) 但這邊的 priority type hint 卻標示為「mixed」,表示 priority 可以是任何資料型態 …?
先從最一般的 case 來測試吧:
$q = new SplPriorityQueue();
$q->insert(1, 'A');
$q->insert(2, 'B');
$q->insert(3, 'C');
$q->insert(4, 'D');
$q->insert(5, 'E');
while ($q->count() > 0) {
echo $q->extract() . PHP_EOL;
}
output:
5
4
3
2
1
看起來會用 ASCII 數值來比較,數值大的優先 dequeue。看起來沒問題。
再來看一下遇到相同 priority 中有多個數值時,到底會發生什麼事:
$q = new SplPriorityQueue();
$q->insert(1, 1);
$q->insert(2, 1);
$q->insert(3, 1);
$q->insert(4, 1);
$q->insert(5, 1);
while ($q->count() > 0) {
echo $q->extract() . PHP_EOL;
}
output:
1
5
4
3
2
「5, 4, 3, 2」還算正常,但是為什麼「1」會突然跑到最前面!?
最後,priority 真的可以放其他資料型態嗎?為了更清楚的看到執行結果,我這邊改使用 psysh 來操作:
Psy Shell v0.8.18 (PHP 7.1.18 — cli) by Justin Hileman
Unable to check for updates
>>> $q = new SplPriorityQueue();
=> SplPriorityQueue {#201
heap: [],
}
>>> $q->insert(1, [1, 2, 3]);
=> true
>>> $q->insert(2, []);
=> true
>>> $q->insert(3, new Exception())
=> true
靠北啊,Exception 也可以當作 priority 使用 ….
>>> while ($q->count() > 0) {
... echo $q->extract() . PHP_EOL;
... }
3
1
2
…. 我不想講了。
總之,若你要使用 SplPriorityQueue,請注意 undefined behavior。
Reference: