├── .gitignore ├── LICENSE ├── README.md ├── config.m4 ├── config.w32 ├── examples ├── basic.php ├── binding.php ├── console.php ├── control-js.php ├── fixed-window.php ├── full_screen.php ├── multi-thread.php └── remote-website.php ├── php_webview.h ├── tests ├── 001.phpt ├── 002.phpt └── 003.phpt ├── webview.c ├── webview.ini ├── webview.stub.php └── webview_arginfo.h /.gitignore: -------------------------------------------------------------------------------- 1 | *.lo 2 | *.la 3 | .libs 4 | acinclude.m4 5 | aclocal.m4 6 | autom4te.cache 7 | build 8 | config.guess 9 | config.h 10 | config.h.in 11 | config.log 12 | config.nice 13 | config.status 14 | config.sub 15 | configure 16 | configure.ac 17 | configure.in 18 | include 19 | install-sh 20 | libtool 21 | ltmain.sh 22 | Makefile 23 | Makefile.fragments 24 | Makefile.global 25 | Makefile.objects 26 | missing 27 | mkinstalldirs 28 | modules 29 | php_test_results_*.txt 30 | phpt.* 31 | run-test-info.php 32 | run-tests.php 33 | tests/**/*.diff 34 | tests/**/*.out 35 | tests/**/*.php 36 | tests/**/*.exp 37 | tests/**/*.log 38 | tests/**/*.sh 39 | tests/**/*.db 40 | tests/**/*.mem 41 | tmp-php.ini 42 | *.dep 43 | .idea 44 | .vscode 45 | configure~ 46 | config.h.in~ 47 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Nazmul Alam 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # php-webview 2 | 3 | This is a simple PHP extension for writing simple, cross-platform GUI applications using PHP. It uses the webview library to create a small, lightweight, cross-platform application that can be used to create simple GUI applications. 4 | 5 | Internally, it uses the [webview](https://github.com/webview/webview) library. 6 | 7 | # Supported Platforms 8 | 9 | In theory, this extension should work on windows, mac & linux but only tested on linux & mac so far. 10 | 11 | # Before you start 12 | You'll need basic tools for C compilation. On mac, the gnu compiler is recommended. On windows, you can use the Visual Studio compiler. 13 | 14 | Before compiling the extension, you'll need to install the webview library. Example commands for mac are: 15 | 16 | ```bash 17 | brew install gcc git 18 | git clone https://github.com/webview/webview.git 19 | cd webview 20 | ./script/build.sh build 21 | cp build/library/libwebview.dylib /usr/local/lib 22 | cp webview.h /usr/local/include 23 | ``` 24 | 25 | For linux, you can use the following commands: 26 | 27 | ```bash 28 | sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.0-dev 29 | git clone https://github.com/webview/webview.git 30 | cd webview 31 | ./script/build.sh build 32 | sudo cp build/library/libwebview.so /usr/lib 33 | sudo cp webview.h /usr/include 34 | ``` 35 | 36 | If you face any issue, or you want to work in windows, please consult the [Getting Started](https://github.com/webview/webview?tab=readme-ov-file#getting-started) section of the webview library. 37 | 38 | # Installation 39 | 40 | ## Linux 41 | 42 | ```bash 43 | phpize 44 | ./configure 45 | make 46 | sudo make install 47 | ``` 48 | 49 | ## Mac 50 | 51 | ```bash 52 | phpize 53 | ./configure CC=gcc-13 CFLAGS="-I/usr/local/include" LDFLAGS="-L/usr/local/lib -lwebview" 54 | make 55 | make install 56 | ``` 57 | 58 | # Usage 59 | 60 | See the [webview.stub.php](webview.stub.php) file for the class signature. Also, checkout the [examples](examples) directory for some examples. 61 | 62 | # Known Issues 63 | ~~There's a few issues like some random crashes especially during the creation and destruction of the webview object.~~ When using with the [parallel](https://www.php.net/manual/en/book.parallel.php) php extension, in linux sometime it crashes while quitting the threads and in mac, it doesn't work at all with multi threading support. 64 | The installation process should also be improved. In theory, it should be possible to skip the installation of the webview library. 65 | If you face any issue, please open an issue in the repository. If you can fix it, please open a pull request. 66 | 67 | # License 68 | 69 | MIT 70 | -------------------------------------------------------------------------------- /config.m4: -------------------------------------------------------------------------------- 1 | dnl config.m4 for extension webview 2 | 3 | dnl Comments in this file start with the string 'dnl'. 4 | dnl Remove where necessary. 5 | 6 | dnl If your extension references something external, use 'with': 7 | 8 | dnl PHP_ARG_WITH([webview], 9 | dnl [for webview support], 10 | dnl [AS_HELP_STRING([--with-webview], 11 | dnl [Include webview support])]) 12 | 13 | dnl Otherwise use 'enable': 14 | 15 | PHP_ARG_ENABLE([webview], 16 | [whether to enable webview support], 17 | [AS_HELP_STRING([--enable-webview], 18 | [Enable webview support])], 19 | [no]) 20 | 21 | if test "$PHP_WEBVIEW" != "no"; then 22 | dnl Write more examples of tests here... 23 | 24 | dnl Remove this code block if the library does not support pkg-config. 25 | dnl PKG_CHECK_MODULES([LIBFOO], [foo]) 26 | dnl PHP_EVAL_INCLINE($LIBFOO_CFLAGS) 27 | dnl PHP_EVAL_LIBLINE($LIBFOO_LIBS, WEBVIEW_SHARED_LIBADD) 28 | 29 | dnl If you need to check for a particular library version using PKG_CHECK_MODULES, 30 | dnl you can use comparison operators. For example: 31 | dnl PKG_CHECK_MODULES([LIBFOO], [foo >= 1.2.3]) 32 | dnl PKG_CHECK_MODULES([LIBFOO], [foo < 3.4]) 33 | dnl PKG_CHECK_MODULES([LIBFOO], [foo = 1.2.3]) 34 | 35 | dnl Remove this code block if the library supports pkg-config. 36 | dnl --with-webview -> check with-path 37 | dnl SEARCH_PATH="/usr/local /usr" # you might want to change this 38 | dnl SEARCH_FOR="/include/webview.h" # you most likely want to change this 39 | dnl if test -r $PHP_WEBVIEW/$SEARCH_FOR; then # path given as parameter 40 | dnl WEBVIEW_DIR=$PHP_WEBVIEW 41 | dnl else # search default path list 42 | dnl AC_MSG_CHECKING([for webview files in default path]) 43 | dnl for i in $SEARCH_PATH ; do 44 | dnl if test -r $i/$SEARCH_FOR; then 45 | dnl WEBVIEW_DIR=$i 46 | dnl AC_MSG_RESULT(found in $i) 47 | dnl fi 48 | dnl done 49 | dnl fi 50 | dnl 51 | dnl if test -z "$WEBVIEW_DIR"; then 52 | dnl AC_MSG_RESULT([not found]) 53 | dnl AC_MSG_ERROR([Please reinstall the webview distribution]) 54 | dnl fi 55 | 56 | dnl Remove this code block if the library supports pkg-config. 57 | dnl --with-webview -> add include path 58 | dnl PHP_ADD_INCLUDE($WEBVIEW_DIR/include) 59 | 60 | dnl Remove this code block if the library supports pkg-config. 61 | dnl --with-webview -> check for lib and symbol presence 62 | LIBNAME=webview # you may want to change this 63 | LIBSYMBOL=webview_create # you most likely want to change this 64 | 65 | dnl If you need to check for a particular library function (e.g. a conditional 66 | dnl or version-dependent feature) and you are using pkg-config: 67 | dnl PHP_CHECK_LIBRARY($LIBNAME, $LIBSYMBOL, 68 | dnl [ 69 | dnl AC_DEFINE(HAVE_WEBVIEW_FEATURE, 1, [ ]) 70 | dnl ],[ 71 | dnl AC_MSG_ERROR([FEATURE not supported by your webview library.]) 72 | dnl ], [ 73 | dnl $LIBFOO_LIBS 74 | dnl ]) 75 | 76 | dnl If you need to check for a particular library function (e.g. a conditional 77 | dnl or version-dependent feature) and you are not using pkg-config: 78 | PHP_CHECK_LIBRARY($LIBNAME, $LIBSYMBOL, 79 | [ 80 | PHP_ADD_LIBRARY_WITH_PATH($LIBNAME, $WEBVIEW_DIR/$PHP_LIBDIR, WEBVIEW_SHARED_LIBADD) 81 | AC_DEFINE(HAVE_WEBVIEW_FEATURE, 1, [ ]) 82 | ],[ 83 | AC_MSG_ERROR([FEATURE not supported by your webview library.]) 84 | ],[ 85 | -L$WEBVIEW_DIR/$PHP_LIBDIR -lm 86 | ]) 87 | PHP_SUBST(WEBVIEW_SHARED_LIBADD) 88 | 89 | dnl In case of no dependencies 90 | AC_DEFINE(HAVE_WEBVIEW, 1, [ Have webview support ]) 91 | 92 | PHP_NEW_EXTENSION(webview, webview.c, $ext_shared) 93 | fi 94 | -------------------------------------------------------------------------------- /config.w32: -------------------------------------------------------------------------------- 1 | ARG_ENABLE('webview', 'webview support', 'no'); 2 | 3 | if (PHP_WEBVIEW != 'no') { 4 | AC_DEFINE('HAVE_WEBVIEW', 1, 'webview support enabled'); 5 | 6 | EXTENSION('webview', 'webview.c', null, '/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1'); 7 | } 8 | -------------------------------------------------------------------------------- /examples/basic.php: -------------------------------------------------------------------------------- 1 | set_title("Hello Webview"); 10 | $webview->set_size(600, 450); 11 | $webview->set_html("

