I am updating my project from PHP 7.0 to PHP 8.0 and I couldn't find out, if it is allowed to EXPLICITLY assign resource
as the data type:
What I know right now is, that:
resource
is one of the types building the mixed type,resource
.Until now I read:
Am I missing something, somewhere?
Thank you for your time.
For more clarity, this is how I want to use the resource
data type in my project (PSR-7 implementation):
<?php
namespace MyPackages\Http\Message;
use Psr\Http\Message\StreamInterface;
/**
* Stream.
*/
class Stream implements StreamInterface {
/**
* A stream, e.g. a resource of type "stream".
*
* @var resource
*/
private resource $stream;
/**
* @param string|resource $stream A filename, or an opened resource of type "stream".
* @param string $accessMode (optional) Access mode. 'r': Open for reading only.
*/
public function __construct(string|resource $stream, string $accessMode = 'r') {
$this->stream = $this->buildStream($stream, $accessMode);
}
/**
* Build a stream from a filename or an opened resource of type "stream".
*
* Not part of PSR-7.
*
* @param string|resource $stream Filename, or resource.
* @param string $accessMode Access mode.
* @return resource
* @throws \RuntimeException If the file cannot be opened.
* @throws \InvalidArgumentException If the stream or the access mode is invalid.
*/
private function buildStream(string|resource $stream, string $accessMode): resource {
if (is_string($stream)) {
//... some validations ...
/*
* Open the file specified by the given filename.
* E.g. create a stream from the filename.
* E.g. create a resource of type "stream" from the filename.
*/
try {
$stream = fopen($stream, $accessMode);
} catch (\Exception $exception) {
throw new \RuntimeException('The file "' . $stream . '" could not be opened.');
}
} elseif (is_resource($stream)) {
if ('stream' !== get_resource_type($stream)) {
throw new \InvalidArgumentException('The provided resource must be an opened resource of type "stream".');
}
}
return $stream;
}
}
No, you cannot type hint with resource
.
Here's an RFC from 2015 where it was brought up, here's the PR with the implementation, and here's a thread of discussion on it.
The gist is that the PHP community wants to get rid of resources because they represent an older way of doing things. Also, resource
is too generic, basically equivalent to object
that it doesn't provide much, if any benefit.
From the discussion:
The reason for this is that the resource type is an anachronism from an age in which PHP did not have objects, yet still needed to make certain types of data opaque. The resource type is a type that exists only to shuffle around C pointers between internal functions. It has no semantic value. Because resources are now redundant, given the existence of objects, their time is running out, and they will be replaced at some point. Adding a type declaration for resource would mean that code using it would break if we replace any existing usage of resources with objects, preventing migration away from resource
Andrea Faulds
And
The long term plan is to do transitions similar to the one which GMP underwent: It uses GMP objects since PHP 5.6 and was using resources previously.
...
In addition to what Andrea said (resource type hint causing issues should we choose to migrate to objects), I also think that the resource type hint provides relatively little value in itself. It only says that you are accepting some resource. However, resources are many. Is this a file handle? Is it a database connection? Is it a streaming hash context? It doesn't tell.
Nikita Popov