3v4l.org

run code in 300+ PHP versions simultaneously
<?php $items = [ (object)['title' => 'a test title'], (object)['title' => 'second title'], (object)['title' => 'Привет!'], (object)['title' => 'çà'], (object)['title' => '!Not a letter'] ]; // Instantiating the single-byte alphabetical groups... $groups = array_fill_keys(array_merge(range('a','z'), ['other']), []); //var_export($groups); //echo "\n---\n"; // Grouping by first (potentially multi-byte) letter... $translate = [ 'à' => 'a', 'á' => 'a', 'ả' => 'a', 'ạ' => 'a', 'ã' => 'a', 'â' => 'a', 'ầ' => 'a', 'ấ' => 'a', 'ẩ' => 'a', 'ậ' => 'a', 'ẫ' => 'a', 'ă' => 'a', 'ằ' => 'a', 'ắ' => 'a', 'ẳ' => 'a', 'ặ' => 'a', 'ẵ' => 'a', 'ä' => 'a', 'å' => 'a', 'æ' => 'a', 'đ' => 'd', 'è' => 'e', 'é' => 'e', 'ẻ' => 'e', 'ẹ' => 'e', 'ẽ' => 'e', 'ê' => 'e', 'ề' => 'e', 'ế' => 'e', 'ể' => 'e', 'ệ' => 'e', 'ễ' => 'e', 'ë' => 'e', 'ì' => 'i', 'í' => 'i', 'ỉ' => 'i', 'ị' => 'i', 'ĩ' => 'i', 'î' => 'i', 'ï' => 'i', 'ò' => 'o', 'ó' => 'o', 'ỏ' => 'o', 'ọ' => 'o', 'õ' => 'o', 'ô' => 'o', 'ồ' => 'o', 'ố' => 'o', 'ổ' => 'o', 'ộ' => 'o', 'ỗ' => 'o', 'ö' => 'o', 'ø' => 'o', 'ù' => 'u', 'ú' => 'u', 'û' => 'u', 'ũ' => 'u', 'ü' => 'u', 'ů' => 'u', 'ủ' => 'u', 'ụ' => 'u', 'ư' => 'u', 'ứ' => 'u', 'ừ' => 'u', 'ữ' => 'u', 'ử' => 'u', 'ự' => 'u', 'ć' => 'c', 'ĉ' => 'c', 'ç' => 'c', 'ç' => 'c', 'ñ' => 'n', 'ý' => 'y', 'ỳ' => 'y', 'ỷ' => 'y', 'ỵ' => 'y', 'ỹ' => 'y', 'ŷ' => 'y', 'ÿ' => 'y' ]; foreach ($items as $item) { $first = strtr(mb_strtolower(mb_substr($item->title, 0, 1, "UTF-8"), "UTF-8"), $translate); if (isset($groups[$first])) { $groups[$first] = $item; } else { $groups['other'] = $item; } } var_export($groups);
based on PM03n
Output for 7.3.0 - 7.3.23, 7.4.0 - 7.4.11, 8.0.0alpha1 - rc2
array ( 'a' => (object) array( 'title' => 'a test title', ), 'b' => array ( ), 'c' => (object) array( 'title' => 'çà', ), 'd' => array ( ), 'e' => array ( ), 'f' => array ( ), 'g' => array ( ), 'h' => array ( ), 'i' => array ( ), 'j' => array ( ), 'k' => array ( ), 'l' => array ( ), 'm' => array ( ), 'n' => array ( ), 'o' => array ( ), 'p' => array ( ), 'q' => array ( ), 'r' => array ( ), 's' => (object) array( 'title' => 'second title', ), 't' => array ( ), 'u' => array ( ), 'v' => array ( ), 'w' => array ( ), 'x' => array ( ), 'y' => array ( ), 'z' => array ( ), 'other' => (object) array( 'title' => '!Not a letter', ), )
Output for 7.1.25 - 7.1.33, 7.2.0 - 7.2.33
array ( 'a' => stdClass::__set_state(array( 'title' => 'a test title', )), 'b' => array ( ), 'c' => stdClass::__set_state(array( 'title' => 'çà', )), 'd' => array ( ), 'e' => array ( ), 'f' => array ( ), 'g' => array ( ), 'h' => array ( ), 'i' => array ( ), 'j' => array ( ), 'k' => array ( ), 'l' => array ( ), 'm' => array ( ), 'n' => array ( ), 'o' => array ( ), 'p' => array ( ), 'q' => array ( ), 'r' => array ( ), 's' => stdClass::__set_state(array( 'title' => 'second title', )), 't' => array ( ), 'u' => array ( ), 'v' => array ( ), 'w' => array ( ), 'x' => array ( ), 'y' => array ( ), 'z' => array ( ), 'other' => stdClass::__set_state(array( 'title' => '!Not a letter', )), )