You have an array of directories (straightforward list of directories):
<?php
$array = array(
'/home/drapeko/var',
'/home/drapeko/var/y',
'/home/drapeko',
'/home',
'/var/libexec'
);
);
?>
And you would like to transform this array to hierarchy of directories:
<?php
$array = array (
'home' => array (
'drapeko' => array (
'var' => array (
'y' => array()
)
)
),
'var' => array(
'libexec' => array()
)
);
?>
How can you do it?
First of all the below function will help us.
<?php
/**
* This function converts real filesystem path to the string array representation.
*
* for example,
* '/home/drapeko/var/y will be converted to $result_array['home']['drapeko']['var']['y']
* '/home/drapeko/var/y/file.txt will be converted to $result_array['home']['drapeko']['var']['y']
*
* @param $path realpath of the directory
* @return string string array representation of the path
*/
function pathToArrayStr($path) {
// TODO constants/configs?
$res_path = str_replace(array(':/', ':\\', '/', '\\', DIRECTORY_SEPARATOR), '/', $path);
// if the first or last symbol is '/' delete it (e.g. for linux)
$res_path = preg_replace(array("/^\//", "/\/$/"), '', $res_path);
// create string
$res_path = '[\''.str_replace('/', '\'][\'', $res_path).'\']';
return $res_path;
}
?>
It simply converts the real path of the file to array string representation.
How can you use this function? I know it looks like a little confusing. But it's quite simple. Consider the example below:
<?php
$result = array();
$check = array();
foreach($array as $val) {
$str = pathToArrayStr($val, 'result');
foreach($check as $ck) {
if (strpos($ck, $str) !== false) {
continue 2;
}
}
$check[] = $str;
eval('$result'.$str.' = array();');
}
print_r($result);
?>
Heh, how do you find it? This approach has helped me very much. I hope you will find it useful. :)
Функции за работа с файловата система
Вж. също
За свързани функции вижте секциите Директория и Изпълнение на програми.
За списък с обяснения за различните URL опаковки, които могат да се използват за достъп до отдалечени файлове вижте List of Supported Protocols/Wrappers.
Съдържание
- basename — Връща името на файла от даден път(path)
- chgrp — Сменя групата на файл
- chmod — Променя режима (mode) на файл
- chown — Променя собственика на файл
- clearstatcache — Изчиства кеша за статуса на файл
- copy — Копира файл
- delete — Вижте unlink или unset
- dirname — При подаден път връща само частта, съдържаща директорията
- disk_free_space — Връща свободното пространство в директория
- disk_total_space — Връща пълния размер на директория
- diskfreespace — Псевдоним на disk_free_space
- fclose — Closes an open file pointer
- feof — Проверява дали указателят е в края на файла
- fflush — Записва данните буферирани в изходия поток във файл
- fgetc — Взима символ от файлов указател
- fgetcsv — Взима ред от файл от текущата позиция, указана от указателя на файла, и го анализира за CVS полета
- fgets — Взима ред от файл от позицията, сочена от файловия указател
- fgetss — Взима ред от файл и изрязва HTML таговете
- file_exists — Проверява дали даден файл съществува
- file_get_contents — Изчита файл в низ
- file_put_contents — Записва низ във файл
- file — Изчита целия файл в масив
- fileatime — Взима времето, когато файлът е бил използван за последно
- filectime — Връща кога за последно е бил променян файла
- filegroup — Връща групата на файл
- fileinode — Връща inode на файл
- filemtime — Връща времето на последна промяна на файл
- fileowner — Връща собственика на файла
- fileperms — Връща правата за работа с файл
- filesize — Връща размера на файл
- filetype — Връща типа на файла
- flock — Преносимо (portable) съвещателно заключване на файл
- fnmatch — Търси съвпадение между име и шаблон
- fopen — Отваря файл или URL
- fpassthru — Изкарва всичките оставащи данни от файлов указател
- fputcsv — Форматира ред като CSV (Comma Separated Values) и го записва във файл
- fputs — Псевдоним на fwrite
- fread — Двоично-безопасно изчитане на файл
- fscanf — Интерпретира входа от файл спрямо указан формат
- fseek — Поставя файловия указател за позиция на зададената позиция
- fstat — Дава информация относно файл при подаден файлов указател
- ftell — Връща позицията на указателя за писане/четене във файл
- ftruncate — Отрязва файл до зададената дължина
- fwrite — Двоично-безопасно записване във файл
- glob — Намира пътища и файлове отговарящи на шаблон
- is_dir — Проверява дали дадено име на файл е директория
- is_executable — Проверява дали даден файл е изпълним
- is_file — Казва дали filename е обикновен файл
- is_link — Казва дали filename е символна връзка (symbolic link)
- is_readable — Казва дали filename е разрешен за четене
- is_uploaded_file — Казва дали файлът е качен чрез HTTP POST
- is_writable — Казва дали файлът е записваем
- is_writeable — Псевдоним на is_writable
- lchgrp — Сменя групата на символна връзка
- lchown — Сменява собственика на символна връзка
- link — Създава "твърда връзка"
- linkinfo — Взима информация относно връзка
- lstat — Дава информация за файл или символна връзка
- mkdir — Създава директория
- move_uploaded_file — Премества качен файл на ново място
- parse_ini_file — Parse a configuration file
- parse_ini_string — Parse a configuration string
- pathinfo — Връща информация за пътя на файла
- pclose — Затваря файлов манипулатор на процес
- popen — Отваря файлов манипулатор към процес
- readfile — Извежда съдържанието на файл
- readlink — Връща името на файла сочен от символична връзка
- realpath — Връща каноничния абсолютен път
- rename — реименува файл или директория
- rewind — Връща указателя за позиция във файл в началото на файла
- rmdir — Премахва директория
- set_file_buffer — Псевдоним на stream_set_write_buffer
- stat — Дава информация относно файл
- symlink — Създава символична връзка
- tempnam — Създава файл с уникално файлово име
- tmpfile — Създава временен файл
- touch — "Докосване" на файл. Променя времето на достъп и времето на модификация на файл
- umask — Променя текущата маска umask
- unlink — Изтрива файл
drapeko.com
23-May-2009 06:19
Christian
17-Mar-2007 09:24
I just learned that, to specify file names in a portable manner, you DON'T need 'DIRECTORY_SEPARATOR' - just use '/'. This really surprised and shocked me, as until now I typed about a zillion times 'DIRECTORY_SEPARATOR' to stay platform independent - unnecessary. Don't make the same mistake.
tunnelareaten at gmail dot com
25-Feb-2005 08:27
I made this function to search and/or display files by extension or for a string occurance in the filename. Any comments or enhancements are welcome offcourse. I'll update this function soon.
usage: list_files([string], [string], [int 1 | 0], [int 1 | 0]);
search for extension: list_files([string], [string], [0], [int 1 | 0]);
returns array: $myArray = list_files([string], [string], [0], [0]);
echo result: list_files([string], [string], [0], [1]);
search for string occurance: list_files([string], [string], [1], [int 1 | 0]);
returns array: $myArray = list_files([string], [string], [1], [0]);
echo result: list_files([string], [string], [1], [1]);
<?php
function list_files($directory, $stringSearch, $searchHandler, $outputHandler) {
$errorHandler = false;
$result = array();
if (! $directoryHandler = @opendir ($directory)) {
echo ("<pre>\nerror: directory \"$directory\" doesn't exist!\n</pre>\n");
return $errorHandler = true;
}
if ($searchHandler === 0) {
while (false !== ($fileName = @readdir ($directoryHandler))) {
if(@substr ($fileName, - @strlen ($stringSearch)) === $stringSearch) {
@array_push ($result, $fileName);
}
}
}
if ($searchHandler === 1) {
while(false !== ($fileName = @readdir ($directoryHandler))) {
if(@substr_count ($fileName, $stringSearch) > 0) {
@array_push ($result, $fileName);
}
}
}
if (($errorHandler === true) && (@count ($result) === 0)) {
echo ("<pre>\nerror: no filetype \"$fileExtension\" found!\n</pre>\n");
}
else {
sort ($result);
if ($outputHandler === 0) {
return $result;
}
if ($outputHandler === 1) {
echo ("<pre>\n");
print_r ($result);
echo ("</pre>\n");
}
}
}
?>
http://iubito.free.fr
30-Dec-2003 04:39
Here is a function I wrote to get the relative path between 2 files or directory.
We suppose that paths are wrotten in Unix format (/ instead of windows \\)
<?php
/**
* Return the relative path between two paths / Retourne le chemin relatif entre 2 chemins
*
* If $path2 is empty, get the current directory (getcwd).
* @return string
*/
function relativePath($path1, $path2='')
{
if ($path2 == '') {
$path2 = $path1;
$path1 = getcwd();
}
//Remove starting, ending, and double / in paths
$path1 = trim($path1,'/');
$path2 = trim($path2,'/');
while (substr_count($path1, '//')) $path1 = str_replace('//', '/', $path1);
while (substr_count($path2, '//')) $path2 = str_replace('//', '/', $path2);
//create arrays
$arr1 = explode('/', $path1);
if ($arr1 == array('')) $arr1 = array();
$arr2 = explode('/', $path2);
if ($arr2 == array('')) $arr2 = array();
$size1 = count($arr1);
$size2 = count($arr2);
//now the hard part :-p
$path='';
for($i=0; $i<min($size1,$size2); $i++)
{
if ($arr1[$i] == $arr2[$i]) continue;
else $path = '../'.$path.$arr2[$i].'/';
}
if ($size1 > $size2)
for ($i = $size2; $i < $size1; $i++)
$path = '../'.$path;
else if ($size2 > $size1)
for ($i = $size1; $i < $size2; $i++)
$path .= $arr2[$i].'/';
return $path;
}
?>
Enjoy ! :-)
Gregor Mosheh
22-Aug-2003 05:23
This function searches a directory and returns an array of all files whose filename matches the specified regular expression. It's similar in concept to the Unix find program.
function findfile($location='',$fileregex='') {
if (!$location or !is_dir($location) or !$fileregex) {
return false;
}
$matchedfiles = array();
$all = opendir($location);
while ($file = readdir($all)) {
if (is_dir($location.'/'.$file) and $file <> ".." and $file <> ".") {
$subdir_matches = findfile($location.'/'.$file,$fileregex);
$matchedfiles = array_merge($matchedfiles,$subdir_matches);
unset($file);
}
elseif (!is_dir($location.'/'.$file)) {
if (preg_match($fileregex,$file)) {
array_push($matchedfiles,$location.'/'.$file);
}
}
}
closedir($all);
unset($all);
return $matchedfiles;
}
$htmlfiles = findfile('/some/dir','/\.(htm|html)$/');
Gregor Mosheh
16-Jul-2003 10:25
I needed a function to find disk usage for a directory and its subs, so here it is. It's kinda like the Unix du program, except it returns the usage in bytes, not blocks.
function du($location) {
if (!$location or !is_dir($location)) {
return 0;
}
$total = 0;
$all = opendir($location);
while ($file = readdir($all)) {
if (is_dir($location.'/'.$file) and $file <> ".." and $file <> ".") {
$total += du($location.'/'.$file);
unset($file);
}
elseif (!is_dir($location.'/'.$file)) {
$stats = stat($location.'/'.$file);
$total += $stats['size'];
unset($file);
}
}
closedir($all);
unset($all);
return $total;
}
print du('/some/directory');
l_domenech at yahoo dot ca
03-Jul-2003 10:25
In the code samples of the user-contributed notes, you'll find functions that sometimes need a slash at the end of a folder path and sometimes don't.
Here's a little function to append a slash at the end of a path if there isn't one already.
function append_slash_if_none($string)
{
if (ereg ("/$", $string))
{
return $string;
}
else
{
return ereg_replace("$", "/", $string);
}
}
(Replace with a backslash if you're on Windows...)
mitra at mitra dot biz
15-May-2003 10:10
Pollard@php.net contributed this in response to a question on setting these variables ...
This option *IS* settable within your PHP scripts.
Example:
<?php
ini_set('auto_detect_line_endings', true);
$contents = file('unknowntype.txt');
ini_set('auto_detect_line_endings', false);
$content2 = file('unixfile.txt');
?>
Note, with PHP 4.3 anytime Mac files are read using fgets or file you'll need to auto_detect_line_endings since \n is otherwise assumed. However, with PHP 5.0, stream_get_line() will allow you to specify what line ending character to read up to.
\\ Read a line from a MAC file
stream_get_line($fp, 4096, "\r");
\\ Read a line from a UNIX file
stream_get_line($fp, 4096, "\n");
\\ Read a line from a DOS file
stream_get_line($fp, 4096, "\r\n");
\\ Read a line up to any filesystem line ending
ini_set('auto_detect_line_endings', true); fgets($fp);
\\ You can also make up your own line ending characters:
\\ Read up to the first instance of ":"
stream_get_line($fp, 4096, ":");
regis at webstuff dot com dot br
03-Apr-2003 07:49
Here is a useful function if you're having trouble writing raw bytes into a file.
It receives an integer and returns an array containing the ASCII values of the bytes on each index of the array.
function int2bytes($number){
$byte = $number;
$i=0;
do{
$dec_tmp = $byte;
$byte = bcdiv($byte,256,0);
$resto = $dec_tmp - (256 * $byte);
$return[] = $resto;
} while($byte >= 256);
if($byte) $return[] = $byte;
return array_reverse($return);
}
Example:
$arr = int2bytes(75832);
$arr will contain the following values:
Array
(
[0] => 1
[1] => 40
[2] => 56
)
Now, to write this data to the file, just use a fputs() with chr(), just like this:
fputs($fp,chr($arr[0]).chr($arr[1]).chr($arr[2]))
-- Regis
jdhurn at uberidx dot com
08-Mar-2003 07:18
This is a function I use to determine if a file contains Binary information. I use this for my search engine so that it doesn't try to index files like .zip or .mp3 or any other file that doesn't contain readable information. It makes use of the Character Type Extension if it's loaded, if it's not then it uses Regular Expressions.
function is_binary($link)
{
$tmpStr = '';
@$fp = fopen($link, 'rb');
@$tmpStr = fread($fp, 256);
@fclose($fp);
if($tmpStr != '')
{
$tmpStr = str_replace(chr(10), '', $tmpStr);
$tmpStr = str_replace(chr(13), '', $tmpStr);
$tmpInt = 0;
for($i =0; $i < strlen($tmpStr); $i++)
{
if( extension_loaded('ctype') )
{
if( !ctype_print($tmpStr[$i]) )
$tmpInt++;
}
else
{
if( !eregi("[[:print:]]+", $tmpStr[$i]) )
$tmpInt++;
}
}
if($tmpInt > 5)
return(0);
else
return(1);
}
else
return(0);
}
