Skip to content

Instantly share code, notes, and snippets.

@marchrius
Created October 12, 2017 08:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save marchrius/93e3d45eb01c5c04d143fcc8668da28a to your computer and use it in GitHub Desktop.
Save marchrius/93e3d45eb01c5c04d143fcc8668da28a to your computer and use it in GitHub Desktop.
Visit object with a path (object and array)
<?php
include_once __DIR__ . '/helpers.php';
$data = ((object)[
"name" => "Matteo",
"surname" => "Gaggiano",
"age" => 25,
"github" => ((object)[
"username" => "Marchrius",
"url" => "https://github.com/Marchrius"
]),
"repositories" => ((object)[
"own" => [
[
"name" => "angular-mimetype",
"link" => "https://github.com/Marchrius/angular-mimetype",
"stars" => 0
]
],
"other" => [
[
"name" => "tracker",
"link" => "https://github.com/antonioribeiro/tracker",
"starts" => 1291
],
[
"name" => "color-thief-php",
"link" => "https://github.com/ksubileau/color-thief-php",
"starts" => 364
],
[
"name" => "angular-moment",
"link" => "https://github.com/urish/angular-moment",
"starts" => 2615
]
]
])
]);
<?php
if (!function_exists("isDotFirst")) {
function isDotFirst($str) {
$posDot = strpos($str, '.');
$posSquare = strpos($str, '[');
$posDot = $posDot === false ? PHP_INT_MAX : $posDot;
$posSquare = $posSquare === false ? PHP_INT_MAX : $posSquare;
return $posDot < $posSquare;
}
}
if (!function_exists("isSquareFirst")) {
function isSquareFirst($str) {
$posDot = strpos($str, '.');
$posSquare = strpos($str, '[');
$posDot = $posDot === false ? PHP_INT_MAX : $posDot;
$posSquare = $posSquare === false ? PHP_INT_MAX : $posSquare;
return $posSquare < $posDot;
}
}
if (!function_exists("extractIndexKey")) {
function extractIndexKey($str) {
$start = strpos($str, '[') + 1;
$end = strpos($str, ']', $start);
$indexKey = substr($str, $start, $end - $start);
if (is_numeric($indexKey))
return intval($indexKey);
return $indexKey;
}
}
// 'path.to[indexKey].property[0]'
if (!function_exists("visitObject")) {
function visitObject($object, $path = null, $default = null) {
// no path. single property
if (null == $path || '' == $path)
return $object;
if (isDotFirst($path)) { // path is like path.to.property
$explodedPaths = explode('.', $path);
$segment = array_shift($explodedPaths);
if (isSquareFirst($segment)) { // has array reference?
$indexKey = extractIndexKey($segment);
$backInArray = '[' . $indexKey . ']';
$segment = str_replace($backInArray, '', $segment);
array_unshift($explodedPaths, $backInArray);
}
$path = implode('.', $explodedPaths);
if (!is_object($object) || !property_exists($object, $segment))
return $default;
return visitObject($object->{$segment}, $path, $default);
} else if (isSquareFirst($path)) { // path is like [0]
if (($sPos = strpos($path, '[')) > 0 && $sPos !== false) {
$segment = substr($path, 0, $sPos);
$path = str_replace($segment, '', $path);
if (!is_object($object) || !property_exists($object, $segment))
return $default;
return visitObject($object->{$segment}, $path, $default);
}
$explodedPaths = explode('.', $path);
$segment = array_shift($explodedPaths);
$indexKey = extractIndexKey($segment);
$path = implode('.', $explodedPaths);
if (!is_array($object) && isset($object[$indexKey]))
return $default;
return visitObject($object[$indexKey], $path, $default);
} else { // path
if (is_object($object) && property_exists($object, $path)) {
return $object->{$path};
}
if (is_array($object) && isset($object[$path])) {
return $object[$path];
}
return $default;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment