Take the State of PHP 2026 Survey →

Resource to object conversion View as Markdown

Accepted
Authors
Máté Kocsis kocsismate@php.net
Date
2023-10-31
Source
wiki.php.net/rfc/resource_to_object_conversion

Votes

Accept the described approach for converting resources to objects? closed
yes
30
no
0
30 voters
alcaeus yes 2024-01-09 08:15
alec yes 2024-01-09 08:38
asgrim yes 2024-01-12 18:11
ashnazg yes 2024-01-10 17:24
bmajdak yes 2024-01-08 06:41
brzuchal yes 2024-01-05 09:06
bukka yes 2024-01-05 14:17
bwoebi yes 2024-01-05 15:41
crell yes 2024-01-05 16:48
cschneid yes 2024-01-05 09:27
derick yes 2024-01-05 16:32
dharman yes 2024-01-05 13:04
galvao yes 2024-01-05 10:13
girgias yes 2024-01-05 13:10
heiglandreas yes 2024-01-05 08:47
ilutov yes 2024-01-19 08:48
jimw yes 2024-01-09 19:58
kalle yes 2024-01-05 14:17
kocsismate yes 2024-01-05 08:17
levim yes 2024-01-09 23:00
mbeccati yes 2024-01-09 08:34
nicolasgrekas yes 2024-01-05 08:27
ocramius yes 2024-01-05 09:26
petk yes 2024-01-05 18:49
pierrick yes 2024-01-16 19:35
saki yes 2024-01-19 09:25
sebastian yes 2024-01-13 07:36
sergey yes 2024-01-15 14:47
theodorejb yes 2024-01-05 17:49
trowski yes 2024-01-17 22:17
When should the migration of the primary stream resources happen? closed
only in a major version (e.g. PHP 9.0)
23
in any minor or major version (e.g. PHP 8.4)
7
30 voters
alcaeus only in a major version (e.g. PHP 9.0) 2024-01-09 08:16
alec only in a major version (e.g. PHP 9.0) 2024-01-09 08:39
asgrim only in a major version (e.g. PHP 9.0) 2024-01-12 18:12
ashnazg only in a major version (e.g. PHP 9.0) 2024-01-10 17:27
bmajdak only in a major version (e.g. PHP 9.0) 2024-01-08 06:41
brzuchal in any minor or major version (e.g. PHP 8.4) 2024-01-05 09:07
bukka only in a major version (e.g. PHP 9.0) 2024-01-05 14:18
bwoebi in any minor or major version (e.g. PHP 8.4) 2024-01-05 15:41
crell only in a major version (e.g. PHP 9.0) 2024-01-05 16:50
derick only in a major version (e.g. PHP 9.0) 2024-01-05 16:33
dharman in any minor or major version (e.g. PHP 8.4) 2024-01-05 13:12
dmitry only in a major version (e.g. PHP 9.0) 2024-01-09 10:18
galvao only in a major version (e.g. PHP 9.0) 2024-01-05 10:14
girgias only in a major version (e.g. PHP 9.0) 2024-01-05 13:11
heiglandreas in any minor or major version (e.g. PHP 8.4) 2024-01-05 08:47
ilutov only in a major version (e.g. PHP 9.0) 2024-01-19 08:46
jimw in any minor or major version (e.g. PHP 8.4) 2024-01-09 19:59
kalle only in a major version (e.g. PHP 9.0) 2024-01-05 14:18
kocsismate only in a major version (e.g. PHP 9.0) 2024-01-05 08:17
levim only in a major version (e.g. PHP 9.0) 2024-01-09 23:01
mbeccati only in a major version (e.g. PHP 9.0) 2024-01-09 08:34
nicolasgrekas only in a major version (e.g. PHP 9.0) 2024-01-05 08:28
ocramius only in a major version (e.g. PHP 9.0) 2024-01-05 09:26
petk in any minor or major version (e.g. PHP 8.4) 2024-01-05 18:50
pierrick only in a major version (e.g. PHP 9.0) 2024-01-16 19:36
saki only in a major version (e.g. PHP 9.0) 2024-01-19 09:25
sebastian only in a major version (e.g. PHP 9.0) 2024-01-13 07:36
sergey only in a major version (e.g. PHP 9.0) 2024-01-15 14:47
theodorejb in any minor or major version (e.g. PHP 8.4) 2024-01-05 17:48
trowski only in a major version (e.g. PHP 9.0) 2024-01-17 22:17
When should the migration of the auxiliary stream resources happen? closed
only in a major version (e.g. PHP 9.0)
16
in any minor or major version (e.g. PHP 8.4)
14
30 voters
alcaeus only in a major version (e.g. PHP 9.0) 2024-01-09 08:16
alec only in a major version (e.g. PHP 9.0) 2024-01-09 08:39
asgrim only in a major version (e.g. PHP 9.0) 2024-01-12 18:12
ashnazg in any minor or major version (e.g. PHP 8.4) 2024-01-10 17:27
bmajdak only in a major version (e.g. PHP 9.0) 2024-01-08 06:41
brzuchal in any minor or major version (e.g. PHP 8.4) 2024-01-05 09:07
bukka only in a major version (e.g. PHP 9.0) 2024-01-05 14:18
bwoebi in any minor or major version (e.g. PHP 8.4) 2024-01-05 15:42
crell in any minor or major version (e.g. PHP 8.4) 2024-01-05 16:49
derick only in a major version (e.g. PHP 9.0) 2024-01-05 16:33
dharman in any minor or major version (e.g. PHP 8.4) 2024-01-05 13:04
dmitry only in a major version (e.g. PHP 9.0) 2024-01-09 10:19
galvao in any minor or major version (e.g. PHP 8.4) 2024-01-05 10:14
girgias in any minor or major version (e.g. PHP 8.4) 2024-01-05 13:10
heiglandreas in any minor or major version (e.g. PHP 8.4) 2024-01-05 08:48
ilutov only in a major version (e.g. PHP 9.0) 2024-01-19 08:46
jimw in any minor or major version (e.g. PHP 8.4) 2024-01-09 19:59
kalle only in a major version (e.g. PHP 9.0) 2024-01-05 14:18
kocsismate in any minor or major version (e.g. PHP 8.4) 2024-01-05 08:18
levim only in a major version (e.g. PHP 9.0) 2024-01-09 23:01
mbeccati only in a major version (e.g. PHP 9.0) 2024-01-09 08:34
nicolasgrekas only in a major version (e.g. PHP 9.0) 2024-01-05 08:29
nikic in any minor or major version (e.g. PHP 8.4) 2024-01-07 20:28
ocramius only in a major version (e.g. PHP 9.0) 2024-01-05 09:26
petk in any minor or major version (e.g. PHP 8.4) 2024-01-05 18:51
saki only in a major version (e.g. PHP 9.0) 2024-01-19 09:28
sebastian only in a major version (e.g. PHP 9.0) 2024-01-13 07:36
sergey in any minor or major version (e.g. PHP 8.4) 2024-01-15 14:47
theodorejb in any minor or major version (e.g. PHP 8.4) 2024-01-05 17:48
trowski only in a major version (e.g. PHP 9.0) 2024-01-17 22:17
When should the migration of the Process resource happen? closed
in the next major version (e.g. PHP 9.0)
15
in the next minor or major version (e.g. PHP 8.4)
14
29 voters
alcaeus in the next major version (e.g. PHP 9.0) 2024-01-09 08:16
alec in the next major version (e.g. PHP 9.0) 2024-01-09 08:39
asgrim in the next major version (e.g. PHP 9.0) 2024-01-12 18:12
ashnazg in the next minor or major version (e.g. PHP 8.4) 2024-01-10 17:26
bmajdak in the next major version (e.g. PHP 9.0) 2024-01-08 06:41
brzuchal in the next minor or major version (e.g. PHP 8.4) 2024-01-05 09:07
bukka in the next major version (e.g. PHP 9.0) 2024-01-05 14:18
bwoebi in the next minor or major version (e.g. PHP 8.4) 2024-01-05 15:42
crell in the next minor or major version (e.g. PHP 8.4) 2024-01-05 16:50
derick in the next major version (e.g. PHP 9.0) 2024-01-05 16:33
dharman in the next minor or major version (e.g. PHP 8.4) 2024-01-05 13:12
dmitry in the next major version (e.g. PHP 9.0) 2024-01-09 10:19
galvao in the next major version (e.g. PHP 9.0) 2024-01-05 10:14
girgias in the next minor or major version (e.g. PHP 8.4) 2024-01-05 13:10
heiglandreas in the next major version (e.g. PHP 9.0) 2024-01-05 08:48
ilutov in the next major version (e.g. PHP 9.0) 2024-01-19 08:46
jimw in the next minor or major version (e.g. PHP 8.4) 2024-01-09 19:59
kalle in the next minor or major version (e.g. PHP 8.4) 2024-01-05 14:18
kocsismate in the next minor or major version (e.g. PHP 8.4) 2024-01-05 08:18
levim in the next major version (e.g. PHP 9.0) 2024-01-09 23:01
mbeccati in the next major version (e.g. PHP 9.0) 2024-01-09 08:34
nicolasgrekas in the next major version (e.g. PHP 9.0) 2024-01-05 08:28
nikic in the next minor or major version (e.g. PHP 8.4) 2024-01-07 20:28
ocramius in the next major version (e.g. PHP 9.0) 2024-01-05 09:26
petk in the next minor or major version (e.g. PHP 8.4) 2024-01-05 18:51
saki in the next minor or major version (e.g. PHP 8.4) 2024-01-19 09:28
sergey in the next minor or major version (e.g. PHP 8.4) 2024-01-15 14:48
theodorejb in the next minor or major version (e.g. PHP 8.4) 2024-01-05 17:48
trowski in the next major version (e.g. PHP 9.0) 2024-01-17 22:18
When should the migration of the resources of other extensions happen? closed
only in a major version (e.g. PHP 9.0)
12
in any minor or major version (e.g. PHP 8.4)
17
29 voters
alcaeus only in a major version (e.g. PHP 9.0) 2024-01-09 08:16
alec only in a major version (e.g. PHP 9.0) 2024-01-09 08:38
asgrim only in a major version (e.g. PHP 9.0) 2024-01-12 18:12
ashnazg in any minor or major version (e.g. PHP 8.4) 2024-01-10 17:26
bmajdak only in a major version (e.g. PHP 9.0) 2024-01-08 06:42
brzuchal in any minor or major version (e.g. PHP 8.4) 2024-01-05 09:07
bukka only in a major version (e.g. PHP 9.0) 2024-01-05 14:18
bwoebi in any minor or major version (e.g. PHP 8.4) 2024-01-05 15:42
crell in any minor or major version (e.g. PHP 8.4) 2024-01-05 16:49
derick in any minor or major version (e.g. PHP 8.4) 2024-01-05 16:34
dharman in any minor or major version (e.g. PHP 8.4) 2024-01-05 13:04
dmitry only in a major version (e.g. PHP 9.0) 2024-01-09 10:19
galvao in any minor or major version (e.g. PHP 8.4) 2024-01-05 10:14
girgias in any minor or major version (e.g. PHP 8.4) 2024-01-05 13:10
heiglandreas in any minor or major version (e.g. PHP 8.4) 2024-01-05 08:49
ilutov in any minor or major version (e.g. PHP 8.4) 2024-01-19 08:46
jimw in any minor or major version (e.g. PHP 8.4) 2024-01-09 19:59
kalle in any minor or major version (e.g. PHP 8.4) 2024-01-05 14:18
kocsismate in any minor or major version (e.g. PHP 8.4) 2024-01-05 08:18
levim only in a major version (e.g. PHP 9.0) 2024-01-09 23:01
mbeccati only in a major version (e.g. PHP 9.0) 2024-01-09 08:35
nicolasgrekas only in a major version (e.g. PHP 9.0) 2024-01-05 08:29
nikic in any minor or major version (e.g. PHP 8.4) 2024-01-07 20:27
ocramius only in a major version (e.g. PHP 9.0) 2024-01-05 09:26
petk in any minor or major version (e.g. PHP 8.4) 2024-01-05 18:50
saki in any minor or major version (e.g. PHP 8.4) 2024-01-19 09:27
sebastian only in a major version (e.g. PHP 9.0) 2024-01-13 07:36
theodorejb in any minor or major version (e.g. PHP 8.4) 2024-01-05 17:49
trowski only in a major version (e.g. PHP 9.0) 2024-01-17 22:18

