Reference PHP array by multiple indexes
It appears your fancy solution was only available as of PHP 5.5. You can combine the use of array_search and array_column to fetch your entry in a single line of code:
$items = [
[
'unique_id' => 42,
'url' => 'http://foo.com'
],
[
'unique_id' => 57,
'url' => 'http://bar.com'
],
[
'unique_id' => 36,
'url' => 'http://example.com'
],
];
$bar = $entries[array_search(57, array_column($items, 'unique_id'))];
var_dump($bar);
//outputs
array (size=2)
'unique_id' => int 57
'url' => string 'http://bar.com' (length=14)
Try something like this:
function selectByIdOrURL($array, $data) {
foreach($array as $row) {
if($row['unique_id'] == $data || $row['url'] == $data) return $row;
}
return NULL;
}
$array = array(
array('unique_id' => 5, 'url' => 'http://blah.com'),
array('unique_id' => 3, 'url' => 'http://somewhere_else.com')
);
$found = selectByIdOrURL($array, 5); //array('unique_id' => 5, 'url' => 'http://blah.com')
$nfound = selectByIdOrURL($array, 10); //NULL
Only way I can think of that doesn't involve iterating the array for each search (see Jacob's answer) is to store references to each item in two arrays.
Edit: As the URLs and IDs cannot collide, they may be stored in the same reference array (thanks Matthew)
$items; // array of item objects
// Use objects so they're implicitly passed by ref
$itemRef = array();
foreach ($items as $item) {
$itemRef[$item->unique_id] = $item;
$itemRef[$item->url] = $item;
}
// find by id
$byId = $itemRef[$id];
// find by url
$byUrl = $itemRef[$url];
You could probably encapsulate this nicely using a collection class that implements getById()
and getByUrl()
. Internally, it could store the references in as many arrays as is necessary.
Of course, what you're essentially doing here is creating indexed result sets, something best left to database management systems.