ganglio/please

PHP Functional Try

v1.1.0.2 2016-03-03 15:10 UTC

This package is not auto-updated.

Last update: 2024-09-20 21:58:27 UTC


README

Functional and polite implementation of try/catch

Latest Stable Version Build Status codecov.io Code Climate Scrutinizer Code Quality License

Examples

Let's start with something simple:

$inverse = function ($v) {
  if (empty($v)) {
    throw new \Exception("Division by zero");
  }

  return 1/$v;
}

Usually what we would do is something like this:

try {
  $result = $inverse(0);
} catch (\Exception $e) {
  error_log("Error: " . $e->getMessage());
}

Using Please we do:

$result = new Please($inverse, 0);

Now we can check if the callable completed successfully or not.

if ($result->isSuccess) {
  echo "The result is: " . $result->get();
}

Or we can do it using a callback (much nicer)

$result->onSuccess(function ($v) {
  echo "The result is: " . $v;
});

Unfortunately we tried to divide by zero so the callable didn't succeeded. We can either get the exception:

$exception = $result->get();

Or process it with the callback:

$result->onFailure(function ($e) {
  error_log("Error: " . $e->getMessage());
});

We can even pass two callbacks using on:

$result->on(
  function ($v) {
    echo "Result: " . $v;
  },
  function ($e) {
    echo "Error: " . $e->getMessage();
  }
);

onSuccess, onFailure and on return a new instance of Please wrapping the callback. This way, if we want we can do something like this:

echo (new Please($inverse, $unknown_divisor))
  ->on(
    function ($v) {
      return "Result: " . $v;
    },
    function ($e) {
      return "Error: " . $e->getMessage;
    }
  )->get();

And now a slighly more complex example:

Let's immagine we have an array of strings, some of which are json encoded objects:

$strings = [
  'not json',
  '{"a":3,"b":4}',
  'still not json',
  '{"c":5}',
];

And a wrapper to json_decode throwing and exception on error:

$json_decoder_exception = function ($string) {
  $out = json_decode($string);
  if (json_last_error() != JSON_ERROR_NONE) {
    throw new \Exception("Invalid JSON");
  }
  return $out;
};

We can then decode and filter them using Please:

$results = array_filter(
  array_map(function ($s) use ($json_decoder_exception) {
    return new Please($json_decoder_exception, $s);
  }, $strings),
  function ($e) {
    return $e->isSuccess;
  }
);