PHP学习笔记-新模式:上下文管理器

2020-11-12  本文已影响0人  赵客缦胡缨v吴钩霜雪明

PHP7之后提供了类似上下文概念,如下代码:

function open($file, $mode = 'r'){
  $f = fopen($file, $mode);
  yield $f;
  fclose($f);
}

此函数用的是生成器,我们可以使用foreach循环,只需循环一次。

foreach(open('output.txt','w') as $file)
{
    fwrite($file,'Hello World!');
}

程序员需要构建自己的上下文管理器,这是确保自己清理的一种更简洁的方法。

下一步举个例子,例如要使用PDO连接。首先连接到数据库,在事务中执行一些工作,然后自动提交结果。

类似如下代码:

try
{
  $dbh = new PDO($dsn, $user, $pass, $options);
} catch (Exception $e) {
  die("Unable to connect: " . $e->getMessage());
}
try {
  $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  $dbh->beginTransaction();
  $dbh->exec("insert into users (id, name, wechat) values (5, 'Eric', 'ericlu')");
  $dbh->exec('insert into authors (id) values (5)');
  $dbh->commit();
} catch (Exception $e) {
  $dbh->rollBack();
  echo "Failed: " . $e->getMessage();
}

换用上下文管理器进行相同的操作,代码则要简单很多:

function transaction()
{
  $dbh = new PDO($dsn, $user, $pass, $options);
  $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  $dbh->beginTransaction();
  yield $dbh;
  try {
    $dbh->commit();
  } catch (Exception $e) {
    $dbh->rollBack();
  }
}
// Now use the transaction
foreach(transaction() as $dbh) {
  $dbh->exec("insert into users (id, name, wechat) values (5, 'Eric', 'ericlu')");
  $dbh->exec('insert into authors (id) values (5)');
}

这比第一个示例要复杂。

要点是数据库连接和事务的安装和卸载都发生在dtransaction()外,这里的函数可以和代码的其余部分位于单独的文件或命名空间中,从而使代码执行逻辑保持简洁,不必担心安装/卸载。

另外,在以上例子中使用Iterator接口的ContextManager对象加一个析构函数,对异常处理会更加强壮。

文件、数据库与资源的远程连接,锁,线程这些都是密集型的操作,使用上下文模式则会让代码更简洁,运行更流畅。

在Python和很多语言都利用了此模式。

这是一种让你的PHP代码更有作为的一种模式。诚然,它与以前的编写PHP的方式有些不同,也更加让人耳目一新。

上一篇下一篇

猜你喜欢

热点阅读