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 )