Archivio della categoria 'PHP'

Scansione ricorsiva di una directory con PHP

Open Source, PHP, Tips & tricks Nessun commento »

Ci sono script che dovresti sempre avere a portata di mano, perché finisce che ne hai bisogno nei momenti e nelle occasioni più impensabili. Questa function in PHP, ad esempio, mi ha risparmiato in molti casi un’inutile perdita di tempo: passandole come argomento una stringa che corrisponde al percorso completo da scandire, la function scan_directory_recursively restituisce un array contenente la struttura completa della directory specificata.

È possibile indicare, come secondo argomento opzionale, una estensione o una porzione di testo che non dovrà necessariamente comparire nel nome del file. Si tratta in pratica di un filtro per escludere una certa classe di risultati.

Ad esempio:

$dirs=scan_directory_recursively('/home/ivan/Tempo');

restituisce un array di tutte le directory e i file contenuti in /home/ivan/Tempo, mentre:

$dirs=scan_directory_recursively('/home/ivan/Tempo','.php');

restituisce un array di tutte le directory e i file contenuti in /home/ivan/Tempo ad eccezione dei file con estensione .php!

Non è opera mia, per questo motivo chiedo a chiunque ne faccia uso nei propri progetti di non rimuovere i riferimenti a lixlpixel, il sito Internet da cui provengono.

Ecco la function:

< ?php
// ------------ lixlpixel recursive PHP functions -------------
// scan_directory_recursively( directory to scan, filter )
// expects path to directory and optional an extension to filter
// of course PHP has to have the permissions to read the directory
// you specify and all files and folders inside this directory
// ------------------------------------------------------------
 
// to use this function to get all files and directories in an array, write:
// $filestructure = scan_directory_recursively('path/to/directory');
 
// to use this function to scan a directory and filter the results, write:
// $fileselection = scan_directory_recursively('directory', 'extension');
 
function scan_directory_recursively($directory, $filter=FALSE)
{
    // if the path has a slash at the end we remove it here
    if(substr($directory,-1) == '/')
    {
        $directory = substr($directory,0,-1);
    }
 
    // if the path is not valid or is not a directory ...
    if(!file_exists($directory) || !is_dir($directory))
    {
        // ... we return false and exit the function
        return FALSE;
 
    // ... else if the path is readable
    }elseif(is_readable($directory))
    {
        // we open the directory
        $directory_list = opendir($directory);
 
        // and scan through the items inside
        while (FALSE !== ($file = readdir($directory_list)))
        {
            // if the filepointer is not the current directory
            // or the parent directory
            if($file != '.' && $file != '..')
            {
                // we build the new path to scan
                $path = $directory.'/'.$file;
 
                // if the path is readable
                if(is_readable($path))
                {
                    // we split the new path by directories
                    $subdirectories = explode('/',$path);
 
                    // if the new path is a directory
                    if(is_dir($path))
                    {
                        // add the directory details to the file list
                        $directory_tree[] = array(
                            'path'    => $path,
                            'name'    => end($subdirectories),
                            'kind'    => 'directory',
 
                            // we scan the new path by calling this function
                            'content' => scan_directory_recursively($path, $filter));
 
                    // if the new path is a file
                    }elseif(is_file($path))
                    {
                        // get the file extension by taking everything after the last dot
                        $extension = end(explode('.',end($subdirectories)));
 
                        // if there is no filter set or the filter is set and matches
                        if($filter === FALSE || $filter == $extension)
                        {
                            // add the file details to the file list
                            $directory_tree[] = array(
                                'path'      => $path,
                                'name'      => end($subdirectories),
                                'extension' => $extension,
                                'size'      => filesize($path),
                                'kind'      => 'file');
                        }
                    }
                }
            }
        }
        // close the directory
        closedir($directory_list); 
 
        // return file list
        return $directory_tree;
 
    // if the path is not readable ...
    }else{
        // ... we return false
        return FALSE;    
    }
}
// ------------------------------------------------------------
 
?>

Per comodità vostra, ma anche mia, aggiungo qui una versione priva di commenti e pronta per il download:

Condividi:
  • del.icio.us
  • Google
  • Digg
  • Sphinn
  • Facebook
  • Technorati
  • YahooMyWeb

Funzioni anonime in PHP

Open Source, PHP, Tips & tricks 2 commenti »

PHP è un buon linguaggio di programmazione, se lo si giudica con i parametri abbastanza empirici del grado di diffusione e della mole di function che integra. Si dimostra però spesso sorprendentemente flessibile anche per affrontare scenari di programmazione molto più complessi del semplice embedding di script in una pagina web.

Durante un recente scambio di opinioni con un matematico appassionato di Open Source si è presentato il problema di creare funzioni anonime e - qui sta il punto - di farlo all’interno di una classe PHP. Tralascio lo sproloquio teorico che mi sono dovuto sorbire sul lambda calcolo e le funzioni anonime e mi limito a riportare qui un passaggio della definizione che ne dà WikiPedia. Cito testualmente:

