Skip to content

Zeroplex 生活隨筆

軟體開發、伺服器和生活瑣事

小 縮小字型大小。 中 重設字型大小。 大 放大字型大小。

月份: 2017 年 10 月

PHP curl 的一些特性

Posted on 2017 年 10 月 9 日2021 年 3 月 12 日 By 日落 在〈PHP curl 的一些特性〉中尚無留言

curl 在 PHP 中是以 extension 形式存在,所以只能透過 resource reference 去操作 curl 行為,沒辦法透過 debug 工具摸清楚 curl 在背景到底做了哪些事情。

手癢用 memory_get_usage() 看了一下 curl 在 init、exec 以及 close 這幾個狀態的記憶體使用量,來猜測 curl 到底怎麼運作。

echo memory_get_usage() . "n"   // 236136;

$ch = curl_init();
var_dump($ch);                   // resource(4) of type (curl)
echo memory_get_usage() . "n";  // 237472

在 init_curl() 以後,會先在記憶體中 allocate 並放一些資料,所以吃掉大概 1 KB 左右的記憶體,再將 curl 的 reference 傳出來給 $ch。

接下來這邊讓 curl 去 http://assets.blog.zeroplex.tw/2017-07/php-bench-v2.html 抓一個大小 128 KB 的網頁,並看一下記憶體使用量:

echo memory_get_usage() . "n"  // 235744;

$ch = curl_init();
echo memory_get_usage() . "n";  // 237072

curl_setopt($ch, CURLOPT_URL, "http://assets.blog.zeroplex.tw/2017-07/php-bench-v2.html");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

curl_exec($ch);
echo memory_get_usage() . "n";  // 371784

curl_close($ch);
echo memory_get_usage() . "n"  // 235928;

var_dump($ch);                  // resource(4) of type (Unknown)

由整個記憶體使用量,可以看出在 curl_exec() 之後,會把傳回來的資料除存在記憶體中,除了網頁 128KB 的內容以外,可能還包括一些與 HTTP 連線有關的資料,所以記憶體使用量增加了 130 KB (371784 – 237072 = 134712) 左右。這些資料存在於記憶體中,直到呼叫了 curl_close() 才會釋放掉。

比較有趣的是 PHP 官方文件只有提到 curl_close() 會關閉 session,但是沒有提到用來儲存 resource 的 $ch reference 會如何。上面可以看到 curl_close() 以後,其實 resource refence 還存在,只是 resource 已經被 released,所以 type 顯示為 unknown。

由此可知,沒有 unset($ch) 還拿原來的 resource reference 亂用的話應該會大爆炸 XD

最後來看一下,如果沒有做 curl_close() 就一直做 curl_exe() 抓多個網頁,到底會不會有 memory leak 問題發生:

for ($i = 0; $i < 10; $i++) {
    curl_exec($ch);
    echo memory_get_usage() . "n";
}

執行結果如下:

369424
369976
372568
370856
372568
372568
372568
372568
370856
372568

所以看起來每次執行 curl_exec() 之前,curl 會自動將上一次的 response 清掉在重新做 request,所以記憶體不會無止境的增加。換而言之,如果今天有很複雜的 curl_setopt() 要處理,可以不用一直 reset curl 也不會有問題,setopt 只要做一次就可以了,可以省下一些時間。

原本想要測試一下 keep alive 的效果如何,但是沒有較為穩定的環境來測試,所以這邊就先跳過了。但大家可以參考 StackOverflow 上面的這篇「Persistent/keepalive HTTP with the PHP Curl library」來設定 keep alive。

Tags:PHP, 資訊學習

使用 VCS 時程式中不應該出現的東西

Posted on 2017 年 10 月 3 日2021 年 3 月 12 日 By 日落 在〈使用 VCS 時程式中不應該出現的東西〉中尚無留言

這件事情應該要從 FreeBSD 6 左右的 make build world && make install world 開始說起。每次 build world 以後,新版的 tool chain 設定檔可能都會有小部份的更新,可能是多幾個功能可以設定,或是把一些舊的功能拔掉,這時 install world 時為了擔心使用者改過的 config 檔直接被覆蓋掉,都會先做一次 diff 讓使用者確定設定檔更新以後不後搞垮系統。但有半數以上的 diff,均為 config 中開發人員的註解,像是「2005/xx/xx 最後更新」之類的,單單處理這類的 diff 就可以耗掉數十分鐘。

現在大家在寫程式時,應該都有習慣將 source code 放進 version control system (VCS) 中,方便做版本管理以及除錯。VCS 除了能夠協助開發者幫不同的修改留下記錄以外,也支援版本之間的比較、建立補丁 (patch) 等功能,讓開發者可以專心在功能的開發上。

既然 VCS 已經協助開發者記錄了這麼多東西,那有哪些是開發者已經不需要寫在 source code 裡面的呢?

  • 日期:大多數的 VCS 在開發者 commit 時就會記錄日期,開發者有修改時不必特別在程式中註解修改日期,只要 commit 時將 commit message 寫好讓其他人看得到、搜尋的到即可。
  • 作者:每個開發人員在 VCS 都會被視為不同的 commitor,所以哪個 commit 是誰送、甚至哪一行是誰修改的都有記錄。把修改原因寫清楚比較重要。
  • 註解掉不使用的程式碼:因為 VCS 會保留從古到今所有的程式碼異動,所以大可不用擔心程式碼刪除以後無法還原,若發現某一段程式已經不再使用了,就放心的把他刪掉吧,萬一誤砍了還是可以透過 VCS 復原回來。(如果 VCS 做不到這個功能就換一個吧 XD)
  • 與專案無關的 binary:大多數 icons、font、design files 都會與專案的版本一起演進,放進 VCS 是應該的。但與專案週期不同、或為一次性用途的 binary 檔案,如週年慶的活動圖片設計、影片等,就不適合放進 VCS,若真的有版本管理需要,應該另外開一個 repository。
  • symbolic link:恩 …. 有事嗎?
Tags:生活雜記, 資訊學習

文章分頁

上一頁 1 2

其他

關於我  (About me)

  文章 RSS Feed

  留言 RSS Feed

Apache AWS Bash C/C++ Docker FreeBSD GCP Git Google Java JavaScript Laravel Linux Microsoft MSSQL MySQL Nginx PHP PHPUnit PostgreSQL Python Qt Ubuntu Unix Vim Web Windows WordPress XD 作業系統 分享 好站推薦 專題 攝影 新奇搞笑 新聞 旅遊 生活雜記 程式設計 網路架站 網頁設計 資訊學習 資訊安全 遊戲 音樂


創用 CC 授權條款
本著作係採用創用 CC 姓名標示-相同方式分享 4.0 國際 授權條款授權.