phpはG-WANでうまく機能しないので、私はこのクレイジーなアイデアを持っています。おそらく解決策は、ファレンジャーを使用してphpコードをc#モノラルアセンブリにコンパイルし、g-wanから使用することです。
誰かがこの組み合わせの経験があり、助けることができますか?
または多分私は間違っていて、G-wanはphpを実行できますか?
誰かがPH7を試しましたか ?
PH7 は、ホスト アプリケーションが PHP スクリプトをインプロセスでコンパイルおよび実行できるようにする PHP エンジンです。
組み込みインタープリターとして、複数のインタープリター状態を同じプログラム内で共存させることができ、それらの間で干渉することはありません。
PH7 はスレッドセーフです。
ただし、スレッドセーフにするためには、PH7_ENABLE_THREADS コンパイル時ディレクティブを定義して PH7 をコンパイルする必要があります。
PHP のサポートを追加するために、Phalanger (および他のいくつかのソリューション) の背後にいる人々に連絡を取りました。そして彼らの答えは(当時)、ファランジャーはもはや開発されていないというものでした.
現在、CLR 言語として再実装されており、PHP に新たな命を吹き込む可能性があります。私は G-WAN 3.9 ベータ版を使用していましたが、Mono ランタイムでサポートされているさまざまな言語をまだ試していませんでした。
本物のPHPライブラリに関しては、以下のコードを書いて実行しました。
// ----------------------------------------------------------------------------
// php.c: G-WAN using PHP scripts
//
// To build PHP5:
//
// CFLAGS="-O3" ./configure --enable-embed --enable-maintainer-zts --with-tsrm-pthreads --without-pear
// make clean
// make
// sudo make install
/* Installing PHP SAPI module: embed
Installing PHP CLI binary: /usr/local/bin/
Installing PHP CLI man page: /usr/local/php/man/man1/
Installing PHP CGI binary: /usr/local/bin/
Installing build environment: /usr/local/lib/php/build/
Installing header files: /usr/local/include/php/
Installing helper programs: /usr/local/bin/
program: phpize
program: php-config
Installing man pages: /usr/local/php/man/man1/
page: phpize.1
page: php-config.1
Installing PEAR environment: /usr/local/lib/php/
[PEAR] Archive_Tar - already installed: 1.3.7
[PEAR] Console_Getopt - already installed: 1.3.0
[PEAR] Structures_Graph- already installed: 1.0.4
[PEAR] XML_Util - already installed: 1.2.1
[PEAR] PEAR - already installed: 1.9.4
Wrote PEAR system config file at: /usr/local/etc/pear.conf
You may want to add: /usr/local/lib/php to your php.ini include_path
/home/pierre/Downloads/PHP/php5.4-20/build/shtool install -c ext/phar/phar.phar /usr/local/bin
ln -s -f /usr/local/bin/phar.phar /usr/local/bin/phar
Installing PDO headers: /usr/local/include/php/ext/pdo/ */
/*
enabling the 'thread safety' --enable-maintainer-zts option results in:
error: 'tsrm_ls' undeclared (first use in this function)
*/
/*
tsrm_ls
TSRM local storage - This is the actual variable name being passed around
inside the TSRMLS_* macros when ZTS is enabled. It acts as a pointer to
the start of that thread's independent data storage block.
TSRM
Thread Safe Resource Manager - This is an oft overlooked, and seldom if
ever discussed layer hiding in the /TSRM directory of the PHP source code.
By default, the TSRM layer is only enabled when compiling a SAPI which
requires it (e.g. apache2-worker). All Win32 builds have this layer
enabled enabled regardless of SAPI choice.
ZTS
Zend Thread Ssafety - Often used synonymously with the term TSRM.
Specifically, ZTS is the term used by ./configure
( --enable-experimental-zts for PHP4, --enable-maintainer-zts for PHP5),
and the name of the #define'd preprocessor token used inside the engine
to determine if the TSRM layer is being used.
TSRMLS_??
A quartet of macros designed to make the differences between ZTS and
non-ZTS mode as painless as possible. When ZTS is not enabled, all
four of these macros evaluate to nothing. When ZTS is enabled however,
they expand out to the following definitions:
TSRMLS_C tsrm_ls
TSRMLS_D void ***tsrm_ls
TSRMLS_CC , tsrm_ls
TSRMLS_DC , void ***tsrm_ls
PHP relies on global variables from resource type identifiers, to
function callback pointers, to request specific information such as
the symbol tables used to store userspace variables. Attempting to
pass these values around in the parameter stack would be more than
unruly, it'd be impossible for an application like PHP where it's
often necessary to register callbacks with external libraries which
don't support context data.
So common information, like the execution stack, the function and
class tables, and extension registries all sit up in the global
scope where they can be picked up and used at any point in the
application.
For single-threaded SAPIs like CLI, Apache1, or even Apache2-prefork,
this is perfectly fine. Request specific structures are initialized
during the RINIT/Activation phase, and reset back to their original
values during the RSHUTDOWN/Deactivation phase in preparation for
the next request. A given webserver like Apache1 can serve up multiple
pages at once because it spawns multiple processes each in their own
process space with their own independant copies of global data.
The trouble starts with threaded webservers like Apache2-worker, or IIS
where two or more threads trying to run the a request at the same time.
Each thread wants to use the global scope to store its request-specific
information, and tries to do so by writing to the same
storage space. At the least, this would result in userspace variables
declared in one script showing up in another. In practice, it leads to
quick and disasterous segfaults and completely unpredictable behavior as
memory is double freed or written with conflicting information by separate
threads.
*/
#pragma include "/usr/local/include/php"
#pragma include "/usr/local/include/php/main"
#pragma include "/usr/local/include/php/TSRM"
#pragma include "/usr/local/include/php/Zend"
#pragma link "/usr/local/lib/libphp5.so"
#include "gwan.h" // G-WAN exported functions
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/syscall.h>
#include <php/sapi/embed/php_embed.h>
#include <php/Zend/zend_stream.h>
static pid_t gettid(void) { return syscall(__NR_gettid); }
// PHP
static int ub_write(const char *str, unsigned int str_len TSRMLS_DC)
{
puts(str); // this is the stdout output of a PHP script
return 0;
}
static void log_message(char * message)
{
printf("log_message: %s\n", message);
}
static void sapi_error(int type, const char * fmt, ...) { }
static void php_set_var(char *varname, char *varval)
{
zval *var;
MAKE_STD_ZVAL(var);
ZVAL_STRING(var, varval, 1);
zend_hash_update(&EG(symbol_table), varname, strlen(varname) + 1,
&var, sizeof(zval*), NULL);
}
static char *php_get_var(char *varname)
{
zval **data = NULL;
char *ret = NULL;
if(zend_hash_find(&EG(symbol_table), varname, strlen(varname) + 1,
(void**)&data) == FAILURE)
{
printf("Name not found in $GLOBALS\n");
return "";
}
if(!data)
{
printf("Value is NULL (not possible for symbol_table?)\n");
return "";
}
ret = Z_STRVAL_PP(data);
return ret;
}
static int php_init(void)
{
static int once = 0;
if(once) return 0;
once = 1;
static char *myargv[2] = {"toto.php", NULL};
php_embed_module.log_message = log_message;
php_embed_module.sapi_error = sapi_error;
php_embed_module.ub_write = ub_write;
if(php_embed_init(1, myargv PTSRMLS_CC) == FAILURE)
{
printf("php_embed_init error\n");
return 1;
}
return 0;
}
static void php_shutdown()
{
php_embed_shutdown(TSRMLS_C);
}
static int php_exec(char *str)
{
zval ret_value;
int exit_status;
zend_first_try
{
PG(during_request_startup) = 0;
// run the specified PHP script file
// sprintf(str, "include (\"% s \ ");", scriptname);
zend_eval_string(str, &ret_value, "toto.php" TSRMLS_CC);
exit_status = Z_LVAL(ret_value);
} zend_catch
{
exit_status = EG(exit_status);
}
zend_end_try();
return exit_status;
}
__thread char reply_num[8] = {0};
__thread pid_t tid = 0;
int main(int argc, char *argv[])
{
if(!tid)
{
tid = gettid();
s_snprintf(reply_num, 8, "%u", tid);
php_init();
}
xbuf_t *reply = get_reply(argv);
//php_set_var("argv", argv[0]);
php_set_var(reply_num, "");
char fmt[] = //"print(\"from php [$test]\n\");\n"
"$reply%s = \"Hello World (PHP)\";\n";
char php[sizeof(fmt) + sizeof(reply_num) + 2];
s_snprintf(php, sizeof(php), fmt, reply_num);
php_exec(php);
xbuf_cat(reply, php_get_var(reply_num));
return 200;
}
PHP ランタイムをクラッシュさせることなく、このコードを複数のワーカー スレッドで動作させることができれば、PHP が G-WAN に追加されます。
G-WAN が 1 つのワーカー スレッドで生成するものを次に示します。
-----------------------------------------------------
weighttp -n 100000 -c 100 -t 1 -k "http://127.0.0.1:8080/?php.c"
finished in 0 sec, 592 millisec, **168744 req/s**, 48283 kbyte/s
requests: 100000 total/started/done/succeeded, 0 failed/errored
status codes: 100000 2xx, 0 3xx, 0 4xx, 0 5xx
traffic: 29299985 bytes total, 27599985 bytes http,
1700000 bytes data
-----------------------------------------------------
この PHP スレッド化の問題を解決するのに最適です。誰か助けてくれてありがとう!