Discussions on the mailing list

Convert ext/xml to use an object instead of resource
by Nikita Popov · 13 messages
BC breaking changes in PHP 8.1
by Matthew Weier O'Phinney · 22 messages
[RFC] [Vote] Resource to object conversion
· 6 messages

RFC text

Copied from wiki.php.net, last synchronized Oct 13, 2026 11:50 UTC

Introduction

Resources are a legacy data structure which were superseded by objects a long time ago. They have quite a few disadvantages like the inability of using resource type declarations, lack of garbage collection (they have to be explicitly freed), bad feedback about memory leaks, etc.

As far as I know, Nikita was the first one who realized these shortcomings and started converting resources to objects, ''GMP'' back in 2013, ''XMLParser'' in 2019. However, this ambitious project only got traction during the release cycle of PHP 8 where dozens of extensions were refactored so that they started to use objects instead of resources (tracker ticket). At the time of writing, only around 7 built-in extensions remain which still expose resources...

Discussion

As eliminating resources altogether should be a strategic goal for PHP, this time, the main question is not whether the remaining resources should be converted to objects or not, but the timeline when we can do so, in order to have acceptable level of backward compatibility breaks.

Therefore the goal of this RFC is to set the rules and BC expectations based on which the project can continue. So far, the vast majority of the individual conversions were “unofficial”, meaning they didn't have to go through the formal RFC process, there was no deprecation period (it is not really feasible anyway), and were performed even in minor versions. I do believe this kind of flexibility has been beneficial for the overall project, however, we occasionally get complaints due to the introduced BC breaks. That's what this RFC should prevent for future conversions. But what are these breaks?

