The transition

I have recently started a series of development work with ThinkPHP 5.1, since I was developing with Laravel, and small problems like the one in the title can be easily implemented in Laravel. Simply use the array_first method for the lookup.

Rapid implementation

But ThinkPHP doesn’t provide a similar way to do it quickly, so is there a need to repeat the wheel? The first method that comes to mind is to use array_search but the official solution in this method is only used for a simple one-dimensional array search, and it returns only an index, which is not the result that we found, but we can retrieve the item by index, A new method array_column, introduced in PHP 5.5, makes it easy to implement a two-dimensional search. The user notes here provide us with a small example.

$userdb=Array
(
    (0) => Array
        (
            (uid) => '100',
            (name) => 'Sandra Shush',
            (url) => 'urlof100'
        ),

    (1) => Array
        (
            (uid) => '5465',
            (name) => 'Stefanie Mcmohn',
            (pic_square) => 'urlof100'
        ),

    (2) => Array
        (
            (uid) => '40489',
            (name) => 'Michael',
            (pic_square) => 'urlof40489'
        )
);

$key = array_search(40489, array_column($userdb, 'uid'));

And it’s got 800+, so at this point you might think that if you take index in this way and you take index out of it, you’ll be fine.

Some 🌰

However, if you scroll down a little bit, you’ll see another user note, and this user note tells us that when we do two-dimensional search in this way you have to have a PHP version of 5.5 +, and the author also tells us that

Since array_column() will produce a resulting array; it won’t preserve your multi-dimentional array’s keys. So if you check against your keys, it will fail.


Because array_column () generates a new array; because array_column () generates a new array; It does not retain the original keys of the multidimensional array. Therefore, if you check your key, it will fail.

Then the author also provides us with a 🌰

$people = array( 2 => array( 'name' => 'John', 'fav_color' => 'green' ), 5 => array( 'name' => 'Samuel', 'fav_color' => 'blue' ) ); $found_key = array_search('blue', array_column($people, 'fav_color')); // 1 // Here, you could expect that the $found_key would be "5" but it's NOT. It will be 1. Since it's the second element of the Produced Array by the array_column() function. // In this case, you expect $found_key to be "5", but it is not. It will be 1. Because it is the second element of the array generated by array_column(). // Secondly, if your array is big, I would recommend you to first assign a new variable so that it wouldn't call array_column() for each element it searches. For a better performance, you could do; Second, if your array is large, I recommend that you assign a new variable first so that it doesn't call array_column() for every element it searches for. For better performance, you can; $colors = array_column($people, 'fav_color'); $found_key = array_search('blue', $colors);

After looking through these hints, you’ve already noticed the hole in this, however, it doesn’t end there, because what you can do with array_search is probably limited to in_array if the data isn’t clean enough. And, even though we’re here, there’s another pothole. First look at 🌰

<? php $userdb = array( 0 => array( 'uid' => 100, 'name' => 'Sandra Shush', 'url' => 'urlof100' ), '8' => array( 'uid' => 5465, 'name' => 'Stefanie Mcmohn', 'pic_square' => 'urlof100' ), '3' => Array( // 'uid' => 5555, 'name' => 'Michael', 'pic_square' => 'urlof40489' ), '6' => Array( 'uid' => 40489, 'name' => 'Michael', 'pic_square' => 'urlof40489' ) ); $found_key = array_search(40489, array_column($userdb, 'uid'));

Guess what $found_key might be here? The answer is: 2. ????? When array_column() is executed, the uid of the third element, which is the key 3, is commented out. PHP ignores it and does not preserve the index position, so the result is only three elements. The fourth element is substituted up because the array index starts at 0. So 2 is going to be the third element.

What do people do?

In the user note area of array_search, we see a lot of array loops and returns, such as this one, but we run into some limitations, and then we think of Laravel as giving the caller the autonomy to do the processing in the anonymous method and return the bool value for processing.

Array_first is a wrapper for the Laravel ::fisrt method. Array_first is a wrapper for the Laravel ::fisrt method. You can also see another method, value(), in this little piece of code. As you can see, this method simply checks if it is an anonymous method, executes the method and returns it if it is, or returns it directly if it is not.

public static function first($array, callable $callback = null, $default = null) { if (is_null($callback)) { if (empty($array)) { return value($default); } foreach ($array as $item) { return $item; } } foreach ($array as $key => $value) { if (call_user_func($callback, $value, $key)) { return $value; } } return value($default); } if (! function_exists('value')) { /** * Return the default value of the given value. * * @param mixed $value * @return mixed */ function value($value) { return $value instanceof Closure ? $value() : $value; }}

Now, this is a pretty complete implementation, but I think of another item related to the helper functions here: Underscore. PHP, which is a PHP method library that also serves as the PHP implementations for Underscore. JS and loadsh and ramda. In this project we saw how to do it

public static function find($array, Closure $closure)
    {
        foreach ($array as $key => $value) {
            if ($closure($value, $key)) {
                return $value;
            }
        }
        return;
    }

The implementation here is much simpler, and we end up with the result we want.