Can PHP return a Resource with ID# 0?
I'm wondering if it's possible for a valid PHP Resource to have an ID of 0. I am getting database connection resources and so far they have all been non-zero positive integers. Just开发者_如何学Python curious what the range of potential IDs is for resources.
The resource id may be in the range of an int
. Search for "resource" or "ZEND_FETCH_RESOURCE" in the source code directory of PHP via the terminal. Then you'll 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'll see that passed_id
is the resource's id and it's of type int
.
Normally, libraries pass a default id of -1
, for example in file ./ext/mysql/php_mysql.c
, line 1060.
In general you can assume that all the libraries will pass a real/exists resource id with value greater than 0, but that's not a rule that every library must follow - it is possible to pass a negative resource id or 0.
It seems not... I couldn't find exactly why, but here's what I've tried (perhaps someone else can shed some more light about this behaviour for the zend engine)
1.- In C, I wrote a very silly program that generates a file descriptor #0 (this is not analogous to a resource in php, but I've tried this with file resources just so we can somehow relate 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 file descriptors 0, 1, 2. open a new file and save the descriptor, which results:
$ 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 id's. even more, stdin id #1, stdout is #2 and stderr is #3 when in fact stdin has file descriptor 0, stdout has 1, and stderr has 2. also, there is another id #4 already allocated.
so I'd say that php reserves the id #0 or wont use it at all.
greping through the zend engine code, i found that actually the resource #0 is used across all code that initializes the zend engine in either sapi (cgi, cli, modules, etc) when ZTS (thread safety is enabled). like:
tsrm_startup(1, 1, 0, NULL);
tsrm_ls = ts_resource(0);
when cleaning up the zend engine, it will traverse the resource table starting from the id #0. You cant (at least I couldnt) get a resource #0 with or without thread safety enabled, so #0 seems to be reserved for both cases but used only when ts enabled.
EDIT: to sum up ;) seems that you cant have a resource id less than 1, being 1, 2, 3 opened by default (not sure about the #4, but its possible that any new resources you will open will start at #4 or #5)
精彩评论