sqonk / phext-context
上下文在资源上创建一个块级作用域,并自动管理该资源的创建和清理,无论在使用过程中出现任何异常。
Requires
- php: ^8
- sqonk/phext-core: ^1.1
Requires (Dev)
- phpunit/phpunit: ^9
Suggests
- ext-mysqli: If you wish to use the MySQL transaction context manager.
- ext-pdo: If you wish to use the PDO transaction context manager.
- ext-zip: If you wish to use the ZIP context manager.
README
上下文在资源上创建一个块级作用域,并自动管理该资源的创建和清理,无论在使用过程中出现任何异常,主要目的是帮助消除资源泄漏的可能性。除此之外,它们还能通过自动化操作此类资源的标准逻辑来帮助保持代码简洁。
它们是Python上下文管理器的伪实现。虽然PHP 7及其之前版本目前不允许一对一优雅的解决方案,但以下解释使用了函数回调来达到类似的效果。
虽然其他实现巧妙地使用了生成器和'yield'将资源推送到1次循环的foreach循环中,但在跟随代码时,可读性有所下降。
此实现试图保持代码的可读性,并在被他人研究时能自我解释正在发生什么,即使这会使代码稍微冗长一些。
在许多方法中,临时注入了一个专门的专用错误处理器,将PHP错误转换为抛出的异常。请注意,在上下文管理器内部,您的代码使用的任何标准错误处理系统都将被覆盖,直到管理器退出到父作用域。
安装
通过Composer
$ composer require sqonk/phext-context
上下文功能
默认情况下,该库支持以下管理器
- 文件
- 流
- GD图像
- MySQL事务
- PDO事务
- 错误/异常抑制
- 输出缓冲区抑制
- 输出缓冲区捕获
- ZIP文件
- CURL
可用方法
use \sqonk\phext\context\context;
file
static public function file(string $filePath, string $mode = 'r')
以所需模式打开文件,然后将它传递给回调。回调应接受一个参数,即文件句柄(资源)。
可以抛出异常和错误,但文件将被安全关闭。
示例
// output some sample text to the file 'out.txt'. context::file('out.txt', 'w')->do(function($fh) { fwrite($fh, "This is a test"); });
tmpfile
static public function tmpfile()
打开一个临时文件,将其传递给回调。回调应接受一个参数,即文件句柄(资源)。
可以抛出异常和错误,但文件将被安全关闭。
示例
// output some sample text to the temp file 'out.txt'. context::tmpfile()->do(function($fh) { fwrite($fh, "This is a test"); rewind($fh); println('contents:', fread($fh, 50)); });
stream
static public function stream(string $filePath, int $chunkMultiplier = 1024)
以“读取”模式打开文件,以块的形式下载内容,并将接收到的每个块传递给回调。
默认读取块大小为1024 * 1024,可以通过传递自己的块乘数进行调整。只需注意,您传入的任何值都会被平方,以形成最终的块大小。
此方法使用文件上下文作为其父上下文管理器,因此不会引入任何进一步的异常处理。
示例
context::stream('path/to/large/file.mov')->do(function($buffer) { println(strlen($buffer)); // print out each chunk of data read from the input stream. });
image
static public function image(string $filePath)
使用GD打开图像资源,并将其传递给回调。回调应接受一个参数:图像资源。
示例
/* Open an image, modify it and output the result. */ context::image('/path/to/image.jpg')->do(function($img) { # greyscale imagefilter($img, IMG_FILTER_GRAYSCALE); # pixelate imagefilter($img, IMG_FILTER_PIXELATE, 8, IMG_FILTER_PIXELATE); # output result imagepng($img, 'modifiedImage.png'); });
new_image
static public function new_image(int $width, int $height)
使用GD创建一个具有指定宽度和高度的新的图像资源,并将其传递给回调。
回调应接受一个参数:图像资源。
示例
/* Create a new image, draw to it and output the result. */ context::new_image(500, 500)->do(function($img) { # white background with a black square. imagefilledrectangle($img, 0, 0, 499, 499, imagecolorallocate($img,255,255,255)); imagefilledrectangle($img, 220, 220, 320, 320, imagecolorallocate($img,0,0,0)); # output to file. imagepng($img, 'out.png'); });
supress_errors
static public function supress_errors()
在回调中执行代码块,并忽略所有可能发生的错误和异常。
示例
/* The following block of code throws an exception which is caught and ignored, leaving the program uninterupted. Also note the use of while() on the callback. 'while' is an alias of 'do' and with some context managers makes more syntactic sense. */ context::supress_errors()->while(function() { println('throwing an exception'); throw new Exception('This is a test exception.'); });
no_output
static public function no_output()
执行代码块,同时阻止任何输出到标准输出(CLI SAPI中的控制台或Web浏览器)。
captured_output
static public function captured_output()
在嵌套输出缓冲区中执行代码块,并通过ob_get_contents()
返回结果。
示例
$output = context::captured_output()->do(function() { // Print some text to the output. As the context manager wraps the callback // between ob_start() and ob_end_clean(), the output is captured and returned // to the caller. print 'This is a test.'; }); println($output); // will print "This is a test."
pdo_transaction
static public function pdo_transaction(\PDO $connection)
执行并尝试提交PDO数据库事务。如果在任何点上抛出错误,则事务将回滚。
示例
/* Execute a transaction on a PDO object. The context manager will initiate the transaction before passing off the instance to the callback. Once completed the transaction will be comitted. If an exception is raised at any point then the transaction is rolled back. */ $pdo = ... // your PDO instance, set up as required. context::pdo_transaction($pdo)->do(function($pdo) { // perform operations on the pdo instance. });
mysql_transaction
static publlic function mysql_transaction(\mysqli $connection)
执行并尝试提交一个MySQL数据库事务。如果在任何点上抛出错误,事务将回滚。
curl
static public function curl(string $url = '')
初始化一个cURL句柄。这个cURL句柄被设置为给定的URL,但没有设置其他选项。
zip
static public function zip(string $filePath, $mode = \ZipArchive::CREATE | \ZipArchive::OVERWRITE)
在指定位置以期望的模式打开一个zip文件,然后将其传递给回调函数。回调函数应接受一个参数,即zip句柄(资源)。
默认行为是打开或创建一个zip存档以输出数据。可以通过传递相关的ZipArchive常量来更改模式。
将抛出异常和错误,但文件将被安全关闭。
致谢
Theo Howell
许可证
MIT许可证(MIT)。请参阅许可证文件获取更多信息。