PHP 8:将 "resource" 分配为 属性、参数或 return 类型
PHP 8: Assign "resource" as property, parameter, or return type
我正在将我的项目从 PHP 7.0 更新到 PHP 8.0,但我找不到是否允许 EXPLICITLY 分配 resource
作为数据类型:
- 一个class属性,
- method/function 参数,
- 由 method/function,
返回
我现在知道的是:
resource
是构建 mixed type, 的类型之一
- 一些内部函数,如 fopen,正在返回类型
resource
。
直到现在我读到:
- 关于迁移到 PHP 8 的所有官方手册:PHP: Migrating from PHP 5.5.x to PHP 5.6.x, ..., PHP: Migrating from PHP 7.4.x to PHP 8.0.x;
- 全部内容在PHP.Watch: PHP Versions;
- 全部内容在Lindevs: PHP.
我是不是遗漏了什么地方?
感谢您的宝贵时间。
为了更清楚,这就是我想在我的项目(PSR-7 实现)中使用 resource
数据类型的方式:
<?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;
}
}
不,您不能使用 resource
键入提示。
这是上面的 RFC from 2015 where it was brought up, here's the PR with the implementation, and here's a thread of discussion。
要点是 PHP 社区想要摆脱资源,因为它们代表了一种旧的做事方式。另外,resource
太笼统了,基本上等同于 object
,如果有任何好处的话,它并没有提供太多。
来自讨论:
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
和
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
我正在将我的项目从 PHP 7.0 更新到 PHP 8.0,但我找不到是否允许 EXPLICITLY 分配 resource
作为数据类型:
- 一个class属性,
- method/function 参数,
- 由 method/function, 返回
我现在知道的是:
resource
是构建 mixed type, 的类型之一
- 一些内部函数,如 fopen,正在返回类型
resource
。
直到现在我读到:
- 关于迁移到 PHP 8 的所有官方手册:PHP: Migrating from PHP 5.5.x to PHP 5.6.x, ..., PHP: Migrating from PHP 7.4.x to PHP 8.0.x;
- 全部内容在PHP.Watch: PHP Versions;
- 全部内容在Lindevs: PHP.
我是不是遗漏了什么地方?
感谢您的宝贵时间。
为了更清楚,这就是我想在我的项目(PSR-7 实现)中使用 resource
数据类型的方式:
<?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;
}
}
不,您不能使用 resource
键入提示。
这是上面的 RFC from 2015 where it was brought up, here's the PR with the implementation, and here's a thread of discussion。
要点是 PHP 社区想要摆脱资源,因为它们代表了一种旧的做事方式。另外,resource
太笼统了,基本上等同于 object
,如果有任何好处的话,它并没有提供太多。
来自讨论:
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
和
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