Can PHP return a resource with ID # 0?

I am wondering if a valid PHP resource can have identifier 0. I get resources for connecting to databases, and so far all of them have been non-zero integers. It’s just interesting what range of potential identifiers for resources.

+6
source share
2 answers

The resource identifier can be in the range int . Find "resource" or "ZEND_FETCH_RESOURCE" in the PHP source directory through the terminal. Then you will see the function:
(file ./Zend/zend_list.c , line 110)

 ZEND_API void *zend_fetch_resource(zval **passed_id TSRMLS_DC, int default_id, char *resource_type_name, int *found_resource_type, int num_resource_types, ...) 

Inside the function, you will see that passed_id is the resource identifier and type int .
Typically, libraries pass a default identifier of -1 , for example, in the file ./ext/mysql/php_mysql.c , line 1060.

In general, you can assume that all libraries will pass a real / existing resource identifier with a value greater than 0, but this is not a rule that every library should follow - you can pass a negative resource identifier or 0.

+4
source

It seems not ... I could not find why, but here is what I tried (maybe someone else can shed some light on this behavior for the zend engine)

1.- In C, I wrote a very stupid program that generates file descriptor # 0 (this does not look like a resource in php, but I tried this with file resources so that we can somehow bind both languages)

 #include <stdio.h> #include <string.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> int main(int argc, char *argv[]) { int a; char buff[8]; close(0); close(1); close(2); a = open("./output", O_CREAT | O_TRUNC | O_WRONLY); sprintf(buff, "%d\n", a); write(a, buff, strlen(buff)); close(a); } 

This code will close the file descriptors 0, 1, 2. open a new file and save the descriptor, and the result:

$ cat output

0

$

now in php:

 <?php fclose(STDIN); fclose(STDOUT); fclose(STDERR); $asd = fopen('./outputphp', 'w'); fwrite($asd, print_r($asd, true)); fclose($asd); 

this will output:

$ cat outputphp

Resource ID # 5

$

so even closing stdin, stdout and stderr, php will not reuse resource ids. moreover, stdin id # 1, stdout is # 2, and stderr is # 3, when stdin actually has a file descriptor of 0, stdout has 1, and stderr has 2. There is also another identifier # 4, already highlighted.

so I would say that php reserves id # 0 or doesn't use it at all.

greping through the zend engine code, I found that actually resource # 0 is used in all the code that initializes the zend engine in sapi (cgi, cli, modules, etc.) when ZTS (thread safety is enabled). as:

 tsrm_startup(1, 1, 0, NULL); tsrm_ls = ts_resource(0); 

when cleaning the zend engine, it will move around the resource table starting with id # 0. You cannot (at least I couldn’t) get resourceC # 0 with or without thread safety, so # 0 seems to be reserved for both cases, but only used when ts is on.

EDIT: summarize;) it seems that you do not have a resource identifier of less than 1, the default is 1, 2, 3 (not sure about # 4, but it is possible that any new resources that you open will start with C # 4 or # 5 )

+3
source

Source: https://habr.com/ru/post/894301/


All Articles