Căi UNIX corecte în PHP

Se dă următoarea problemă, aparent mai simplă decât zice titlul: să se determine dacă o cale de tip UNIX este corectă. Buba este faptul că această cale poate să fie către un fișier ce nu există, spre exemplu o cale de UNIX socket ce va fi creat într-un director ce va conține un pool de socket-uri. Deci funcțiile la nivel de filesystem nu vor ajuta, cel puțin nu în primă fază. În cazul  în care există vreo încercare de intuiție a scopului, da, scriu server scripting și în PHP. *sh este prea limitat pentru anumite chestii mai avansate, sau are nevoie de prea mult “boilerplate code”, pe când în Perl nu sunt încă fluent. Pentru cei ce au pierdut știrile de la ora 5, PHP nu mai este de mult un limbaj strict “web oriented”, funcționează bine merci și pentru “general purpose”.

Să revin la problema inițială. Practic se pot identifica două probleme: a) validarea unei căi inexistente – deci apelăm la regex; b) validarea directorului – deși fișierul poate să nu existe în timpul execuției de validare, directorul e musai să fie acolo. De regulă aplicațiile care creează câte un UNIX socket nu verifică aceasta și vor eșua să pornească.

Rezumat, codul arată cam așa:

$validate = preg_match('/^(\/[^\0]*?\/?)[^\0\/]+$/', $path, $matches);
if (empty($validate) === TRUE OR is_dir($matches[1]) !== TRUE OR is_dir($matches[0]) !== FALSE)
{
	// handle error here
}

Acum, discuție pe marginea textului. Acest regex satisface direct ambele probleme. Prima, este fix problema de validare. Se ține cont doar de căi absolute – acesta fiind contextul în care operez. Cu toate acestea, soluția se poate adapta ușor pentru căi relative.

Singurul capturing group din expresie preia întreaga cale, mai puțin numele fișierului. A fost făcută să funcționeze inclusiv pentru root (/). Calea capturată trebuie să fie către un director, pe când calea întreagă trebuie să nu fie un director.

Teoria căilor este simplă. O cale UNIX poate să conțină orice caracter, mai puțin nul, iar / este folosit pe post de separator de directoare, deci este rezervat acestui scop. Căile de tip //var///www//// sunt valide. Exemplul anterior va duce în //var/www unde // în general (Linux, BSD) este tot una cu /. Nu am lucrat pe sisteme unde // să fie distinct față de /, deci nu am considerat că este nevoie să tratez cazul prin expresia de mai sus.

2 thoughts on “Căi UNIX corecte în PHP

  1. SaltwaterC Post author

    Deci funcțiile la nivel de filesystem nu vor ajuta, cel puțin nu în primă fază.

    Tradus: prima fază este fix validarea cu regex, după care se validează captura cu is_dir(). PHP are “lazy evaluation” pentru expresiile logice, deci dacă regex-ul nu capturează nimic adică $validate e gol (FALSE sau 0), atunci înseamnă că acea cale nu este specificată corect. Conform documentației pentru preg_match(), $validate e FALSE în caz de eroare de regex (nu ar trebui să se întâmple în condiții normale) sau 0 în cazul în care nu găsește nimic. Practic is_dir() va face un apel către stat()/lstat() (is_dir() face și symlink resolving) doar în cazul în care calea este validă din punct de vedere sintactic, ceea ce de regulă se întâmplă dacă nu este specificată ca /var/ spre exemplu … /var trece prin regex, dar se oprește la al doilea is_dir(). /fake/file se va opri la primul is_dir() (dacă /fake nu există).

Leave a Reply

Your email address will not be published. Required fields are marked *