php7のphp-cppライブラリを使用した拡張機能の作成

すべてのphpプログラマーは、人生で少なくとも一度は、phpの独自の拡張機能を作成することを考えました。 今日は、PHP-CPPライブラリを使用して拡張機能を作成する方法について説明します。 gtkを使用したボタンでアラートの例を使用します。







プロセスに興味がある人は、猫をお願いします。



依存関係:



1. libgtk2.0-dev

2. php7.0-dev

3. php-cpp-すべての開発を支援するライブラリ



最初の2つの依存関係は、Linuxディストリビューションのリポジトリから作成されます。







$ apt-get install libgtk2.0-dev php7.0-dev
      
      





php-cppをインストールするには、github.com php-cppからリポジトリを複製し、tmpディレクトリにすべてを収集します。



 $ cd /tmp/ $ git clone https://github.com/CopernicaMarketingSoftware/PHP-CPP.git $ cd PHP-CPP/ #      $ make #     $ sudo make install #    
      
      











これですべての準備が整いました。これで、開発を開始し、プロジェクトのディレクトリを作成できます。gtkPHP7という名前です。 開始する前に、 empty-extension.zipで将来の拡張機能のスケルトンをダウンロードし、アーカイブをプロジェクトフォルダーに解凍します。 その後、次のファイルが作成されます。



1. extensions.ini

2. Makefile

3. main.cpp

4。

extensions.iniの名前を変更し、編集用に開きます。 文字列「extensions = extensions.ini」を「extensions = gtkphp7.ini」に置き換えます。 次に、Makefileの次の行を編集して、Makefileを変更する必要があります。







 NAME = gtkphp7 INI_DIR = /etc/php/7.0/mods-available/ COMPILER_LIBS = `pkg-config --cflags --libs gtk+-2.0` all: ${OBJECTS} ${EXTENSION} ${EXTENSION}: ${OBJECTS} ${LINKER} ${LINKER_FLAGS} -o $@ ${OBJECTS} ${LINKER_DEPENDENCIES} ${COMPILER_LIBS}
      
      





NAMEは拡張機能の名前です

INI_DIR-phpモジュール構成用のディレクトリ。/etc/php/7.0/mods-available/があります。

COMPILER_LIBS-この場合gtkに必要なライブラリをロードします

最後に、すべてのターゲットにCOMPILER_LIBSを追加しました。







拡張機能の開発に直接進みます。 これを行うには、jetbrainsからclionをインストールし、プロジェクトをideにインポートしました。 他のすべての作業は、main.cppファイルで実行されます。 私は、PHPでインスタンス化され、アラートウィンドウを形成するための連続したメソッドを使用してクラスを開発することにしました。







 #include <phpcpp.h> #include <iostream> #include <gtk/gtk.h> class Gtk : public Php::Base { private: GtkWidget *_window; char *_titleWindow; char *_buttonTitle; GtkWidget *_button; Php::Value callB; public: Php::Value setTitle(Php::Parameters ¶ms); Php::Value setButtonTitle(Php::Parameters ¶ms); Php::Value createWindow(); Php::Value setButton(); static void callback(GtkButton *button, gpointer data); Php::Value render(); };
      
      





これは、拡張クラスのプロトタイプです。



1. setTitle-ウィンドウのタイトルを設定します

2. setButtonTitle-ボタンのタイトル

3. createWindow-ウィンドウを作成します

4. setButton-ボタンを作成し、ウィンドウに設定します

5.コールバック-ボタンがクリックされたときに呼び出されるコールバック関数

6.レンダリング-画面にボタンのあるウィンドウを表示します



最初の2つのメソッドは、ヘッダーとして使用する適切な変数を設定するだけなので、省略します。



 /** * create window gtk * @return Gtk */ Php::Value Gtk::createWindow() { int argc = 0; char **argv = NULL; gtk_init(&argc, &argv); _window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(_window), _titleWindow); gtk_container_set_border_width(GTK_CONTAINER(_window), 50); return this; }
      
      





gtkを初期化するために、変数argcとargvを作成し、それぞれ0とNULLを渡します。まるでアプリケーションがパラメーターなしで起動されたかのようです。 「gtk_window_new」メソッドを使用してウィンドウを作成し、_window変数に割り当てます。これはクラスのプライベートパラメーターです。



 /** * set button gtk * @return Gtk */ Php::Value Gtk::setButton() { _button = gtk_button_new_with_label(_buttonTitle); gtk_container_add(GTK_CONTAINER(_window), _button); g_signal_connect(G_OBJECT(_button), "clicked", G_CALLBACK(&Gtk::callback), G_OBJECT(_window)); return this; }
      
      





このメソッドは、ボタンウィジェットを作成し、_windowウィンドウに割り当てます。 g_signal_connect関数はボタンのクリックを監視し、次のパラメーターを関数に渡します。



1.ボタンオブジェクト

2.アクションのタイプ

3.コールバック関数(クラスのメンバーであってはなりません。つまり、静的関数または別個の関数でなければなりません)

4.ここで、コールバック関数で使用するウィンドウオブジェクトを渡します。



コールバック関数を分析しましょう:



 /** * callback click * @param button * @param window */ void Gtk::callback(GtkButton *button, gpointer window) { gtk_widget_destroy(GTK_WIDGET(window)); gtk_main_quit(); }
      
      





2番目のパラメーターはレースのようなもので、上記の関数で4つのパラメーターによって渡されたもので、最初のパラメーターは実際にはボタンです。 この関数は単純で、gtkを終了するだけです。 さて、最後の1つはレンダー関数です。



 /** * render alert * @return */ Php::Value Gtk::render() { gtk_widget_show_all(_window); gtk_main(); return true; }
      
      





