Skip to content

Add resource typehint and return type #1631

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed

Add resource typehint and return type #1631

wants to merge 1 commit into from

Conversation

DASPRiD
Copy link
Contributor

@DASPRiD DASPRiD commented Nov 11, 2015

This PR adds a resource typehint and return type. Corresponding RFC:
https://wiki.php.net/rfc/resource_typehint

@laruence laruence added the RFC label Nov 29, 2015
@Fleshgrinder
Copy link
Contributor

@DASPRiD: is this abandoned?

@DASPRiD
Copy link
Contributor Author

DASPRiD commented Jun 27, 2016

@Fleshgrinder it seems like an unwanted feature, since resource itself is too generic.

@staabm
Copy link
Contributor

staabm commented Jun 27, 2016

As far as I remember is the type "resource" itself only a workaround from the time where PHP did not support proper object orientation. It remains in the php-src base only for BC reasons.

newer apis like e.g, PDO wrap this "handles" in a object and hide it from the user, which is the far more elegant approach.

@Fleshgrinder
Copy link
Contributor

That is all fine but there are still many APIs left that actually give you a resource and one might want to type hint against those, even if it is only internally while creating such a wrapping object. Of course, one cannot check the type of the resource itself via type hints, that is actually a problem.

Complicated situation … simply ignoring it is not a good approach imho.

@DASPRiD
Copy link
Contributor Author

DASPRiD commented Jun 27, 2016

At least for file access, we have SplFileObject.

@staabm
Copy link
Contributor

staabm commented Jun 27, 2016

typehint against resource itself is not very helpful either, because you still can pass e.g. a network connection handle into a function which expects a GD resource etc.

@HallofFamer
Copy link

Well if in modern PHP era you still actually use resource type and pass it around functions/methods, then you aint following good OOP practices.

With files and databases you have SplFileObject/MySQLi/PDO classes that you can use. With other resource types such as CURL it wont hurt to write a wrapper class for it.

To summarize, there's no need to typehint on resource because theres no need to pass resource as a parameter/argument to methods/functions.

@Fleshgrinder
Copy link
Contributor

Unless you type hint your privates too. Something that is particularly useful in an environment with many developers who all change code, come and leave, … You are approaching the issue from the mindset of an open source developer I guess.

@staabm: that is exactly the problem I am seeing too. One would need something to specify the resource type too (e.g. function fn(resource<stream> $rs)) but that would still not solve the whole problem. My personal approach, as always as a very defensive programmer, is assert. 😋

@nikic
Copy link
Member

nikic commented Jun 27, 2016

Another issue that was brought up on the ML is that this will complicate migration away from resources, as we did with GMP for example. It would increase the amount of code that would have to change if a resource changes to an object. (Or we'd have to special-case the resource typehint to allow certain objects, which is it's own pit of vipers.)

@Fleshgrinder
Copy link
Contributor

We definitely should come up with a roadmap here and I will invest time if nobody else does before I find the time to do so.

We should most probably close this PR and mark + move the RFC to Withdrawn.

@s3b4stian
Copy link

Hello, I think that resource type hint and return type useful. With Psr-7 I would have liked this feature, precisely when i implemented the stream class.

I so wrote the constructor the stream class:

public function __construct($resource)
{
    if (!is_resource($resource)) {
        throw new InvalidArgumentException(__CLASS__.': Invalid resource provided');
    }

    if  ('stream' !== get_resource_type($resource)) {
        throw new InvalidArgumentException(__CLASS__.': Resource provided is not a stream');
    }

    $this->resource = $resource;
    $this->isPipe = $this->checkFileMode($resource);
}

With resource type hint, I would have written so:

public function __construct(resource $resource)
{
    //only check the type of resource
    if  ('stream' !== get_resource_type($resource)) {
        throw new InvalidArgumentException(__CLASS__.': Resource provided is not a stream');
    }

    $this->resource = $resource;
    $this->isPipe = $this->checkFileMode($resource);
}

Modifies in the php code are very short. I also forked the php-src repository and added myself the resource type hint at s3b4stian/php-src

Before begin a RFC I checked the requests already present and I found this.

Please reconsider the implementation.

@php-pulls
Copy link

Comment on behalf of kalle at php.net:

Closing due to inactivity

@php-pulls php-pulls closed this Sep 26, 2018
@jchook
Copy link

jchook commented Dec 3, 2019

@Fleshgrinder it seems like an unwanted feature, since resource itself is too generic.

What does this say about is_resource()?

Perhaps this critical missing feature exposes a hole in the core design of PHP resources?

I think the community would welcome this 2-line change to php-src, and ultimately, with a little planning, I don't imagine it would stymie future granularity or improvements on the resource umbrella.


From the scalar type hints RFC.

No type hint for resources is added, as this would prevent moving from resources to objects for existing extensions, which some have already done (e.g. GMP).

Why not prefer this type hint capability (and language uniformity) over catering to possible 3rd party extension API changes? Maybe we could provide a generous deadline? Afterwards, extensions could still achieve broad API changes by introducing a new namespace (e.g. mysql vs mysqli).

Altering existing extensions to use object instead of resource still presents the backwards incompatibility problem of users checking is_resource(), no?

@nikic
Copy link
Member

nikic commented Dec 4, 2019

FYI migration from resources to objects is underway, PHP 8 has migrated ext/xml, ext/gd and one more resource type I forgot... So you would type against GdImage rather than abstract resource type, which is essentially useless.

I have no idea how many more extensions will get converted in time for PHP 8, but we can clearly say that resources are on the way out ;)

@moliata
Copy link
Contributor

moliata commented Mar 23, 2020

@nikic So it's safe to say that resource as a data type, will be completely removed from PHP 8.x?

@nikic
Copy link
Member

nikic commented Mar 23, 2020

@moliata No, the type will not be completely removed in PHP 8.

@moliata
Copy link
Contributor

moliata commented Mar 23, 2020

@nikic But then speaking of functions such as fopen() which return the resource type, are these changing any time soon to wrapper objects or will still return a resource.

@KalleZ
Copy link
Member

KalleZ commented Mar 23, 2020

@moliata they will still return a resource, there is no plan to change the streaming API from resources to objects as of now

@moliata
Copy link
Contributor

moliata commented Mar 23, 2020

@KalleZ And as such, I believe that this should be reconsidered and that we should add the resource type hinting support (for parameters, properties and as a return type).

@DASPRiD
Copy link
Contributor Author

DASPRiD commented Mar 23, 2020

@KalleZ And as such, I believe that this should be reconsidered and that we should add the resource type hinting support (for parameters, properties and as a return type).

Actually, as a nice replacement for fopen() there's SplFileObject.

@KalleZ
Copy link
Member

KalleZ commented Mar 23, 2020

@moliata We can't. Because a resource type is returned as an integer value of the index of the internal list that holds open resources. Given resources are not first class citizens (unlike objects).

That means you cannot hint them in anyway even if you have a prototype like function test(resource $fp), then $fp will accept a value from fopen() and a value returned from pgsql_connect() and you are therefore still forced to validate the parameter value with get_resource_type() manually.

I think it is safe to say that we won't be adding any new resources in the future.

@KalleZ
Copy link
Member

KalleZ commented Mar 23, 2020

@DASPRiD That would be a huge BC break and something we cannot do or even consider.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.