PHP Extension&Makefile作成

5356 ワード

PHP Extensionって何ですか?多くのPHPを書くエンジニアは、PHP Extensionがどのようにして作られたのか分からないかもしれませんが、実はPHPの最下層はc言語を使っています.すべてのPHPの文法は、c言語を通じて実現されています.だから、私たちはcを通じて、PHPの機能を強化することができます.PHPをもっと使いやすくすることができます.正常なPHP Extensionを作るときは、まずconfigを書きます.m 4このファイル、このファイルは難しくありませんが、彼とMakefileのフォーマットの落差はとても大きいです.ここではMakefileを使ってPHP Extensionをコンパイルする方法を紹介します.まず、正常なPHP Extensionコンパイルの流れを紹介します.phpizeはMakefileファイルを構築します.configureこのコマンドは関連パッケージがインストールされているかどうかを自動的にチェックします
  • c codeとconfigを確立する.m4
  • phpize(下Linux指令phpize)
  • ./configure
  • make
  • mv modules/xxx.so/extension:コンパイルされたsoファイルをextensionディレクトリの下に移動し、PHP Extension
  • を完了しても
    php extension Makefileの作成
    基本phpizeの動作はMakefile,libtoolなどのツールを構築することです./configureは、いくつかの設定が正常かどうか、パス設定をチェックすることです.つまり、php extensionを自分で書く必要があります.では、この2つのプロセスをスキップして、Makefileを自分で書きましょう.
  • まずphpizeを使用して、自動的にMakefileを生成し、それから彼を私たちが望んでいるフォーマットに変更します.
  • phpize & mv Makefile Makefile.Global:MakefileをMakefileに変更します.global

  • Makefile.を修正する私たちが望むようにglobalの例
  • phpインストールディレクトリPHP_を追加DIR=/home/program/php(パスは自分で変更しましょう)
  • 部分変数の値をPHP_に変更DIR、例えばprefix=$(PHP_DIR)、phpincludedir=$(PHP_DIR)/include/php
  • phplibdir=$(SRC_PATH)/modules:コンパイル完了後、soファイルのパス
  • を指定
  • PHP_PECL_EXTENSION=extension name//(名前が重複しないように注意)
  • srcdir , builddir , top_srcdir , top_builddir、現在のディレクトリに変更し、絶対ディレクトリ
  • を使用します.
    簡略化されたMakefile
    Makefile.globalは半日やって、最後にやっと簡略化して完成して、後でphp extensionをコンパイルするのはずっと便利で、正式にプログラムをコンパイルするためのMakefileを書いて、見て!次のPHP Makefileはどんなに短いか.
    Example
    SRC_PATH = $ ( shell pwd ) 
    LDEF =  - DCOMPILE_DL_MyExtension 
    CXXFILE = myClass . cc extension . cc 
    EXTRA_CXXFLAGS = 
    CXXOUTPUT =  MyExtension 
    include Makefile . global 
    cp : 
     sudo cp ./ modules / $ ( CXXOUTPUT ). so / home / php_extension / 

    makeの結果
    Example
    create myClass . lo 
    create myClass . o 
    create extension . lo 
    create extension . o 
    create MyExtension . la 
    create MyExtension . so 
    //    MyExtension.so     

    phpが伝達する変数を受信する方法zend_を使用parseのfunctionには、[sal,lsl]が接続する変数の型を表す2つがあります.
  • zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,"sal",xxx,xx)
  • zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET,num_args TSRMLS_CC,"lsl", xx,xx,xx,xx)
  • l:long
  • を表す
  • s : string
  • a : array
  • b : boolean
  • d : double
  • resultをphpに返信する方法は以下のいくつかの
  • がある.
  • RETURN_LONG:回送long
  • RETURN_STRING:回送文字列
  • RETURN_DOUBLE:エコー倍精数
  • RETURN_BOOL:回伝boolean(true or false)
  • php extension functionを確立する
    extension functionと書くにはPHP_を使いますFUNCTIONというfunctionですが、最初のパラメータはfunction名で、書き終わったらphpでsimple(「xxx」)を使うことができます.
    Example
    PHP_FUNCTION ( simple ) 
    { 
     char * str = NULL ; 
     char * tmp =  new  char [ 50 ]; 
     string result =  "" ; 
     int str_len =  0 ; 
     if ( zend_parse_parameters ( ZEND_NUM_ARGS () TSRMLS_CC , 
     "s" , 
     & str ,& str_len )  == FAILURE )  { 
     RETURN_NULL (); 
     } 
     sprintf ( tmp ,  "Your input string is [%s]"  , str ); 
     result = tmp ; 
      
     delete [] tmp ; 
     RETURN_STRING ( const_cast < char *>( result . c_str ()), 1 ); 
      
    }

    第2の例はfunction entryで定義されたaddであり、主な機能は第1のパラメータと第2のパラメータを合計する機能であり、php extensionではすべてのデジタル破壊はRETURN_を使用するLONGは,int,long,floatに基づいてリターン値を判断する必要はないが,php変数の型態が自由であるため,こんなに細かく区別する必要はない.
    Example
    PHP_FUNCTION ( add ) 
    { 
     int num_args = ZEND_NUM_ARGS (); 
     if  ( num_args !=  2 )  { 
     RETURN_LONG ( 0 ); 
     } 
     int result =  0 , int1 , int2 ; 
     if ( zend_parse_parameters ( ZEND_NUM_ARGS () TSRMLS_CC , 
     "ll" , 
     & int1 ,& int2 )  == FAILURE )  { 
     RETURN_NULL (); 
     } 
     result =  int1  +  int2 ; 
      
      
     RETURN_LONG ( result ); 
      
    } 

    関連する問題
    warning: deprecated conversion from string constant to 'char*'
    私はgcc 4.2をアップグレードします.0後、コンパイルするとこのWarningが現れ、gcc 3.4を使用する.6大丈夫です.
    第2手、Warningに出会って止まらないで、Makefileファイルの中で、-Werrorのこの属性を取りましょう
    undefined symbol:__gxx_personality_v0
    c++構文を使用しているため、c++のlibraryはロードされていません.
    解法:MakefileのCCに-lstdc++を加え、これを加えるとコンパイル時に/usr/lib/libstdc++が自動的にロードされます.so.
    Example
    CC = cc - lstdc ++ 

    エラー:Invalid library(maybe not a PHP library)の処理
    これは、phpがsoファイルをロードすると、プログラムエントリが見つかりません.c&c++のプログラムエントリはmainですが、php extensionのプログラムエントリはzend_です.module_entryですが、私はc++文法を使っているので、c++には特性があり、コンパイル時に数やfunction名を自動的に変更します.
    Example
    zend_module_entry MyExtension_module_entry 

    このような文法は、c++コンパイル後、MyExtension_になる可能性があります.module_entryii,結果としてプログラムエントリが見つからずエラーを報告する.
    解法はextern「C」を追加することです
    Example
    zend_module_entry MyExtension_module_entry  =  { 
    
    } 
      
    extern  "C"  { 
     ZEND_GET_MODULE ( MyExtension ) 
    } 

    なぜextern「C」をつけるのですか?
    C++にはoverloadingの機能があることを知っています.一つのfunctionにはいろいろなパラメータの数がありますが、c++はどうやってできますか.実は彼はプログラムをコンパイルするとき、自動的にfunction nameのmappingをします.例えば、次の例ですが、単純なc言語ではこれが分からないので、c言語がc++のfunctionを読み取るとき、extern「C」を付けて、c++に名前をむやみに変更しないように強制しなければならない.そうすれば、c言語はfunctionを正しく実行することができる.
    Example
    int  test ( int a ){} 
    int  test ( char b , char c ){} 
      
    //    
    test ( int a )  => test_1 ( int a ) 
    test ( char b ,  char c )  => test_2 ( char b ,  char c )