thecodingmachine / safe
PHP 核心函数,在错误发生时抛出异常而不是返回 FALSE
Requires
- php: ^8.0
Requires (Dev)
- phpstan/phpstan: ^1.5
- phpunit/phpunit: ^9.5
- squizlabs/php_codesniffer: ^3.2
- thecodingmachine/phpstan-strict-rules: ^1.0
- 8.1.x-dev
- v2.5.0
- v2.4.0
- v2.3.1
- v2.3.0
- dev-master / 2.2.x-dev
- v2.2.3
- v2.2.2
- v2.2.1
- v2.2.0
- v2.2-alpha
- v2.1.4
- v2.1.3
- v2.1.2
- v2.1.1
- v2.1.0
- v2.0.2
- v2.0.1
- 2.0
- 2.0.0-alpha.3
- 2.0.0-alpha.2
- 2.0.0-alpha.1
- 1.x-dev
- v1.3.3
- v1.3.2
- v1.3.1
- v1.3.0
- v1.2.1
- v1.2.0
- v1.1.3
- v1.1.2
- v1.1.1
- v1.1
- v1.0.3
- v1.0.2
- v1.0.1
- v1.0.0
- v1.0.0-beta4
- v1.0.0-beta3
- v1.0.0-beta2
- 1.0.0-beta1
- v0.1.16
- v0.1.15
- v0.1.14
- v0.1.13
- v0.1.12
- v0.1.11
- v0.1.10
- v0.1.9
- v0.1.8
- v0.1.7
- v0.1.6
- v0.1.5
- v0.1.4
- v0.1.3
- v0.1.2
- v0.1.1
- v0.1.0
- dev-create-pull-request/regenerate-files
- dev-dependabot/composer/generator/guzzlehttp/psr7-2.5.0
- dev-fgetcsv
- dev-sleep
- dev-mktime
- dev-OpenSSLCertificate
- dev-curlHandle
- dev-more-strict-php-requirement
This package is auto-updated.
Last update: 2024-09-22 03:10:19 UTC
README
Safe PHP
一组核心 PHP 函数被重写,以便在遇到错误时抛出异常而不是返回 false
。
问题
大多数 PHP 核心函数都是在添加异常处理之前编写的。因此,大多数 PHP 函数不会抛出异常。相反,在出现错误时它们会返回 false
。
但我们大多数人太懒惰了,以至于不想逐个检查每个核心 PHP 函数的每个返回值。
// This code is incorrect. Twice. // "file_get_contents" can return false if the file does not exist // "json_decode" can return false if the file content is not valid JSON $content = file_get_contents('foobar.json'); $foobar = json_decode($content);
这段代码的正确版本应该是
$content = file_get_contents('foobar.json'); if ($content === false) { throw new FileLoadingException('Could not load file foobar.json'); } $foobar = json_decode($content); if (json_last_error() !== JSON_ERROR_NONE) { throw new FileLoadingException('foobar.json does not contain valid JSON: '.json_last_error_msg()); }
显然,虽然这个片段是正确的,但它不那么容易阅读。
解决方案
输入 thecodingmachine/safe 也称为 Safe-PHP。
Safe-PHP 重新声明了所有核心 PHP 函数。新的 PHP 函数的行为与旧函数完全一样,只是在遇到错误时适当地抛出异常。这些“安全”函数的名称与核心 PHP 函数相同,但它们位于 Safe
命名空间中。
use function Safe\file_get_contents; use function Safe\json_decode; // This code is both safe and simple! $content = file_get_contents('foobar.json'); $foobar = json_decode($content);
所有可以在错误时返回 false
的 PHP 函数都是 Safe 的一部分。此外,Safe 还提供了两个 'Safe' 类:Safe\DateTime
和 Safe\DateTimeImmutable
,其方法将抛出异常而不是返回 false。
PHPStan 集成
是的...但我必须为应用程序的每个文件显式地考虑导入函数的“安全”版本。我确信我会忘记一些“use function”语句!
不用担心!thecodingmachine/safe 伴随着一个 PHPStan 规则。
之前没有听说过 PHPStan?去看看吧,它是一个令人惊叹的 PHP 代码分析器。
只需在 PHPStan 设置中安装 Safe 规则(在“安装”部分中解释),PHPStan 就会每次告诉你何时使用了“不安全”的函数。
下面的代码将触发此警告
$content = file_get_contents('foobar.json');
函数 file_get_contents 不安全使用。它可以返回 FALSE 而不是抛出异常。请将 'use function Safe\file_get_contents;' 添加到文件的开始部分以使用由 'thecodingmachine/safe' 库提供的版本。
安装
使用 composer 安装 Safe-PHP
$ composer require thecodingmachine/safe
强烈推荐:安装 PHPStan 和 PHPStan 扩展
$ composer require --dev thecodingmachine/phpstan-safe-rule
现在,编辑你的 phpstan.neon
文件并添加以下规则
includes: - vendor/thecodingmachine/phpstan-safe-rule/phpstan-safe-rule.neon
自动重构
你有大量的遗留代码库,并想在项目中使用“Safe-PHP”函数?PHPStan 会帮助你找到这些函数,但逐个更改函数的命名空间可能是一项繁琐的任务。
幸运的是,Safe 随带一个“Rector”配置文件。Rector 是一个命令行工具,可以即时重构你的应用程序。
运行
$ composer require --dev rector/rector
安装 rector/rector
。
运行
vendor/bin/rector process src/ --config vendor/thecodingmachine/safe/rector-migrate.php
运行 rector/rector
。
注意:不要忘记将“src/”替换为你的源目录路径。
重要:重构只执行“愚蠢”的函数替换。它不会修改处理“false”返回值的方式。所以如果你的代码已经执行了错误处理,你将需要手动处理。
特别是,你应该寻找已经执行的错误处理,如下
if (!mkdir($dirPath)) { // Do something on error }
此代码将被 Rector 重构为
if (!\Safe\mkdir($dirPath)) { // Do something on error }
然后你应该(手动)将其重构为
try { \Safe\mkdir($dirPath)); } catch (\Safe\FilesystemException $e) { // Do something on error }
性能影响
Safe 在每个请求中从大约85个文件中加载1000+个函数。然而,这种加载对性能的影响非常低。
如果您担心,使用Safe会在每个请求中“花费”大约700µs。性能部分包含了更多关于我们如何测试Safe性能影响的信息。
了解更多
如果您想了解更多关于触发Safe-PHP开发的信息,请阅读TheCodingMachine博客上的发布文章。
贡献
包含所有函数的文件是从PHP文档自动生成的。阅读CONTRIBUTING.md文件,了解如何重新生成这些文件以及如何为此库做出贡献。