PHP 5のスカラー型制御

[更新]:コードにいくつかの変更が加えられました。 ithilionLoneCatに感謝



PHP 5では、関数の引数で、...スカラー型を除く、型を指定できることを誰もが既に知っています。つまり、整数、文字列、ブール、フロートなどです。



ただし、型制御のマニュアルページのコメントで、ダニエルL.ウッドは、エラーハンドラクラスを使用して、この問題に対するかなり興味深いソリューションを提供しています。 このソリューションの唯一の重大な欠点は、そのパフォーマンスです。



以下では、このソリューションを最適化する方法と、原則として製品リリースで使用する価値があるかどうかを説明します。



それで、与えられた解が何を犯しているかを分析します:

  1. 絶対に不要なdebug_backtrace呼び出し。 原則として、問題を解決するには、エラーメッセージの解析で十分です。 引数の明示的な検証は、妄想のスマックです。 実際、「Class :: function()に渡される引数Nは文字列、指定された文字列のインスタンスである必要があります...」という形式のメッセージをキャッチした場合、これはすでに正しい選択をするすべての理由を示しています。 注意してください... 文字列、文字列 ...たとえば、エラーの場合、... integer、string ...これは、このメッセージが実際にエラーであるかどうかを判断するのに十分です。
  2. タイプの配列にタイプミスがあります。 're srou ce' => 'is_resource'。
  3. 一部の場所でやや準最適なコード。


次のようにクラスを書き直して、これらの問題をすべて解決しようとします。

  <?php
クラスTypehint {

     private static $ _types = array(
         'boolean'、=> 'boolean'、
         'bool、' => 'boolean'、
         '整数'、=> '整数'、
         'int、' => 'integer'、
         'float、' => 'float'、
         'double、' => 'float'、
         'real、' => 'float'、
         'string、' => 'string'、
         「リソース」=>「リソース」
     );

    プライベート関数__construct(){}

     public static function init(){
         set_error_handler( 'Typehint :: handle');
         trueを返します。
     }

    パブリック静的関数ハンドル($ lvl、$ msg){
         if($ lvl == E_RECOVERABLE_ERROR && strstr($ msg、 'must be be' of instance ')!== false){
             $ errmsg = explode( ''、$ msg、13);
             return isset(self :: $ _ types [$ errmsg [10]])&& self :: $ _ types [$ errmsg [10]] == $ errmsg [11];
         }
         falseを返します。
     }
 }
 ?> 




それでは、テストを実行して、何が起こったのか見てみましょう。



  <?php
 require_once 'Typehint.php';
 Typehint :: init();

 function teststring(string $ string){return $ string;  }
関数テスト($ var){return $ var;  }

関数micro_time(){
     $ timearray = explode( ""、microtime());
     return($ timearray [1] + $ timearray [0]);
 }
 $ start = micro_time();

 for($ i = 0; $ i <10000; $ i ++){
    テスト文字列( '123');
 }

 $ end = micro_time();

 echo 'Typehint:'を使用。  ($ end- $ start)。  「秒」;

 echo "<br /> \ n";

 $ start = micro_time();

 for($ i = 0; $ i <10000; $ i ++){
    テスト( '123');
 }

 $ end = micro_time();

 echo「Typehintなし:」。  ($ end- $ start)。  「秒」;
 ?> 




ここに私が得たものがあります:



Typehintを使用:0.0787329673767秒

タイプヒントなし:0.00326299667358秒



ダニエルの元のソリューションでは、0.215523958206秒のような結果が得られました。 つまり 生産性はほぼ2.7倍になりました。



それにもかかわらず、私たちが見るように、Typehintソリューションを使用しなければ、生産性で24倍以上勝ったでしょう。 むしろ、それを使用すると、24回失われます。



これは、その使用の妥当性を示唆しています。 スクリプトの実行時間に約0.1秒追加された10,000コールを見てください。 考えるべきことがあります。



一方、Typehintを使用すると、コードの自己文書化性が向上し、特に必要な場合に、渡される引数のタイプを制御できるようになります。



ただし、PHPのユビキタスな強力な型付けは、実際にはdeには利点がないことを忘れないでください。 言語にはオーバーロードメカニズムはありません。宣言された型では、引数のデフォルト値に問題があります。 さらに、言語構造の戻り値を保証することはできません。



したがって、このソリューションを使用するかどうかを検討する前に、何度も考える価値があります。



それでも有用性が見られ、プロジェクトで使用したい場合は、クラス関数とメソッドの定義のスカラー型をクリーニングすることにより、本番用の最終コードをリリースする何らかの自動ビルダーを作成する可能性/必要性を検討することをお勧めします。



これを行うことは、原則として、少なくとも同じPHPまたはシェルを使用して難しくありません。



開発に頑張ってください!



PSブログからのクロスポスト: mikhailstadnik.com/php5-types-control



All Articles