in_array() tests for a value and array_search() returns its key, both loosely unless the third argument is true, as it almost always should be. isset($a[$k]) treats a stored null as absent; array_key_exists() does not. count() counts one level, or all levels with COUNT_RECURSIVE.
<?php
$stock = ['BK-101' => 7, 'BK-205' => 0, 'BK-300' => null, 'BK-410' => '12'];
echo json_encode([in_array(12, $stock), in_array(12, $stock, true), // loose, strict
isset($stock['BK-300']), array_key_exists('BK-300', $stock)]), "\n"; // null is "unset"
$pos = array_search('BK-101', array_keys($stock)); // 0: a valid position
echo $pos == false ? 'wrongly missing' : 'found', ' | ', $pos === false ? 'none' : "at $pos";
echo "\n", json_encode(array_keys($stock, 0)), ' ', json_encode(array_keys($stock, 0, true));
$shelves = ['SF' => ['Dune', 'Ubik'], 'Poetry' => ['Odes']];
echo "\n", count($shelves), ' ', count($shelves, COUNT_RECURSIVE), ' ', array_key_last($stock),
' ', json_encode(array_count_values(['SF', 'Poetry', 'SF'])), "\n";Output
[true,false,false,true]
wrongly missing | at 0
["BK-205","BK-300"] ["BK-205"]
2 5 BK-410 {"SF":2,"Poetry":1}The second line is the classic bug: array_search() found BK-101 at position 0, and 0 == false, so test its result with === false. Loosely null == 0, so array_keys($a, 0) lets BK-300 in until the strict flag goes on. array_key_first() and array_key_last() (PHP 7.3) read the end keys, and array_count_values() builds a frequency table. PHP 8.5 deprecates null as an array offset or as the key given to array_key_exists(); both always meant '', so write ''.