文字列のPHPコードの実行方法


最近、プロジェクトの必要性から、文字列のphpコード(phpとhtmlの混在)をどのように実行するかという議題が出されました.注意:従来、phpコードはファイルに格納され、直接ファイルを実行すればいいのです.phpコードがデータベースから取得された場合、どのように実行するかについて説明します.
最も直感的な案
  • 文字列コードをテンポラリファイルに書き込み、プロジェクト内でファイルをincludeし、完了してからこのテンポラリファイル
  • を削除する.
  • system execのようなシステム関数
  • php関数eval(セキュリティの問題はありますか?)

  • さらなる妄想
  • 文字列コードをパラメータとしてphpのcliまたはphp-fpmに入力
  • を実行する.
  • includeを再定義し、includeが文字列
  • を直接操作できるようにする.
    いくつかの考え方の検証
  • 1:テンポラリ・ファイルを書いてincludeファイルを作成します.疑問なく、可能です.では、毎回ファイルを書くのではなく、リクエストごとに1回ファイルを書くのではないでしょうか.はい、解決策があります.キャッシュ+期限切れ検証などですが、この案は専門的ではないような気がします..
  • 2:system execのような関数です.少し考えてみると、phpコード
  • を実行するのではなく、システムコマンドを実行することがわかります.
  • 3:eval関数、マニュアルには次のように書かれています.
    Caution :The eval() language construct is very dangerous because it allows execution of arbitrary PHP code. Its use thus is discouraged. If you have carefully verified that there is no other option than to use this construct, pay special attention not to pass any user provided data into it without properly validating it beforehand.
  • 4:php-fpm cliモードでこのような問題を解決する方法があるかどうかは、文字列コードをfpm、cliモードに転送し、戻り結果を待つことを想定している.しかし、実行する必要がある文字列コードにはコンテキストがある.例えば、文字列コードには変数$_GETが使用されており、この文字列コードをfpmに転送し、$_GET変数が転送されていない場合、そのコードはまだ正常に動作しません.
  • 5:includeは文字列を直接操作できるかどうか、前の4つの方法はあまり満足していないようですが、この考えを深く掘り下げてみましょう.まず、phpのincludeはどんな原理ですか.ソースコードを見たことがありません.当ててみましょう.1:ファイル(fopen、freadの類)を読みます.2:php構文の解析3:コードを実行すると、fopen,freadに文字列を操作させることができれば、この問題は解決するかもしれない.想定:文字列をオブジェクトまたはストリームに変換し、fopen,freadインタフェースを提供する.まずphpのSPLにこのようなインタフェースがあるべきだと考え、php公式マニュアルを調べ、phpマニュアルの「サポートされているプロトコルとパッケージプロトコル」の章を見つける(同僚もカスタムプロトコルを使用する方法を提案したことがあります)、以下はテストの最も簡単なdemoです:(カスタムプロトコルをカプセル化し、includeを使用して文字列を直接操作します)
    ";
    	echo "hello $i 
    ";  '; } // class VariableStream {     private $string;     private $position;     public function stream_open($path, $mode, $options, &$opened_path) {         $url = parse_url($path);         $id = $url["host"];         // ID php         $this-?>string = mysql_get($id);         $this->position = 0;         return true;     }     public function stream_read($count) {         $ret =  substr($this->string, $this->position, $count);         $this->position += strlen($ret);         return $ret;     }     public function stream_eof() {}     public function stream_stat() {} } stream_wrapper_register("var", "VariableStream"); // $contextName = "1000"; //include php 。(php , 199 ID) include("var://199"); // $contextName = "2000"; // php include("var://299");
    OK、やっと解決策が見つかりました.さらに考えてみましょう.最終的な展示がincludeであることを望んでいる以上、includeの内部はfopenのようなシステム関数ですが、fopenはカスタムプロトコルのほかに、どのようなものをサポートしていますか.マニュアルでは、fopenの最初のパラメータ$filenameは、ファイル名であってもよいし、「scheme://...「のフォーマットです.2つ目のフォーマットは、上記のカスタムプロトコル方式です.さらに関連するものを見続けると、SplFileInfo、stream_context_createが見つかりますが、問題は解決できません.
  • まとめ
         3           ,        
    1:     ,   ,  include
    2: eval,               
    3:     ,  include
    
          1,  1:         I/O。  2:    (      )
      eval       ,             ,                         ,    。
        ,  2      3   。
    
    
        ,                  php   ,     eval  
                 ,             。
               : include("protocolName://param");

    はい、以上の提供の大部分は構想で、構想があなたに役に立つことを望んでいます.