Hello World

"); 12 | 13 | $webview->run(); 14 | unset($webview); // must clear 15 | -------------------------------------------------------------------------------- /examples/binding.php: -------------------------------------------------------------------------------- 1 | Tap me 9 |
You tapped 0 time(s).
10 | 11 |
Result of computation: 0
12 | 13 | 30 | EOD; 31 | 32 | $webview = new Webview(); 33 | 34 | $webview->set_title("Hello World"); 35 | $webview->set_size(600, 450); 36 | 37 | $webview->bind("compute", function(int $a, int $b){ 38 | sleep(1); // simulate a long computation 39 | return json_encode(["result" => $a * $b]); 40 | }); 41 | 42 | $count = 0; 43 | $webview->bind("increment", function() use (&$count) { 44 | return json_encode(["count" => ++$count]); 45 | }); 46 | 47 | $webview->bind("donothing", function() { 48 | echo "This will not be executed\n"; 49 | }); 50 | $webview->unbind("donothing"); 51 | 52 | $webview->set_html($html); 53 | 54 | $webview->run(); 55 | unset($webview); 56 | -------------------------------------------------------------------------------- /examples/console.php: -------------------------------------------------------------------------------- 1 | set_title("Hello World"); 14 | $webview->set_size(600, 450); 15 | 16 | $webview->set_html(" 17 |

Time: HH:mm:ii

18 | "); 19 | 20 | // redirect the console log to the PHP console 21 | $webview->init(" 22 | window.console = { 23 | log: function(data){ 24 | window.console_log(JSON.stringify(data)); 25 | } 26 | } 27 | window.onload = function(){ 28 | setInterval(function() { 29 | var date = new Date(); 30 | hour.innerText = date.getHours(); 31 | minute.innerText = date.getMinutes(); 32 | second.innerText = date.getSeconds(); 33 | console.log('Date: ' + date); 34 | }, 1000); 35 | } 36 | "); 37 | 38 | $webview->bind('console_log', function($data){ 39 | echo print_r(json_decode($data), true). PHP_EOL; 40 | }); 41 | 42 | $webview->run(); 43 | unset($webview); 44 | 45 | -------------------------------------------------------------------------------- /examples/control-js.php: -------------------------------------------------------------------------------- 1 | set_title("Hello Webview"); 10 | $webview->set_size(600, 450); 11 | $webview->set_html(" 12 | 13 | 14 | title 15 | 16 | 17 |

Hello Webview

18 |

This is a simple webview example.

19 | 20 | 21 | 22 | "); 23 | 24 | // Set initial color to red 25 | $webview->init(" 26 | window.onload = function() { 27 | document.body.style.backgroundColor = 'red'; 28 | } 29 | "); 30 | 31 | $webview->bind("change_color", function() use ($webview) { 32 | $colors = ['red', 'green', 'blue', 'yellow', 'purple', 'orange', 'pink', 'brown', 'black', 'white']; 33 | $color = $colors[array_rand($colors)]; 34 | $webview->eval("document.body.style.backgroundColor = '{$color}'"); 35 | }); 36 | 37 | $webview->run(); 38 | unset($webview); // must clear 39 | -------------------------------------------------------------------------------- /examples/fixed-window.php: -------------------------------------------------------------------------------- 1 | set_title("Hello Webview"); 10 | $webview->set_size(600, 450, WEBVIEW_HINT_FIXED); // window size is fixed 11 | $webview->set_html("

Hello World

"); 12 | 13 | $webview->run(); 14 | unset($webview); // must clear 15 | -------------------------------------------------------------------------------- /examples/full_screen.php: -------------------------------------------------------------------------------- 1 | set_title("Hello World"); 10 | 11 | $webview->set_html(<< 13 | 14 |
15 |

Fullscreen Demo

16 |

Window maximizing doesn't work without user interaction.

17 |

But we can set the window size to the available screen size.

18 |

For mac, this is the size of the screen minus the dock & the menu bar.

19 |

For windows, this is the size of the screen minus the taskbar.

20 |

For linux, this is the size of the screen minus the panel.

21 |

When the user actually wants to go fullscreen, we can use the requestFullscreen method.

22 | 23 | 28 | 29 | 30 | HTML); 31 | 32 | $webview->bind("setWindowSize", function($width, $height) use ($webview) { 33 | $webview->set_size($width, $height); 34 | }); 35 | 36 | $webview->run(); 37 | unset($webview); 38 | 39 | -------------------------------------------------------------------------------- /examples/multi-thread.php: -------------------------------------------------------------------------------- 1 | run(function () use($channel) { 16 | $webview = new Webview(); 17 | $webview->set_title('UI Thread'); 18 | $webview->set_size(600, 450); 19 | $webview->set_html(" 20 |

Time: HH:mm:ii

21 | 22 | 23 | "); 24 | $webview->init(" 25 | window.onload = function(){ 26 | setInterval(function() { 27 | var date = new Date(); 28 | hour.innerText = date.getHours(); 29 | minute.innerText = date.getMinutes(); 30 | second.innerText = date.getSeconds(); 31 | }, 1000); 32 | } 33 | "); 34 | $webview->bind('single_thread', function () { 35 | sleep(3); // simulate a long-running task 36 | echo "Single Thread task finished\n"; 37 | }); 38 | $webview->bind('multi_thread', fn() => $channel->send(true)); 39 | $webview->run(); 40 | unset($webview); 41 | $channel->send(false); // send a signal to stop the worker 42 | }); 43 | 44 | //$channel->setBlocking(false); 45 | $worker->run(function () use ($channel) { 46 | while (true) { 47 | $data = $channel->recv(); 48 | if ($data === true) { 49 | sleep(3); // simulate a long-running task 50 | echo "Multi Thread task finished\n"; 51 | } 52 | if ($data === false){ 53 | echo "Quiting the worker\n"; 54 | break; 55 | } 56 | } 57 | }); 58 | 59 | echo "Hello from the main thread\n"; // this will be printed immediately 60 | -------------------------------------------------------------------------------- /examples/remote-website.php: -------------------------------------------------------------------------------- 1 | set_title("Hello Webview"); 10 | $webview->set_size(600, 450); 11 | $webview->navigate("https://php.net"); 12 | 13 | $webview->run(); 14 | unset($webview); // must clear 15 | -------------------------------------------------------------------------------- /php_webview.h: -------------------------------------------------------------------------------- 1 | /* webview extension for PHP */ 2 | 3 | #ifndef PHP_WEBVIEW_H 4 | # define PHP_WEBVIEW_H 5 | 6 | extern zend_module_entry webview_module_entry; 7 | # define phpext_webview_ptr &webview_module_entry 8 | 9 | # define PHP_WEBVIEW_VERSION "0.1.0" 10 | 11 | # if defined(ZTS) && defined(COMPILE_DL_WEBVIEW) 12 | ZEND_TSRMLS_CACHE_EXTERN() 13 | # endif 14 | 15 | #endif /* PHP_WEBVIEW_H */ 16 | -------------------------------------------------------------------------------- /tests/001.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Check if webview is loaded 3 | --EXTENSIONS-- 4 | webview 5 | --FILE-- 6 | 9 | --EXPECT-- 10 | The extension "webview" is available 11 | -------------------------------------------------------------------------------- /tests/002.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | test1() Basic test 3 | --EXTENSIONS-- 4 | webview 5 | --FILE-- 6 | 11 | --EXPECT-- 12 | The extension webview is loaded and working! 13 | NULL 14 | -------------------------------------------------------------------------------- /tests/003.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | test2() Basic test 3 | --EXTENSIONS-- 4 | webview 5 | --FILE-- 6 | 10 | --EXPECT-- 11 | string(11) "Hello World" 12 | string(9) "Hello PHP" 13 | -------------------------------------------------------------------------------- /webview.c: -------------------------------------------------------------------------------- 1 | /* webview extension for PHP */ 2 | 3 | #ifdef HAVE_CONFIG_H 4 | #include "config.h" 5 | #endif 6 | 7 | #include "php.h" 8 | #include "webview.h" 9 | #include "ext/standard/info.h" 10 | #include "php_webview.h" 11 | #include "webview_arginfo.h" 12 | 13 | /* For compatibility with older PHP versions */ 14 | #ifndef ZEND_PARSE_PARAMETERS_NONE 15 | #define ZEND_PARSE_PARAMETERS_NONE() \ 16 | ZEND_PARSE_PARAMETERS_START(0, 0) \ 17 | ZEND_PARSE_PARAMETERS_END() 18 | #endif 19 | 20 | zend_result php_json_decode_ex(zval *return_value, const char *str, size_t str_len, zend_long options, zend_long depth); 21 | 22 | static zend_object_handlers webview_object_handlers; 23 | 24 | typedef struct php_webview_t 25 | { 26 | webview_t native; 27 | zend_object std; 28 | } php_webview_t; 29 | 30 | typedef struct bind_arg_t 31 | { 32 | webview_t native; 33 | zend_fcall_info *fci; 34 | zend_fcall_info_cache *fcc; 35 | } bind_arg_t; 36 | 37 | #define Z_WEBVIEW_P(zv) \ 38 | ((php_webview_t *)((char *)(Z_OBJ_P(zv)) - XtOffsetOf(php_webview_t, std))) 39 | 40 | zend_object *webview_new(zend_class_entry *ce) 41 | { 42 | php_webview_t *wv = zend_object_alloc(sizeof(php_webview_t), ce); 43 | 44 | zend_object_std_init(&wv->std, ce); 45 | wv->std.handlers = &webview_object_handlers; 46 | return &wv->std; 47 | } 48 | 49 | PHP_METHOD(Webview, __construct) 50 | { 51 | php_webview_t *container = Z_WEBVIEW_P(ZEND_THIS); 52 | zend_long debug = 0; 53 | 54 | ZEND_PARSE_PARAMETERS_START(0, 1) 55 | Z_PARAM_OPTIONAL 56 | Z_PARAM_LONG(debug) 57 | ZEND_PARSE_PARAMETERS_END(); 58 | 59 | if (ZEND_NUM_ARGS() > 0) 60 | { 61 | zend_update_property_long(Z_OBJCE_P(ZEND_THIS), Z_OBJ_P(ZEND_THIS), 62 | "debug", sizeof("debug") - 1, debug); 63 | } 64 | 65 | container->native = webview_create((int) debug, NULL); 66 | } 67 | 68 | PHP_METHOD(Webview, __destruct) 69 | { 70 | php_webview_t *container = Z_WEBVIEW_P(ZEND_THIS); 71 | webview_destroy(container->native); 72 | } 73 | 74 | PHP_METHOD(Webview, set_title) 75 | { 76 | zval *title; 77 | php_webview_t *container = Z_WEBVIEW_P(ZEND_THIS); 78 | 79 | ZEND_PARSE_PARAMETERS_START(1, 1) 80 | Z_PARAM_ZVAL(title) 81 | ZEND_PARSE_PARAMETERS_END(); 82 | 83 | webview_set_title(container->native, Z_STRVAL(*title)); 84 | } 85 | 86 | PHP_METHOD(Webview, set_html) 87 | { 88 | zval *html; 89 | php_webview_t *container = Z_WEBVIEW_P(ZEND_THIS); 90 | 91 | ZEND_PARSE_PARAMETERS_START(1, 1) 92 | Z_PARAM_ZVAL(html) 93 | ZEND_PARSE_PARAMETERS_END(); 94 | 95 | webview_set_html(container->native, Z_STRVAL(*html)); 96 | } 97 | 98 | PHP_METHOD(Webview, set_size) 99 | { 100 | zend_long width, height, hint = 0; 101 | php_webview_t *container = Z_WEBVIEW_P(ZEND_THIS); 102 | 103 | ZEND_PARSE_PARAMETERS_START(2, 3) 104 | Z_PARAM_LONG(width) 105 | Z_PARAM_LONG(height) 106 | Z_PARAM_OPTIONAL 107 | Z_PARAM_LONG(hint) 108 | ZEND_PARSE_PARAMETERS_END(); 109 | 110 | webview_set_size(container->native, (int) width, (int) height, hint); 111 | } 112 | 113 | PHP_METHOD(Webview, navigate) 114 | { 115 | zval *url; 116 | php_webview_t *container = Z_WEBVIEW_P(ZEND_THIS); 117 | 118 | ZEND_PARSE_PARAMETERS_START(1, 1) 119 | Z_PARAM_ZVAL(url) 120 | ZEND_PARSE_PARAMETERS_END(); 121 | 122 | webview_navigate(container->native, Z_STRVAL(*url)); 123 | } 124 | 125 | PHP_METHOD(Webview, init) 126 | { 127 | zval *js; 128 | php_webview_t *container = Z_WEBVIEW_P(ZEND_THIS); 129 | 130 | ZEND_PARSE_PARAMETERS_START(1, 1) 131 | Z_PARAM_ZVAL(js) 132 | ZEND_PARSE_PARAMETERS_END(); 133 | 134 | webview_init(container->native, Z_STRVAL(*js)); 135 | } 136 | 137 | PHP_METHOD(Webview, eval) 138 | { 139 | zval *js; 140 | php_webview_t *container = Z_WEBVIEW_P(ZEND_THIS); 141 | 142 | ZEND_PARSE_PARAMETERS_START(1, 1) 143 | Z_PARAM_ZVAL(js) 144 | ZEND_PARSE_PARAMETERS_END(); 145 | 146 | webview_eval(container->native, Z_STRVAL(*js)); 147 | } 148 | 149 | PHP_METHOD(Webview, run) 150 | { 151 | php_webview_t *container = Z_WEBVIEW_P(ZEND_THIS); 152 | ZEND_PARSE_PARAMETERS_NONE(); 153 | webview_run(container->native); 154 | } 155 | 156 | PHP_METHOD(Webview, terminate) 157 | { 158 | php_webview_t *container = Z_WEBVIEW_P(ZEND_THIS); 159 | ZEND_PARSE_PARAMETERS_NONE(); 160 | webview_terminate(container->native); 161 | } 162 | 163 | void bind_callback_handler(const char *seq, const char *req, void *arg) 164 | { 165 | bind_arg_t *context = (bind_arg_t *)arg; 166 | 167 | zval args; 168 | zval *result = emalloc(sizeof(zval)); 169 | context->fci->retval = result; 170 | context->fci->param_count = 0; 171 | 172 | if (strlen(req) > 0) { 173 | php_json_decode_ex(&args, req, strlen(req), 1, 512); 174 | context->fci->param_count = zend_array_count(Z_ARRVAL(args)); 175 | zend_fcall_info_args(context->fci, &args); 176 | } 177 | 178 | if(zend_call_function(context->fci, context->fcc) == SUCCESS){ 179 | if (ZVAL_IS_NULL(result)) { 180 | ZVAL_STRING(result, "[]"); 181 | } 182 | webview_return(context->native, seq, 0, Z_STRVAL_P(result)); 183 | } else { 184 | webview_return(context->native, seq, 1, "[]"); 185 | } 186 | zval_ptr_dtor(result); 187 | zval_ptr_dtor(&args); 188 | } 189 | 190 | PHP_METHOD(Webview, bind) 191 | { 192 | zval *name; 193 | php_webview_t *container = Z_WEBVIEW_P(ZEND_THIS); 194 | 195 | bind_arg_t *context = emalloc(sizeof(bind_arg_t)); 196 | context->native = container->native; 197 | context->fci = emalloc(sizeof(zend_fcall_info)); 198 | context->fcc = emalloc(sizeof(zend_fcall_info_cache)); 199 | 200 | ZEND_PARSE_PARAMETERS_START(2, 2) 201 | Z_PARAM_ZVAL(name) 202 | Z_PARAM_FUNC(*context->fci, *context->fcc) 203 | ZEND_PARSE_PARAMETERS_END(); 204 | 205 | Z_TRY_ADDREF(context->fci->function_name); 206 | if (context->fci->object != NULL){ 207 | ++context->fci->object->gc.refcount; // @todo: really needed? 208 | } 209 | 210 | webview_bind(container->native, Z_STRVAL(*name), bind_callback_handler, context); 211 | } 212 | 213 | PHP_METHOD(Webview, unbind) 214 | { 215 | zval *name; 216 | php_webview_t *container = Z_WEBVIEW_P(ZEND_THIS); 217 | 218 | ZEND_PARSE_PARAMETERS_START(1, 1) 219 | Z_PARAM_ZVAL(name) 220 | ZEND_PARSE_PARAMETERS_END(); 221 | 222 | webview_unbind(container->native, Z_STRVAL(*name)); 223 | } 224 | 225 | PHP_MINIT_FUNCTION(webview) 226 | { 227 | zend_class_entry *ce = register_class_Webview(); 228 | 229 | ce->create_object = webview_new; 230 | 231 | memcpy(&webview_object_handlers, &std_object_handlers, 232 | sizeof(zend_object_handlers)); 233 | webview_object_handlers.offset = XtOffsetOf(php_webview_t, std); 234 | 235 | REGISTER_LONG_CONSTANT("WEBVIEW_HINT_NONE", 0, CONST_CS | CONST_PERSISTENT); 236 | REGISTER_LONG_CONSTANT("WEBVIEW_HINT_MIN", 1, CONST_CS | CONST_PERSISTENT); 237 | REGISTER_LONG_CONSTANT("WEBVIEW_HINT_MAX", 2, CONST_CS | CONST_PERSISTENT); 238 | REGISTER_LONG_CONSTANT("WEBVIEW_HINT_FIXED", 3, CONST_CS | CONST_PERSISTENT); 239 | 240 | return SUCCESS; 241 | } 242 | 243 | /* {{{ PHP_RINIT_FUNCTION */ 244 | PHP_RINIT_FUNCTION(webview) 245 | { 246 | #if defined(ZTS) && defined(COMPILE_DL_WEBVIEW) 247 | ZEND_TSRMLS_CACHE_UPDATE(); 248 | #endif 249 | 250 | return SUCCESS; 251 | } 252 | /* }}} */ 253 | 254 | /* {{{ PHP_MINFO_FUNCTION */ 255 | PHP_MINFO_FUNCTION(webview) 256 | { 257 | php_info_print_table_start(); 258 | php_info_print_table_row(2, "webview support", "enabled"); 259 | php_info_print_table_end(); 260 | } 261 | /* }}} */ 262 | 263 | /* {{{ webview_module_entry */ 264 | zend_module_entry webview_module_entry = { 265 | STANDARD_MODULE_HEADER, 266 | "webview", /* Extension name */ 267 | NULL, /* zend_function_entry */ 268 | PHP_MINIT(webview), /* PHP_MINIT - Module initialization */ 269 | NULL, /* PHP_MSHUTDOWN - Module shutdown */ 270 | PHP_RINIT(webview), /* PHP_RINIT - Request initialization */ 271 | NULL, /* PHP_RSHUTDOWN - Request shutdown */ 272 | PHP_MINFO(webview), /* PHP_MINFO - Module info */ 273 | PHP_WEBVIEW_VERSION, /* Version */ 274 | STANDARD_MODULE_PROPERTIES}; 275 | /* }}} */ 276 | 277 | #ifdef COMPILE_DL_WEBVIEW 278 | #ifdef ZTS 279 | ZEND_TSRMLS_CACHE_DEFINE() 280 | #endif 281 | ZEND_GET_MODULE(webview) 282 | #endif 283 | -------------------------------------------------------------------------------- /webview.ini: -------------------------------------------------------------------------------- 1 | extension=webview -------------------------------------------------------------------------------- /webview.stub.php: -------------------------------------------------------------------------------- 1 |