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

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

作者: 赵客缦胡缨v吴钩霜雪明 | 来源:发表于2020-11-12 09:34 被阅读0次

    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的方式有些不同,也更加让人耳目一新。

    相关文章

      网友评论

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

          本文链接:https://www.haomeiwen.com/subject/wipubktx.html