Ok, no estoy seguro de que sea a prueba de balas, pero creo 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;
});
Esto tomará el primer valor de la matriz como cadena de referencia. Luego iterará sobre la cadena de referencia y comparará cada carácter con el carácter de la segunda cadena en la misma posición. Si un carácter no coincide, la cadena de referencia se acortará a la posición del carácter y se comparará la siguiente cadena. Entonces, la función devolverá la cadena coincidente más corta.
El rendimiento depende de las cuerdas dadas. Cuanto antes se acorte la cadena de referencia, más rápido finalizará el código. Sin embargo, realmente no tengo ni idea de cómo poner eso en una fórmula.
Descubrí que el enfoque de Artefacto para clasificar las cuerdas aumenta el rendimiento. Añadiendo
asort($array);
$array = array(array_shift($array), array_pop($array));
antes de array_reduce
que aumentará significativamente el rendimiento.
También tenga en cuenta que esto devolverá la subcadena inicial coincidente más larga , que es más versátil pero no le dará la ruta común . Tienes que correr
substr($result, 0, strrpos($result, '/'));
en el resultado. Y luego puedes usar el resultado para eliminar los valores
print_r(array_map(function($v) use ($path){
return str_replace($path, '', $v);
}, $array));
que debería dar:
[0] => /lib/abcdedd
[1] => /conf/xyz/
[2] => /conf/abc/def
[3] => /htdocs/xyz
[4] => /lib2/abcdedd
Comentarios bienvenidos.