Come sempre la notte porta consiglio...

Alla fine ho risolto facendo varie prove con le espressioni regolari, questa è la funzione che ho scritto e che va con tutti i tipi di carattere esprimibili in UTF-8 (i miei script e le pagine generate sono tutti codificati con questa codifica):

Codice PHP:
public function filter($value) {
    
$value = (string) $value;
    
// split the input in characters respecting utf8 properties
    
preg_match_all('/./ux'$value$chars);
    
$firstchar true;
    
$output '';
    foreach (
$chars[0] as $char) {
        if (
preg_match('/\pL/ux'$char)) {
            if (
$firstchar) {
                
$firstchar false;
            } else if (
preg_match('/\p{Lu}/ux'$char)) {
                
// if is uppercase and not first char in a word, strtolower it
                
$char mb_strtolower($charmb_detect_encoding($char));
            }
        } else {
            
$firstchar true;
        }
        
// adding to output
        
$output .= $char;
    }
    return 
$output;

E questo è l'output della funzione su una frase con i caratteri più strani che mi siano venuti in mente

Original value: fràSe Da ñApíLiooÓÃÍ
Filtered value: fràse Da ñapíliooóãí
Time to 100000 run: 1.92074 sec.

Saluti.