rryqszq4 / ngx-php

ngx-php - Embedded php7 or php8 scripting language for nginx module. Mainline development version of the ngx-php.
BSD 2-Clause "Simplified" License
582 stars 56 forks source link

Error inlcude file (cannot declare class) #174

Open Qwoker opened 11 months ago

Qwoker commented 11 months ago

Hello! I try execute code on rewrite_block. My code config nginx

location / {
        default_type 'text/html';  
            rewrite_by_php '
            include "/etc/nginx/php/index.php";
            ';
}

file index.php

include "/etc/nginx/php/memcache.php";
$memcached = new memcached();
$res = $memcached->add('qwe', 123, 100);
var_dump($res);
echo microtime(1) * rand(100,3000000000444);
ngx_exit(200); 

file memchache.php i take here - https://github.com/rryqszq4/ngx-php-memcached

Log file error.log

#0 ngx_php eval code(2): include()
#1 [internal function]: ngx_rewrite_11ffda65490a9c0a0c4c70dd24594f27()
#2 {main}
  thrown in /etc/nginx/php/index.php on line 96, client: 43.3.23.55, server: localserver.net, request: "GET / HTTP/1.1", host: "3.3.3.55"
2023/08/04 18:11:41 [error] 14873#0: *4 Fatal error: Cannot declare class memcached\memcached, because the name is already in use in /etc/nginx/php/memcache.php on line 10, client: 43.3.23.55, server: localserver.net, request: "GET / HTTP/1.1", host: "3.3.3.55"
2023/08/04 18:11:43 [error] 14875#0: *5 Fatal error: Uncaught Error: Class 'memcached' not found in /etc/nginx/php/index.php:96
Stack trace:
#0 ngx_php eval code(2): include()
#1 [internal function]: ngx_rewrite_11ffda65490a9c0a0c4c70dd24594f27()
#2 {main}
  thrown in /etc/nginx/php/index.php on line 96, client: 43.3.23.55, server: localserver.net, request: "GET / HTTP/1.1", host: "3.3.3.55"
2023/08/04 18:11:50 [error] 14875#0: *5 Fatal error: Cannot declare class memcached\memcached, because the name is already in use in /etc/nginx/php/memcache.php on line 10, client: 43.3.23.55, server: localserver.net, request: "GET / HTTP/1.1", host: "3.3.3.55"

I can't figure out how to connect php files correctly and make it so that every time the memory is not connected to the library. Maybe this can be done in Init_worker? How can you store data in php memory as it is done for example in Lua via a shared dict? So that I can get data not limited to the scope of the current process, but from another. Or is only memcached going to help here?

Qwoker commented 11 months ago

Okay, declare error i fixed with

if (!class_exists('test')) {
     class test 
     {
...
}

now the question remains, how to initialize variables in init_worker so that they are visible and available for change in other workers, for example, in rewrite

joanhey commented 11 months ago

Please, don't use class_exists(), it isn't a solution to the problem.

The problem is basic knowledge of PHP.

Include

If you include the same file two or more times in a php file, the error will always exist of cannot declare class (function, ...)

Try this in any PHP SAPI (php-fpm, cli, ...)

function rewrite() {
     include "/etc/nginx/php/index.php";
}

rewrite();
rewrite();
....

Ngx-php is embeded PHP in Nginx, so the application is persistent. Once included a file, it isn't necessary to include again or you will have that problems.

A simple fix is use include_once , or better because you will use it always, is a normal include in the init_worker. The init_worker only run the first time, and all the code is always available in any place in your workers.

Namespaces

The second error Class 'memcached' not found, it's also normal. You are calling a class: memcached, that don't exist, because in your included file you only have the class: ngxphp\memcached\memcached

Examples

Check the files in the Techempower benchmark. Exist examples with global variables, with classes, .... https://github.com/TechEmpower/FrameworkBenchmarks/tree/master/frameworks/PHP/php-ngx

Qwoker commented 11 months ago

Yes, your right. If i include once on init_worker is good, work! Latest question how to collect data in memory PHP. Example do $dataArray = array() in init_worker and call it in content_by_php block and possible to modify $dataArray (unset, push and etc functions for arrays)