Il lambda calcolo è un sistema di riscrittura definito formalmente dal matematico Alonzo Church. È stato sviluppato per analizzare formalmente le definizioni di funzioni, le loro applicazioni ed è uno strumento interessante per studiare anche fenomeni di ricorsione. In quanto sistema di riscrittura, esso dà una descrizione dei termini ben formati, che sono le sequenze di simboli riconosciute dal sistema e in grado di essere riscritti da esso. Il lambda calcolo, infatti, definisce un insieme di regole di riscrittura che determinano in maniera precisa come i termini stessi possano essere riscritti. In questo modo, il processo di riscrittura diventa un vero e proprio calcolo.

E ancora (disponibile solo in inglese):

Anonymous functions can be used to contain functionality that need not be named and possibly for short-term use. Some notable examples include closures and currying. [...]
Closures are functions evaluated in an environment containing bound variables. The following example binds the variable “threshold” in an anonymous function that compares the input to the threshold. [...]
Currying is transforming a function from multiple inputs to fewer inputs (in this case integer division).

Anche se ufficialmente non esiste in PHP un vero e proprio metodo per gestire le funzioni anonime, si può facilmente ottenere qualcosa di simile in almeno due modi:

  1. chiamando una variabile col nome di una funzione:
    $foo = "phpinfo";
    $foo();
  2. inizializzando una variabile con l’istruzione `create_function`:
    $sum = create_function('$a, $b','return $a + $b;');
    echo $sum(1,2);

Nel primo caso stiamo creando soltanto un link alla funzione. Nel secondo, invece, assegniamo la funzione alla variabile proprio mentre la creiamo. Provare per credere: si tratta di un aspetto insolito e per certi versi divertente del PHP, ma scoraggio chiunque ad adottare una soluzione simile in ambienti di produzione in cui non si vogliano perdere di vista praticità e facilità di lettura del codice.

Condividi:
  • del.icio.us
  • Google
  • Digg
  • Sphinn
  • Facebook
  • Technorati
  • YahooMyWeb

Convertire un testo in array di righe con la costante PHP_EOL

Open Source, PHP, Tips & tricks Nessun commento »

Quando si scrivono applicazioni per il web in PHP capita spessissimo di dovere trattare i dati contenuti in un file di testo. Il metodo migliore per acquisire dati di questo tipo è senz’altro la funzione `file`, che restituisce appunto un array contenente tutte le righe del file di testo.

Capita però altrettanto spesso di avere a che fare con script PHP datati o realizzati per girare in situazioni anomale, come ad esempio server embedded che mettono a disposizione un range limitato di funzioni PHP, oppure ancora di script che elaborano le righe del testo nel momento stesso in cui lo generano.

In questi casi si può ricorrere a una sintassi meno immediata ma altrettanto efficace, ricorrendo alla funzione `explode` e alla costante di sistema PHP_EOL.

Ecco un semplice esempio:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
< ?php
 
$txtMessage = <<<EOD
RIGA #1
RIGA #2
RIGA #3
RIGA #4
EOD;
 
$aLines = explode(PHP_EOL, $txtMessage);
 
echo "<table border=\"1\">\n" .PHP_EOL;
 
foreach ($aLines as $strLine)
{
  echo "<tr>\n".PHP_EOL."<td>\n".$strLine."</td>\n".PHP_EOL."</tr>\n".PHP_EOL;
}
 
echo "\n" .PHP_EOL;
 
?>

Il risultato sarà il seguente:

RIGA #1
RIGA #2
RIGA #3
RIGA #4

 

La costante PHP_EOL equivale al carattere di end of line del sistema operativo su cui stiamo elaborando lo script: ricorrere a questa costante non migliora soltanto la leggibilità del nostro programma, ma anche la sua portabilità.

Condividi:
  • del.icio.us
  • Google
  • Digg
  • Sphinn
  • Facebook
  • Technorati
  • YahooMyWeb

Differenza fra date con PHP

PHP, Tips & tricks Nessun commento »

Calcolare la differenza fra due date in termini di giorni è molto, molto semplice con PHP. Ecco la function che restituisce il calcolo:

function days_diff( $giornoA, $meseA, $annoA, $giornoB, $meseB, $annoB )
{
$timestampA = mktime(0, 0, 0, $meseA, $giornoA, $annoA);
$timestampB = mktime(0, 0, 0, $meseB, $giornoB, $annoB);
$diff = floor(($timestampB - $timestampA) / (3600 * 24));
return $diff;
}
I valori da passare alla function sono i seguenti:

  • $giornoA, $meseA, $annoA: giorno, mese ed anno (int) della data minore
  • $giornoB, $meseB, $annoB: giorno, mese ed anno (int) della data maggiore
Condividi:
  • del.icio.us
  • Google
  • Digg
  • Sphinn
  • Facebook
  • Technorati
  • YahooMyWeb