Может ли PHP вернуть ресурс с идентификатором # 0? - PullRequest
6 голосов
/ 04 августа 2011

Мне интересно, может ли допустимый ресурс PHP иметь идентификатор 0. Я получаю ресурсы соединения с базой данных, и до сих пор все они были ненулевыми положительными целыми числами.Просто интересно, каков диапазон возможных идентификаторов для ресурсов.

Ответы [ 2 ]

4 голосов
/ 04 августа 2011

Идентификатор ресурса может находиться в диапазоне int.Найдите «ресурс» или «ZEND_FETCH_RESOURCE» в каталоге исходного кода PHP через терминал.Затем вы увидите функцию:
(файл ./Zend/zend_list.c, строка 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, ...)

Внутри функции вы увидите, что passed_id - это идентификатор ресурса и его тип int.
Обычно библиотеки передают идентификатор по умолчанию -1, например, в файле ./ext/mysql/php_mysql.c, строка 1060.

Как правило, можно предположить, что все библиотеки передадут реальное / существуетидентификатор ресурса со значением больше 0, но это не правило, которому должна следовать каждая библиотека - можно передавать отрицательный идентификатор ресурса или 0.

3 голосов
/ 04 августа 2011

Кажется, нет ... Я не мог точно найти, почему, но вот что я попробовал (возможно, кто-то еще может пролить немного света на это поведение для Zend Engine)

1.-В Си я написал очень глупую программу, которая генерирует файловый дескриптор # 0 (это не аналогично ресурсу в php, но я пробовал это с файловыми ресурсами, чтобы мы могли как-то связать оба языка)

#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);
}

Этот код закроет файловые дескрипторы 0, 1, 2. откроет новый файл и сохранит дескриптор, в результате чего:

$ cat output

0

$

сейчас, в php:

<?php
fclose(STDIN);
fclose(STDOUT);
fclose(STDERR);

$asd = fopen('./outputphp', 'w');
fwrite($asd, print_r($asd, true));
fclose($asd);

это выдаст:

$ cat outputphp

Идентификатор ресурса # 5

$

, поэтому даже закрывая stdin, stdout и stderr, php не будет повторно использовать идентификаторы ресурсов.Более того, идентификатор stdin # 1, stdout - № 2, а stderr - № 3, когда на самом деле stdin имеет дескриптор файла 0, stdout - 1, а stderr - 2. Кроме того, уже выделен другой идентификатор # 4.

так что я бы сказал, что php резервирует id # 0 или вообще не будет его использовать.

, просматривая код движка zend, я обнаружил, что на самом деле ресурс # 0 используется во всем коде, который инициализируетZend Engine в sapi (cgi, cli, modules и т. д.), когда ZTS (защита потока включена).например:

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

при очистке Zend Engine будет проходить таблицу ресурсов, начиная с id # 0.Вы не можете (по крайней мере, я не мог) получить ресурс # 0 с включенной или без безопасности потоков, поэтому # 0, кажется, зарезервирован для обоих случаев, но используется только при включенном ts.

EDIT: для суммирования;)кажется, что вы не можете иметь идентификатор ресурса меньше 1, так как 1, 2, 3 открыты по умолчанию (не уверен насчет # 4, но возможно, что любые новые ресурсы, которые вы откроете, начнутся с # 4 или # 5)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...