<?php

/**
 * Simple php equivalent of Oracle's decode()
 *
 * It can be used as simple oneline-alternative to switch or if operators in many
 * cases without difficult logic. For example, get string mnemocode of some value:
 *
 * echo 'State: '.decode($state, 0, 'disabled', 1, 'enabled', 'unknown');
 *
 * will output:
 * 'State: disabled' if $state === 0
 * 'State: enabled' if $state === 1
 * 'State: unknown' in other cases
 *
 * This is how decode() works:
 * 1)   Store first argument separately from other ones to compare them with it
 * 2)   Reduce and reindex array of arguments from 0
 * 3)   Detect default value:
 * 3.1) If count of fresh args array is odd (which means that decode() was called
 *      with even args count) then the last known argument is default result.
 *      We also need to reduce and reindex args array here.
 * 3.2) If count is even, then default result === null.
 * 4)   The rest of args processing this way:
 *    - every even argument (n, n+2, n+4,...) is possible value;
 *    - every odd arg (n+1, n+3, n+5,...) is result for previous arg.
 * 
 * @see https://docs.oracle.com/cd/B19306_01/server.102/b14200/functions040.htm
 * @author Anthony Axenov
 * @return mixed
 */
function decode()
{
    $args = func_get_args();
    $expression = $args[0];
    unset($args[0]);
    $args = array_values($args);
    if (count($args) % 2 !== 0) {
        $default = $args[count($args) - 1];
        unset($args[count($args) - 1]);
        $args = array_values($args);
    } else {
        $default = null;
    }
    for ($i = 0; $i < count($args); $i += 2) {
        if ($expression === $args[$i] && isset($args[$i + 1])) {
            return is_callable($args[$i + 1]) ? call_user_func($args[$i + 1]) : $args[$i + 1];
        }
    }
    return $default;
}

// usage:
$somevar = 'function';
$anything = 'Lorem ipsum dolor sit amet';
$result = decode($somevar,                   // 0
    true      , 'decode(): boolean true',    // 1
    0         , 'decode(): int zero',        // 2
    '0'       , 'decode(): string zero',     // 3
    'string'  , 'decode(): just string',     // 4
    'function', function() use ($anything) { // 5
        // bla-bla-bla some logic here
        $anything = explode(' ', $anything);
        return 'Hey, this is '.print_r($anything, true);
    },
    'decode(): default result'               // 6 -- comment this line to get null
);
var_dump($result);