一般に、このメソッドはウィンドウ内のすべてのウィジェットを表示し、gtkを起動します。 停止後、コールバック関数を使用して、trueを返します。



最後のステップは、クラスとそのメソッドを登録することです。



 /** * tell the compiler that the get_module is a pure C function */ extern "C" { /** * Function that is called by PHP right after the PHP process * has started, and that returns an address of an internal PHP * strucure with all the details and features of your extension * * @return void* a pointer to an address that is understood by PHP */ PHPCPP_EXPORT void *get_module() { static Php::Extension extension("gtkphp7", "1.0"); Php::Class<Gtk> gtk("Gtk"); //   gtk.method<&Gtk::setTitle>("setTitle"); //     gtk.method<&Gtk::setButtonTitle>("setButtonTittle"); gtk.method<&Gtk::setButton>("setButton"); gtk.method<&Gtk::createWindow>("createWindow"); gtk.method<&Gtk::render>("render"); extension.add(std::move(gtk)); //        // return the extension return extension; } }
      
      





スポイラーの下の完全なmain.cppコード:



main.cpp
 #include <phpcpp.h> #include <iostream> #include <gtk/gtk.h> class Gtk : public Php::Base { private: GtkWidget *_window; char *_titleWindow; char *_buttonTitle; GtkWidget *_button; Php::Value callB; public: Php::Value setTitle(Php::Parameters ¶ms); Php::Value setButtonTitle(Php::Parameters ¶ms); Php::Value createWindow(); Php::Value setButton(); static void callback(GtkButton *button, gpointer data); Php::Value render(); }; /** * set title to window * @param params * @return Gtk */ Php::Value Gtk::setTitle(Php::Parameters ¶ms) { std::string title = params[0]; _titleWindow = new char[title.size() + 1]; std::copy(title.begin(), title.end(), _titleWindow); _titleWindow[title.size()] = '\0'; return this; } /** * set button title * @param params * @return Gtk */ Php::Value Gtk::setButtonTitle(Php::Parameters ¶ms) { std::string title = params[0]; _buttonTitle = new char[title.size() + 1]; std::copy(title.begin(), title.end(), _buttonTitle); _buttonTitle[title.size()] = '\0'; return this; } /** * create window gtk * @return Gtk */ Php::Value Gtk::createWindow() { int argc = 0; char **argv = NULL; gtk_init(&argc, &argv); _window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(_window), _titleWindow); gtk_container_set_border_width(GTK_CONTAINER(_window), 50); return this; } /** * set button gtk * @return Gtk */ Php::Value Gtk::setButton() { _button = gtk_button_new_with_label(_buttonTitle); gtk_container_add(GTK_CONTAINER(_window), _button); std::cout << callB << std::endl; g_signal_connect(G_OBJECT(_button), "clicked", G_CALLBACK(&Gtk::callback), G_OBJECT(_window)); return this; } /** * callback click * @param button * @param window */ void Gtk::callback(GtkButton *button, gpointer window) { gtk_widget_destroy(GTK_WIDGET(window)); gtk_main_quit(); } /** * render alert * @return */ Php::Value Gtk::render() { gtk_widget_show_all(_window); gtk_main(); return true; } /** * tell the compiler that the get_module is a pure C function */ extern "C" { /** * Function that is called by PHP right after the PHP process * has started, and that returns an address of an internal PHP * strucure with all the details and features of your extension * * @return void* a pointer to an address that is understood by PHP */ PHPCPP_EXPORT void *get_module() { static Php::Extension extension("gtkphp7", "1.0"); Php::Class<Gtk> gtk("Gtk"); gtk.method<&Gtk::setTitle>("setTitle"); gtk.method<&Gtk::setButtonTitle>("setButtonTittle"); gtk.method<&Gtk::setButton>("setButton"); gtk.method<&Gtk::createWindow>("createWindow"); gtk.method<&Gtk::render>("render"); extension.add(std::move(gtk)); // return the extension return extension; } }
      
      







次のステップに進み、拡張機能をコンパイルしてインストールします。



 $ make $ sudo make install
      
      





インストール後、接続またはphpenmodのシンボリックリンクを作成します。



 $ sudo ln -s /etc/php/7.0/mods-available/gtkphp7.ini /etc/php/7.0/cli/conf.d/20-gtkphp7.ini $ sudo service php7.0-fpm restart #  php $ php -m | grep gtkphp7 #    
      
      





拡張機能を再構築して再インストールするには、次のようにします。



 $ make clean $ make $ sudo make install
      
      





テストのために、単純なphpスクリプトが作成されました。



 <?php function alert($title) { $gtk = new Gtk; return $gtk ->setTitle($title) ->setButtonTittle("Ok") ->createWindow() ->setButton() ->render(); } if(alert("Hellow habr")) { alert("Hellow again"); }
      
      





スクリプトの結果、記事のタイトルと同じスクリーンショット...拡張機能での作業の便宜上、関数が作成されました。



 void dump(Php::Value dumping) { Php::call("var_dump",dumping); }
      
      





php関数var_dumpを呼び出します。変数php配列などをダンプすると非常に便利です。







結論として、いくつかのリンクを示します。



1. Php-cppドキュメント

2. 記事のサンプルを含むリポジトリ

ps c ++では、これは最初の実験の1つであるため、コードに何か問題がある場合は、コメントを書き、良い週末をお過ごしください。








All Articles