First and foremost, the return value changes of is_resource() invocations cause the biggest issues. An example of such situation is the following:

$pipes = [];
$process = proc_open("sleep 1", [], $pipes);
if (is_resource($process)) {
    // do some stuff
    proc_close($process);
}

The above code won't work anymore after the conversion, since the is_resource($process) condition will yield a different result than before (false compared to true).

The easiest solution to fix the problem is to change the condition to the following:

$pipes = [];
$process = proc_open("sleep 1", [], $pipes);
if ($process !== false) {
    // do some stuff
    proc_close($process);
}

By using $process !== false instead of is_resource($process), the if will yield the correct result, and the code is going to be compatible with any PHP version. One could also use is_resource($process) || $process instanceof ProcessHandle, but this is a more verbose way to achieve the same result.

Implementation details

Some people suggest that the is_resource() function should return true for classes which originally used to be resources (read a long thread about this topic here). Doing so would apparently minimize the BC break by making the above mentioned code change unnecessary.

However, the current RFC rejects the usage of the above workaround for any resources besides streams mostly because of the low perceived BC impact of their migration (see the impact analysis below for more information). Additionally, the issues introduced by the is_resource() return value changes are mostly easy to spot and fix (but admittedly need some careful manual work).

In case of streams though - due to their ubiquitous nature - a different course of action is applied in order to avoid the possibly huge BC breaks: is_resouce() will return true if any object is passed to it which previously used to be stream or persistent stream resource. This way the following code will continue to work no matter that streams are represented as objects:

