Arr::get work with ArrayAccess and NULL values

Passing `NULL` as first argument would return the default.

Passing something else than `array` or instance of `ArrayAccess` would throw an exception.

Using `isset()` for performance reasons.

Using `array_key_exists()` for arrays and `ArrayAccess::offsetExists()` otherwise.

unit tests for new Arr::get()

Signed-off-by: Haralan Dobrev <hkdobrev@gmail.com>

Slightly better performance for Arr::get()

If the check with `isset()` is moved to the top the functionality would be the same.

But when the first argument is and the key is present and the value is not NULL, which is perhaps the most common case, there would be 3 checks less.