Ok, não tenho certeza se isso é à prova de balas, mas acho que funciona:
echo array_reduce($array, function($reducedValue, $arrayValue) {
if($reducedValue === NULL) return $arrayValue;
for($i = 0; $i < strlen($reducedValue); $i++) {
if(!isset($arrayValue[$i]) || $arrayValue[$i] !== $reducedValue[$i]) {
return substr($reducedValue, 0, $i);
}
}
return $reducedValue;
});
Isso tomará o primeiro valor da matriz como string de referência. Em seguida, ele itera sobre a string de referência e compara cada caractere com o caractere da segunda string na mesma posição. Se um char não corresponder, a string de referência será encurtada para a posição do char e a próxima string será comparada. A função retornará a string correspondente mais curta.
O desempenho depende das cordas fornecidas. Quanto mais cedo a string de referência ficar mais curta, mais rápido o código terminará. Eu realmente não tenho ideia de como colocar isso em uma fórmula.
Descobri que a abordagem da Artefacto para classificar as cordas aumenta o desempenho. Adicionando
asort($array);
$array = array(array_shift($array), array_pop($array));
antes de o array_reduce
aumentará significativamente o desempenho.
Observe também que isso retornará a substring inicial correspondente mais longa , que é mais versátil, mas não fornecerá o caminho comum . Voce tem que correr
substr($result, 0, strrpos($result, '/'));
no resultado. E então você pode usar o resultado para remover os valores
print_r(array_map(function($v) use ($path){
return str_replace($path, '', $v);
}, $array));
que deve dar:
[0] => /lib/abcdedd
[1] => /conf/xyz/
[2] => /conf/abc/def
[3] => /htdocs/xyz
[4] => /lib2/abcdedd
Feedback bem-vindo.