<?php

class ArrayHelper
{
	public static function getValue($array, $key, $default = null)
    {
        if (!is_array($array) && !is_object($array)) {
            throw new InvalidParamException('Argument passed to getValue() must be an array or object.');
        }
        if ($key instanceof \Closure) {
            return $key($array, $default);
        }
        if (is_array($key)) {
            $lastKey = array_pop($key);
            foreach ($key as $keyPart) {
                $array = static::getValue($array, $keyPart);
            }
            $key = $lastKey;
        }
        if (is_array($array) && (isset($array[$key]) || array_key_exists($key, $array)) ) {
            return $array[$key];
        }
        if (($pos = strrpos($key, '.')) !== false) {
            $array = static::getValue($array, substr($key, 0, $pos), $default);
            $key = substr($key, $pos + 1);
        }
        if (is_object($array)) {
            // this is expected to fail if the property does not exist, or __get() is not implemented
            // it is not reliably possible to check whether a property is accessible beforehand
            return $array->$key;
        } elseif (is_array($array)) {
            return (isset($array[$key]) || array_key_exists($key, $array)) ? $array[$key] : $default;
        } else {
            return $default;
        }
    }
}


$arrayHelper = new ArrayHelper();


print_r($arrayHelper::getValue($_POST, 'username'));
echo "\n";

$post = ['username' => 'forecho'];
print_r($arrayHelper::getValue($post, 'username'));
echo "\n";

class Address
{
	public $street = '唐人街';
}

class User
{
	public $username = 'forecho1';
	public $address;
	
	function __construct() 
	{
		$this->address = new Address();
	}
}

print_r($arrayHelper::getValue(new User(), 'username'));
echo "\n";


print_r($arrayHelper::getValue(new User(), 'address.street'));
echo "\n";







$versions = ['date' => '2016年12月19日', '1.0' => ['date' => '2016年12月18日']];
print_r($arrayHelper::getValue($versions, ['1.0', 'date']));