Open Girgias opened 4 years ago
About ZIP, I don't know if it worth the work, as we already have a full OO API. Perhaps we should rather deprecate the old functional and minimal API.
@remicollet I was wondering about this a while ago. See my question at https://github.com/php/php-src/pull/5601#issuecomment-631681185
I even had a try at the conversion, but for me, it didn't go as easy as it seemed first, so I stopped. As far as I remember, my main problem was that the data structures used by the OO and procedural interface don't align really well.
Is it really the case? If so, then I'd also prefer deprecating the old API.
I apologize if this was discussed before.
Wouldn't it be appropriate to declare a ResourceInterface
and have all the classes implement that? Methods such as ResourceInterface::close
can provide a unified way to close resources, ResourceInterface::getId
can return spl_object_id()
-esque results, and serializers for example can refuse to serialize all \ResourceInterface
instances.
I apologize if this was discussed before.
Wouldn't it be appropriate to declare a
ResourceInterface
and have all the classes implement that? Methods such asResourceInterface::close
can provide a unified way to close resources,ResourceInterface::getId
can returnspl_object_id()
-esque results, and serializers for example can refuse to serialize all\ResourceInterface
instances.
The whole point of the migration is to move away from the legacy resource behaviour, moreover with objects all the x_close variants become no-ops.
Adding an OOP API to the opaque objects is also a completely orthogonal issue to moving resources to opaque objects.
And I'd rather that we have a long think about each individual API instead of just bundling a weird interface which will be mostly useless IMHO
With the curl class implementation, for example, is_resource()
returns false
for CurlHandle
class objects. This means anyone who wants to check if a given variable is a resource (in a semantic sense) needs to use is_resource
and instanceOf
.
Having an interface means we will need only one instaceOf
op, as opposed to every different class name the migration brings.
This means anyone who wants to check if a given variable is a resource […]
Why do you want to check this? Is there any reason not to check for !== false
?
Because this is an anticipated failure mode of hosting this internal coordination tracker on GitHub, I'm going to err on the side of over-moderation and say: This is not the place to have this discussion. These issues have been discussed extensively on the PHP internals list in the past, and that would also be the place to revisit any decisions.
BZ2 should be filed under ext/standard/streams The only resources it interacts with are streams.
Regarding streams (which are going to be biggest PITA by far), I've been thinking it might make transition smoother (and make calling semantics generally nicer for extension authors) to add a new ZPP type F
which returns a php_strea*
, so:
php_stream *stream;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "F", &stream) == FAILURE) {
RETURN_THROWS();
}
The idea being that we can update the rest of the runtime where streams are taken as arguments to remove any remaining hint of resources first, then work on the internals without a massive chunk of the userspace API breaking underneath us. Obviously a handful of functions will still need special attention (fclose()
, a few stream_*()
functions), but they'll be the minority.
We could even update the stubs file with a not-yet-extant "File" class and initially have the arginfo generator regard this as ZEND_ARG_TYPED_INFO(IS_RESOURCE), but when we do the big switchover, just have the generator now use ZEND_ARG_OBJ_INFO(File). Again, this should let us focus on the hard parts without being bogged down by a thousand callsites.
Edit to add: I just remembered why I never moved on this. php_stream
is a PHP thing, Zend shouldn't call back to PHP. Back to the drawing board.
Okay, expanded idea:
typedef void* (zend_parse_param_callback*)(zval *arg);
// In zpp arg handler:
case 'R': { /* Resolver */
void **ptr = va_arg(*va, void **);
zend_parse_param_callback *callback = va_arg(*va, zend_parse_param_callback*);
*ptr = callback(arg);
if (!*ptr) {
ZEND_ASSERT(EG(exception));
return "";
}
break;
}
Then callsites look like:
{
php_stream *stream;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "R", &stream, php_stream_from_zval) == FAILURE) {
RETURN_THROWS();
}
}
Edit to add: While php_stream_from_zval() doesn't currently throw exceptions, I'm sure we could use a version which does throw a proper TypeError.
On the other hand.... I've just actually sat down to do grep -r php_stream_to_zval ext/ | wc -l and the answer is only 60. So I may be making a tempest in a teapot.
For completeness of the list, the following extensions also saw resource to object changes in PHP 8.0:
The status of the Enchant extension is not 100% clear to me. The change from resource to object is mentioned in the changelog, but the associated PR discussion gives the impression that the commit got reverted: https://github.com/php/php-src/pull/5533
Another one for which I can't seem to determine the status is SNMP. I can see some PHP 8.0 commits mentioning a resource to object change, but I can't find an entry in the changelog, nor an associated PR:
For completeness of the list, the following extensions also saw resource to object changes in PHP 8.0:
* GD, GdImage - [php/php-src#4714](https://github.com/php/php-src/pull/4714) * XML - [php/php-src#3526](https://github.com/php/php-src/pull/3526) * XMLWriter - [php/php-src#4706](https://github.com/php/php-src/pull/4706)
The status of the Enchant extension is not 100% clear to me. The change from resource to object is mentioned in the changelog, but the associated PR discussion gives the impression that the commit got reverted: php/php-src#5533
Have a look at commit: https://github.com/php/php-src/commit/cd3e04dff375fbfaba37a4ae1c8ef1805f63c940 for Enchant
Thanks @Girgias !
Another one for which I can't seem to determine the status is SNMP.
Me neither, but it seems there is an OOP API as of PHP 5.4.0 (http://github.com/php/php-src/commit/5e82e334ddffcf577542a74a37f3388d14790686) which is not documented at all.
PS: oh, it is documented.
@cmb69 Thanks for taking a look! Still not entirely clear what the change in PHP 8.0 is related to that. Let's hope someone figures it out and adds it to the changelog (if relevant enough) ;-)
A long term project is to move all extension resources to objects as they are all in all better.
This issue aims to list the remaining usages of resources within php-src
Related RFC: https://wiki.php.net/rfc/resource_to_object_conversion
PHP 8.0:
PHP 8.1:
Scheduled for PHP 8.4:
Scheduled for PHP 9.0:
Remaining:
Persistent resources that are only used internally and not exposed to userland: