Learn about Context Managers in PHP with Example

Learn about Context Managers in PHP with Example

Ever wanted to use a ''with'' block in PHP? One of the nicer patterns in Python is the Context Manager. It's refreshing to work with and learn from various programming languages :)

These days, I spend far more time writing and reviewing code in Python than I do in PHP. It's been a refreshing change of pace, and it's fun to learn different patterns in various programming languages.

If you haven't taken the time to look around to see what other languages or frameworks are doing, I'd highly recommend it.

You may also like: PHP Programming Language - PHP Tutorial for Beginners.

One of the nicer patterns in Python is the Context Manager. In Python, certain objects and functions can be wrapped in a with block used to provide specific context to the code running within it. Opening files, for example, becomes remarkably easy:

with open('output.txt', 'w') as f:
  f.write('Hello world!')

The beauty of this pattern is the automated resource cleanup. You don't have to manage (and free) file pointers manually. You don't have to initialize and disconnect a database session. The context manager handles things for you automatically.

A database context manager could manage creating and closing a connection to the database itself (or the connection pool it uses). Or it could be used to wrap a transaction and automatically commit the results at the end of the block. Either way, you don't have to manage things on your own.

PHP doesn't have a pattern like this natively. I think adding a with construct would be a huge value add for the language, but my lower-level coding skills are a bit too rusty to code up a quick proof of concept. Instead, I can abuse generators and loops to simulate similar functionality with an existing system.

The Python example above used the open() function to demonstrate context management, as applied to files. We can do something similar in PHP with the following helper function:

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

  fclose($f);
}

Since this function is a generator, we can use it natively inside a foreach loop. The thing is, we only ever loop once, so the foreach in this example is really a parallel to Python's with.

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

Since the generator only yields once, we only get a single item to iterate across in our  foreach loop. The loop will also automatically return back to the generator after it iterates, which gives us the opportunity to clean up our context and scope.

It's a bit more verbose than Python, and we have to build our own context managers, but it's a much cleaner way to ensure we're cleaning up after ourselves.

Taking things a step further, assume we need to work with a PDO connection. We want to connect to the database, do some work within a transaction, and automatically commit the result. Doing so imperatively would look something like:

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, first, last) values (5, 'Eric', 'Mann')");
  $dbh->exec('insert into authors (id) values (5)');
  $dbh->commit();
} catch (Exception $e) {
  $dbh->rollBack();
  echo "Failed: " . $e->getMessage();
}

The same operation, leveraging a context manager pattern, would be far simpler:

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, first, last) values (5, 'Eric', 'Mann')");
  $dbh->exec('insert into authors (id) values (5)');
}

This is more complex than the first example. The gist is that the setup and teardown code for the database connection and the transaction happens outside of your business logic. The  transaction() function here could be in a separate file or namespace from the rest of your code, which keeps the execution logic clean and removes the need to worry about setup/teardown at all.

Files, databases, remote connections to resources, locks, threads. These are all intensive operations that could benefit from the use of this pattern - and which do leverage this pattern in Python and other languages.

Is this a pattern that would make a difference in your code? It's certainly different than the way many of us write PHP today. How else might you leverage this pattern? Would it make more sense if we extended the language with our own implementation of with?

Thank for reading! If you liked this post, share it with all of your programming buddies!

This article has been republished from ttmm.io

Further Reading

php python web-development design-pattern

Bootstrap 5 Complete Course with Examples

Bootstrap 5 Tutorial - Bootstrap 5 Crash Course for Beginners

Nest.JS Tutorial for Beginners

Hello Vue 3: A First Look at Vue 3 and the Composition API

Building a simple Applications with Vue 3

Deno Crash Course: Explore Deno and Create a full REST API with Deno

How to Build a Real-time Chat App with Deno and WebSockets

Convert HTML to Markdown Online

HTML entity encoder decoder Online

PHP Web Application Development Company

As a top **PHP Web Application Development Company in USA**[https://www.dataeximit.com/php-development-services/](https://www.dataeximit.com/php-development-services/ "https://www.dataeximit.com/php-development-services/"), we at Data EximIT have...

PHP Website Development

Skenix Infotech is a leading PHP Web Development Company that helps companies get results with industry best practices. Get affordable PHP Development Services.

Hire Python Developers

Are you looking for experienced, reliable, and qualified Python developers? If yes, you have reached the right place. At **[HourlyDeveloper.io](https://hourlydeveloper.io/ "HourlyDeveloper.io")**, our full-stack Python development services...

Hire Dedicated PHP Developer

Looking to hire affordable yet experienced PHP developers? **[Hire Dedicated PHP Developer](https://hourlydeveloper.io/hire-dedicated-php-developer/ "Hire Dedicated PHP Developer")**, who can convert your idea to reality, within the stipulated...

Latest Web Design and Development Trends To Follow In 2020

Web development is a dynamic field. With the emergence of new technologies each year, we can observe web development trends changing to a greater or lesser extent. In 2020 too, new technologies have emerged and