2012-10-10 56 views
1

好的,我有这个疯狂的想法,因为php不能和G-WAN一起玩,也许解决方法是使用phalanger将php代码编译为c#单声道程序集,然后在g-wan中使用它?G-WAN + Phalanger

任何人都有这种组合的经验,可以帮助吗?

也许我错了,G湾可以运行PHP?

+0

这是一个好主意。新版本发布后,我会试一试。 (当前版本没有C#单声道支持) –

+0

我知道,本月3.9。 – Programista

+0

因此,任何人或有人知道如何直接运行PHP,G湾站点缺乏文档? – Programista

回答

1

好吧,我确实联系了Phalanger(以及其他一些解决方案)后面的人员来增加对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 runtime,然后PHP会添加到G-WAN。

这里是G-WAN与一个单一的工作线程产生:

----------------------------------------------------- 
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线程问题。感谢您帮助任何人!

+0

由于缺乏更好的解决方案,我已经将其设置为答案,g-wan应该有自己的论坛。 如何获得g-wan 3.9 beta吉尔?你在g-wan工作吗?那么请告诉Pierre,我们非常需要更多的代码示例和g-wan示例。 – Programista

+0

G-WAN有一个由G-WAN用户Paco主持的论坛,但他最近放弃了这个论坛。 Stackoverflow是一个体面的选择。我是G-WAN开发团队的一员,但公司注册用户也可以访问beta版。对于“更多示例”请求(其中已有60个可用),请尝试更具体:告诉您希望G-WAN展示如何操作。为此,G-WAN网站上有一个联系表格。 – Gil

+0

Gil以前是G-WAN订购的一部分,可以访问“仅限会员”论坛。这仍然是计划的一部分吗? – Tim

2

有人试过PH7

PH7是一个PHP引擎,它允许宿主应用程序编译和执行PHP脚本进程中

作为一个嵌入式解释器,它允许多个解释器状态在同一个程序中共存,而不会在它们之间产生任何干扰。

PH7是线程安全的

但为了线程安全,PH7必须在定义PH7_ENABLE_THREADS编译时指令的情况下编译。