Ваша функция обратного вызова не имеет смысла.
Во-первых, поймите, что когда вы сравниваете строки с операторами сравнения (>, <и =), PHP конвертирует символы в этих строках в их порядковые значения, а затем выполняет числовое сравнение, а не лексикографическое. Причина "b" <"t" в том, что на самом деле PHP сравнивает целые числа. Это дает результаты, которые вы не обязательно ожидаете: </p>
php > $one = "a"; $two = "b";
php > var_dump(strcmp($one, $two));
int(-1)
php > $one = "b"; $two = "a";
php > var_dump(strcmp($one, $two));
int(1)
php > $one = "b"; $two = "b";
php > var_dump(strcmp($one, $two));
int(0)
php > $one = "a"; $two = "z";
php > var_dump(strcmp($one, $two));
int(-25)
php > $one = "z"; $two = "a";
php > var_dump(strcmp($one, $two));
int(25)
php > $one = "aa"; $two = "z";
php > var_dump(strcmp($one, $two));
int(-25)
php > $one = "zz"; $two = "a";
php > var_dump(strcmp($one, $two));
int(25)
Использование операторов сравнения для оценки строк следует тому же самому поведению, поэтому ожидается 100%, учитывая то, что находится в вашей функции обратного вызова. Я не уверен, почему вы проверяете, является ли одна подстрока другой. Если вы хотите сначала проверить длины, проверьте их, но поймите, что вскоре вы изменили существующее соглашение PHP о коротких строках; наши первые два возвращаемых значения отражают это изменение.
$result = usort($nc, function ($item1, $item2) use($sortcol){
$string1 = trim(strtolower($item1[$sortcol]));
$string2 = trim(strtolower($item2[$sortcol]));
if (strlen($string1) > strlen($string2) ) {return -1;}
if (strlen($string1) < strlen($string2) ) {return 1;}
return $string1 < $string2;
});