public static function fopen($resource = 'php://temp', $mode = 'w+b')
    {
        static::register();

        $context = stream_context_create(
            [static::PROTOCOL => ['resource' => $resource]]
        );
        set_error_handler(function () {
            throw new Exception('Failed to open stream.');
        });
        try {
            $fp = fopen(static::PROTOCOL . '://', $mode, false, $context);
        } catch (Exception $ex) {
            restore_error_handler();
            throw new InvalidArgumentException(sprintf(
                'Failed to create resource from "%s".',
                is_resource($resource) ? get_resource_type($resource)
                                       : gettype($resource)
            ), null, $ex);
        }
        restore_error_handler();

        return $fp;
    }