關于 PHP 的編譯和執行分離

openkk 12年前發布 | 15K 次閱讀 PHP PHP開發

關于讓”PHP的編譯和執行分離”這個問題, 一直有人提, 也一直有人嘗試. 提的人認為編譯執行分離以后, 可以得到性能提升, 可以做代碼保護等.

我本身并不是對這個特性很感冒, 因為這里面存在一個投入產出比. 讓我來給大家解釋一下, 然而不管怎么樣, 在最后我會給大家提供一種方案來實現這個功能.

1. PHP的編譯并不是很耗時

我之前的文章也介紹過, PHP的編譯是線性的編譯過程, 不做任何優化, 所以這個過程非常之快. 而編譯和執行分離這個特性的提出著認為分離以后, 可以省掉編譯過程, 會有很大的性能提升.

2. 開發速度

PHP的一個優點就是開發/部署/調試非常方案, 更改立即見效, 而如果我們采用了編譯/執行分離以后, 那么更改就需要首先編譯, 然后部署, 然后才能生效, 這對于開發來說, 并不是什么好事.

3. 我們有APC/Zend O+等第三方的代碼緩存工具

APC等第三方的代碼緩存工具(Opcodes Cache)已經相對比較成熟, 并對開發者透明, 大家只要在服務器上安裝了APC, 就可以得到編譯/執行分離的性能提升.

當然, 還有一些因素, 比如編譯/執行分離這個方案是有人在做的, 但是還不成熟等等.

最后呢, 我給大家提供一個類似的解決方案.

首先, 我要打個廣告, 以后APC將由我來維護, 大家以后在APC的使用中如果有問題, 可以直接聯系我. 

回歸正題: 要實現編譯和執行分離, 其實我們借助APC就能做到, APC提供了一族apc_bin_dump, apc_bin_load函數, 能把Opcodes緩存導出到外部文件中.

然而, 可惜的是, 這部分功能以前一直不能很好的正常工作, 這和之前的開發者因為時間原因不在投精力在這個上面是有關系的.

經過我對apc_bin系列函數的重新梳理, 修復以后, 這部分功能現在終于可以正常工作了, 那么基于這些函數, 我們就可以實現編譯執行分離..

思路很簡單, 在本地通過apc_bin_dumpfile把我們的php文件, 導出成bin文件, 然后在服務器上通過apc_bin_loadfile來讀取這些bin文件. 就可以實現編譯和執行分離啦, 一個簡單的示意代碼如下:

$ find ./ -name "*.php" -exec php -r "apc_bin_dumpfile(array('{}'), array(), '{}' . '.bin');" \;

然后在服務器端的文件自動加載部分

<?php
    function __autoload($name) {
       /*首先計算出文件名字*/
       $file =  根據類名得到PHP文件路徑();
       if (!file_exists($file)) {
          //文件不存在, 說明我們還沒有load過, 那么創建一個空文件.
          file_put_contents($file, '');
          apc_bin_loadfile($file . '.bin');
       } else {
          //我們已經load過了, 理論上應該已經被服務器的APC緩存處理Cache住了.
        }

       include ($file);
   }

當然, 這里只是一個簡單的示意, 如果要實際使用, 你還要考慮緩存被換出的可能, 那么一個解決方案就是設置倆個自動加載函數, 第一個如上, 第二個如果被調用, 就說明緩存被換出, 導致include了一個空文件, 于是就再次load一次bin文件就可以了.

當然, 你也可以把所有的文件打包到一個bin文件中, 然后只load一次, 后續就交給服務器上的APC Cache來做就可以了. 但是這里有一個要注意的點就是,

那么對于這部分希望代碼保護功能的人來說, 就可以使用APC來免費的完成這些事情了. 不過, 這個方案確實有點丑陋, 后續可以考慮在APC上增加直接對bin文件的支持. 

這是來自雪候鳥 博客的最新文章

 本文由用戶 openkk 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!