$file = fopen(__DIR__ . "/foo.txt", "r");
if (is_resource($file)) {
    // do some stuff
    fclose($file);
}

Moreover, get_resource_type() is also changed so that it gives a consistent and BC compliant result for streams after the migration:

$pipes = [];
$process = proc_open("sleep 1", [], $pipes);
var_dump(get_resource_type($process));     //  TypeError: Argument #1 ($resource) must be of type resource
 
$file = fopen(__DIR__ . "/foo.txt", "r");
var_dump(get_resource_type($file));        // string(6) "stream"

This way, code using streams doesn't have to be changed at the time of the stream resource to object migration. However, as the end goal is to get rid of resources altogether, the is_resource() function and anything related to resources may occasionally be deprecated and removed in the future.

Resource categories

The resources yet to be migrated can be categorized the following way based on their prevalence (biggest to smallest):

Primary stream-related resources

There are a number of stream-related resources which are to be converted: the most important ones are stream and persistent stream themselves. Historically, these have always been the most widely used resources in the whole PHP ecosystem, since the file handling API is organized around them.

The list of functions which return primary stream resources:

  • File-handling related functions:
    • opendir()
    • popen()
    • fopen()
    • tmpfile()
  • . Compressed file handling related functions:
    • bzopen()
    • gzopen()
    • ZipArchive::getStreamIndex()
    • ZipArchive::getStreamName()
    • ZipArchive::getStream()
  • Socket-related functions:
    • fsockopen()
    • pfsockopen()
    • socket_export_stream()
    • stream_socket_client()
    • stream_socket_server()
    • stream_socket_accept()
  • Database-related functions:
    • PDO::pgsqlLOBOpen()
    • PdoPgsql::lobOpen()
    • pg_socket()
    • SQLite::openBlob()

