Buen dia... tengo una funcion que lista directorios en un tree view. Tengo una funcion para subir archivos a esos directorios que estan en un servidor. Al subir un archivo con ñ por ejemplo: Albañil lo sube bien al servidor sin problemas pero no se me ve en mi sistema web a la hora de cargarlo en el tree view, aca les dejo la funcion..si me pudieran ayudar gracias de antemano.
Utilizo una expresion regular la cual creo esta correcta.
protected function path($id) {
$id = str_replace('/', DIRECTORY_SEPARATOR, $id);
$id = trim($id, DIRECTORY_SEPARATOR);
$id = $this->real($this->base . DIRECTORY_SEPARATOR . $id);
return $id;
}
public function lst($id, $with_root = false) {
$dir = $this->path($id);
$lst = @scandir($dir);
if(!$lst) { throw new Exception('Could not list path: ' . $dir); }
$res = array();
foreach($lst as $item) {
if($item == '.' || $item == '..' || $item === null) { continue; }
$tmp = preg_match('([^ a-z -я-_0-9.]+)ui', $item);
if($tmp === false || $tmp === 1) { continue; }
if(is_dir($dir . DIRECTORY_SEPARATOR . $item)) {
$res[] =array('text' => $item, 'children' => true, 'id' => $this->id($dir . DIRECTORY_SEPARATOR . $item), 'icon' => 'folder') ;
}
else {
$res[] = array('text' => $item, 'children' => false, 'id' => $this->id($dir . DIRECTORY_SEPARATOR . $item), 'type' => 'file', 'icon' => 'file file-'.substr($item, strrpos($item,'.') + 1));
}
}
if($with_root && $this->id($dir) === '/') {
$res = array(array('text' => basename($this->base), 'children' => $res, 'id' => '/', 'icon'=>'folder', 'state' => array('opened' => true, 'disabled' => true)));
}
return $res;
}
Hola,
El problema no está en el subida ni en el tree view, está en esta línea:
$tmp = preg_match('([^ a-z -я-_0-9.]+)ui', $item);
Estás usando esa expresión regular como filtro: si encuentra algún carácter «raro» en el nombre del fichero, hace continue y lo salta de la lista. El problema es la clase de caracteres [^ a-z -я-_0-9.]: ese rango raro en medio (con una letra cirílica suelta) es casi seguro un problema de copiar/pegar o de guardar el fichero con una codificación distinta a la que esperabas, y el resultado es que letras acentuadas y la ñ caen fuera del conjunto permitido. Por eso el archivo se sube bien al servidor (eso no pasa por esta función) pero desaparece del árbol: esta función de listado lo está descartando activamente.
La solución más robusta no es intentar enumerar a mano qué letras acentuadas permitir, sino usar las clases Unicode que ya trae PCRE para «cualquier letra» y «cualquier número»:
$tmp = preg_match('/[^p{L}p{N}_. -]/u', $item);
p{L} significa «cualquier carácter que sea una letra en cualquier idioma» (incluye ñ, acentos, y letras de otros alfabetos), y p{N} cualquier dígito. Así el filtro sigue bloqueando caracteres realmente problemáticos (barras, comillas, etc.) sin excluir letras válidas de nombres de fichero en español.
Un detalle más a vigilar: asegúrate también de que el fichero PHP donde vive esta función está guardado en UTF-8 sin BOM, si el propio código fuente tiene una codificación distinta, ese carácter cirílico suelto en el patrón es exactamente el tipo de síntoma que delata el problema.
David Carrero