Подтвердить что ты не робот

Предоставляются ли ресурсы php по ссылке?

Сегодня я обнаружил, что помимо объектов и примитивов PHP имеет ресурсы. В документации указано, что по умолчанию php передает имена по значению. Но мы знаем, что в PHP 5, объекты ссылаются на дескриптор, и поэтому, пока дескриптор передается по значению, вы можете обрабатывать дескрипторы как ссылки сами, аккуратно избегая вопроса.

Но как насчет ресурсов? Являются ли они, подобно объектам, просто ручками, которые будут рассматриваться как сами ссылки, или они являются значениями, которые копируются при их передаче?

Например:

/**
 * Close the ftp connection and throw an exception.
 *
 * @hack Because php doesn't have a `finally` statement,
 *       we workaround it to make sure the ftp connection is closed.
 * @param resource $conn FTP Buffer
 * @param Exception $e
 */
function ftpCloseWithException($conn, $e) {
    ftp_close($conn); // <-- Is this the same FTP Buffer resource or a new one?
    throw $e;
}
/**
 * Copy the README file from ftp.mozilla.org or do something equally arbitrary using ftp.
 */
function getMozReadme() {
    try {
        $conn = ftp_connect('ftp.mozilla.org');
        …
    } catch (Exception $e) {
        ftpCloseWithException($conn, $e);
    }
}
4b9b3361

Ответ 1

Ресурс - это не фактическое соединение. Ресурс - не что иное, как указатель на соединение. Поэтому, когда вы закрываете соединение, принадлежащее этому ресурсу, не имеет значения, было ли оно оригинальным или скопированным.

Ответ 2

Нет, они не передаются по ссылке по умолчанию, они обрабатываются как любая другая переменная PHP в этом случае. Проверьте этот пример:

function test($fd) {
    $fd = NULL;
}

$fd = fopen('/tmp/test', 'w+');
test($fd);
var_dump(is_resource($fd)); // bool(true);

... но по характеру ресурсов они указывают на один внешний ресурс. Это может быть файл, соединение с базой данных или что-то в этом роде. Таким образом, любые операции с ресурсом (или его копией) будут иметь прямое влияние на этот единственный внешний ресурс.

Проверьте этот пример:

function close($fd) {
    fclose($fd);
}

$fd = fopen('/tmp/test', 'w+');
close($fd);
var_dump(is_resource($fd)); // bool(false);

В приведенном выше примере механизм PHP сбрасывает ссылки all на $fd во всех областях после закрытия файлов. Это означает, что с точки зрения этого побочного эффекта они не могут быть точно такими же, как другие переменные.

Ответ 3

Ресурс не является ни объектом, ни переменной. Это всего лишь ресурс. В основном это означает, что вы действительно не взаимодействуете с ресурсами так, как вы могли бы сделать, скажем, для объекта. В самой документации PHP говорится:

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

В принципе, если вы не говорите, что работаете над ядром Zend Engine или создаете расширения для PHP, такие как PECL, вы действительно будете беспокоиться о ресурсе. От точки штампа PHP-кода единственный раз, когда мы делаем материал на ресурсах, скажем, чтобы проверить, вернулась ли попытка подключения к базе данных NULL or a resource

У вас есть функция с именем get_resource_type(), которая возвращает type ресурса, например say "file" для возврата функции fopen(), но это просто именованный идентификатор и ничего не вышло.