Impact analysis: Primary stream resources won't be affected by the above mentioned BC break due to workaround discussed in the previous section.

Auxilliary stream-related resources

Furthermore, streams have some auxiliary resources:

  • stream context: it stores parameters/options for the different stream wrappers
  • stream filter: it helps perform operations on streams
  • userfilter.bucket, userfilter.bucket brigade: a very detailed explanation, written by Bob

Auxilliary resources are “isolated” from the primary ones, and used less often than them, that's why it may be possible to migrate the two resource categories separately from each other.

Impact analysis:

  • stream context: since stream_context_create() throws in case of failure, the issue with the is_resource() check doesn't apply to stream context resources
  • stream filter: 3 out of the 2000 most popular PHP packages rely on checking the result of stream_filter_append() and stream_filter_prepend() with is_resource()
  • userfilter.bucket, userfilter.bucket brigade: None of the 2000 most popular PHP packages rely on checking the result of stream_bucket_new() with is_resource(). Since userfilter.bucket brigade is created by PHP itself when the php_user_filter::filter() method is invoked, therefore neither it is affected by the BC break.

Process resource

The Process resource is returned by proc_open(). According to my earlier straw poll, its new class name is going to be ProcessHandle once the migration takes place.

Impact analysis: 31 out of the 2000 most popular PHP packages rely on checking the result of proc_open() with is_resource().

Implementation: https://github.com/php/php-src/pull/12098/

Other resources

The rest of the built-in extensions which currently expose resources are the following:

Impact analysis: None of the 2000 most popular PHP packages rely on the above mentioned resources.

Vote

The RFC consists of a primary vote for accepting the implementation approach and 4 secondary votes for each resource category to decide when it is possible to convert them. Since the majority of the resource migrations in question don't yet have an implementation, most voting choices are intentionally left vague so that they only define whether a resource group can only be migrated in a major version or the conversion can happen in minor versions as well. The primary vote requires 2/3, while the secondary ones require a simple majority in order to be accepted.

Implementation

Vote: Accept the described approach for converting resources to objects? — yes: 30 · no: 0 (closed)

Primary stream resources (stream, persistent stream)

Vote: When should the migration of the primary stream resources happen? — only in a major version (e.g. PHP 9.0): 23 · in any minor or major version (e.g. PHP 8.4): 7 (closed)

Auxiliary stream resources (contexts, filters, brigades, buckets)

Vote: When should the migration of the auxiliary stream resources happen? — only in a major version (e.g. PHP 9.0): 16 · in any minor or major version (e.g. PHP 8.4): 14 (closed)

Process resource

Vote: When should the migration of the Process resource happen? — in the next major version (e.g. PHP 9.0): 15 · in the next minor or major version (e.g. PHP 8.4): 14 (closed)

Other resources

Vote: When should the migration of the resources of other extensions happen? — only in a major version (e.g. PHP 9.0): 12 · in any minor or major version (e.g. PHP 8.4): 17 (closed)

Impact on existing extensions

Extensions which use resources must adapt to the conversion and use objects instead.

Future Scope

Support for resources altogether could be removed in the future.