Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Scrivere funzioni personalizzate

Imparare a scrivere e utilizzare delle funzioni scritte ad hoc con php
Imparare a scrivere e utilizzare delle funzioni scritte ad hoc con php
Link copiato negli appunti

Introduzione

Una delle caratteristiche che rendono PHP un linguaggio così usato e così amato, è, oltre alla sua relativa
semplicità di apprendimento e d'uso, l'incredibile ricchezza di funzioni che fanno parte del suo "core"
(basta dare una rapida occhiata al manuale ufficiale per rendersene conto), e che sono quindi immediatamente a
disposizione del programmatore.

Questo differenzia PHP da altri linguaggi di scripting, come Perl o Python ad esempio, il cui nucleo essenziale è costituito da relativamente poche funzioni e che si appoggiano molto a moduli esterni per lo svolgimento di vari compiti.

Naturalmente anche con PHP, come con qualsiasi altro linguaggio di programmazione, è possibile, e talvolta
indispensabile, creare delle funzioni personalizzate per lo svolgimento di compiti specifici.
Ma cosa si intende per funzione ?

Una funzione, semplificando, non è altro che un blocco di codice (che a sua volta può essere formato da variabili, istruzioni e altre funzioni, ma anche niente in ipotesi estrema), racchiuso tra parentesi graffe, cui si dà un nome specifico (che deve essere unico, non possono esistere infatti due funzioni personalizzate con lo stesso nome all'interno dello stesso script, e deve altresì essere diverso dalle funzioni preesistenti), destinato a svolgere un particolare compito.

Schema di una funzione

Una funzione, prima di essere utilizzata, deve essere definita mediante la parola chiave function,
ecco lo schema tipico:

function [&]nome_funzione([&]argomenti) {

/* qui vanno inserite le istruzioni, il codice e
tutto ciò che costituirà il corpo della funzione,
compreso l'eventuale valore restituito */

}

A differenza di altri linguaggi, come C ad esempio, PHP non prevede la fase preliminare della dichiarazione del
prototipo della funzione, ma distingue solo tra definizione (o dichiarazione) e chiamata (o invocazione) della
funzione.

Scomponendo lo schema di funzione presentato sopra, possiamo rilevarne i componenti essenziali:

  • Il nome della funzione. È obbligatorio e deve osservare le regole in tema di nomi delle
    variabili, quindi può iniziare con una lettera o con un underscore (_) e può essere seguito da lettere e/o numeri.
    A differenza delle variabili, il nome delle funzioni (sia predefinite, sia personalizzate) è case-insensitive,
    ossia insensibile alla differenza tra maiuscole e minuscole.
  • Le parentesi tonde. Obbligatorie e destinate a contenere gli argomenti delle funzioni (nel numero desiderato,
    ma comunque facoltativi, una funzione infatti può anche non avere argomenti), cioè le variabili necessarie
    alla funzione per svolgere il suo compito.
  • Il corpo della funzione. Obbligatoriamente racchiuso tra parentesi graffe, può contenere istruzioni,
    variabili, costanti o altre funzioni, ma anche niente in extrema ratio (ovviamente una funzione vuota non è molto
    utile, ma è corretta sintatticamente per cui il parser non solleverà obiezioni).
  • Il valore restituito (o ritornato) dalla funzione. Facoltativo (tramite l'istruzione return) perchè può anche non restituire niente (void).

Osservando attentamente il paradigma di funzione su esposto, si sarà notata la presenza dell'ampersand o
"e" commerciale, che può essere anteposto sia al nome della funzione che ai suoi argomenti, ma a che serve in concreto ?
La funzione che svolge è la medesima in entrambi i casi (anche se le variabili meritano un discorso a parte),
e chi ha una minima familiarità con il linguaggio C, dovrebbe conoscere l'operatore & ed il suo significato di
indirizzo.

Senza approfondire troppo il discorso (che esula dagli scopi di questo articolo), possiamo dire che
con l'ampersand si fa riferimento all'indirizzo della locazione di memoria che contiene il valore assegnato alla
variabile contrassegnata da quel particolare nome.

In soldoni questo significa che la funzione restituirà un riferimento diretto ai dati risultanti, e non ad una copia di essi (cosa che avverrebbe in assenza della e commerciale).

Passaggio parametri per valore e per riferimento

I parametri della funzione, e quindi le variabili che essa eventualmente utilizzerà, possono essere passati in due
modi diversi: per valore o per riferimento.

Di norma vengono passati nel primo modo, quindi la funzione riceve solo il valore della variabile (una sua copia nella sostanza), e la variabile originaria non verrà modificata.

Nel caso di passaggio di variabili per riferimento, che si effettua anteponendo alle stesse il segno &, vale invece
il discorso fatto in precedenza; la funzione quindi modificherà direttamente la variabile e non una sua copia.

Per rendersi conto della differenza, facciamo due esempi utilizzando la stessa funzione:

<?php

### definiamo una semplice funzione per entrambi gli esempi ###

function aggiungi_nome($stringa, $nome) {
$stringa .= " $nome !";
return $stringa;
}

// esempio passaggio argomenti per valore
echo "<br>Esempio passaggio argomenti per valore
";
$stringa = "Ciao";
$nome = "Giancarlo";
echo "il valore di $nome è Giancarlo<br>n";
echo "il valore di $stringa prima della chiamata della funzione è "$stringa"<br>n";
echo "L'output della funzione è: " . aggiungi_nome($stringa, 'Giancarlo');

echo "n<br>n";

// vediamo il valore di $stringa dopo la chiamata della funzione
echo "il valore di $stringa dopo la chiamata della funzione è "$stringa"<br>nnn";

// esempio passaggio argomenti per riferimento
echo "<br>Esempio passaggio argomenti per riferimento
n";
$stringa = "Ciao";
$nome = "Giancarlo";
echo "il valore di $nome è Giancarlo<br>n";
echo "il valore di $stringa prima della chiamata della funzione è "$stringa"<br>n";
echo "L'output della funzione è: " . aggiungi_nome(&$stringa, 'Giancarlo');

echo "n<br>n";

// vediamo il valore di $stringa dopo la chiamata della funzione
echo "il valore di $stringa dopo la chiamata della funzione è "$stringa"<br>n";

?>

Come si vede dagli esempi, passando la variabile $stringa per riferimento (anteponendole la &), il suo valore cambia
dopo la chiamata della funzione. C'è quindi una differenza dal primo esempio in cui la stessa variabile viene passata
per valore e conserva quindi il suo contenuto originario anche dopo l'esecuzione della funzione personalizzata.

Parametri obbligatori e facoltativi - valore di default

Come accennato sopra, è possibile passare ad ogni funzione un numero arbitrario di parametri, ma è anche possibile non passargliene alcuno. Infatti gli argomenti sono una componente facoltativa della funzione, nel senso che è perfettamente lecito (e accade di frequente) di definire ed utilizzare funzioni prive di parametri, che si presentano quindi con questo aspetto:

function nome_funzione() {

// contenuto della funzione

}

In casi del genere la funzione va chiamata quindi senza passare alcun parametro alla stessa, altrimenti il parser
restituirebbe un errore, così come un errore verrebbe generato se si cercasse si passare un numero di argomenti
diverso da quello previsto al momento della creazione della stessa funzione, a meno che non si prevedano dei
parametri di default.

È infatti possibile, al momento della definizione di una funzione, prevedere dei parametri facoltativi, indicando
un valore di default per gli stessi, valore che la funzione utilizzerà se al momento della chiamata, gli argomenti
vengono omessi. Un esempio chiarirà meglio la cosa:

<?php

function param_default($stringa, $stringa_1 = " come stai ?") {
return $stringa . $stringa_1;
}

$stringa = "Ciao Giancarlo";

// in questo caso passiamo solo $stringa, $stringa_1 assumerà il valore di default
echo param_default($stringa);

echo "n<br>n";

// in questo caso passiamo anche $stringa_1
echo param_default($stringa, ", hai una grande fantasia !");

?>

Nel primo caso viene omesso il secondo parametro della funzione, pertanto $stringa_1 assumerà il valore di default indicato nella definizione. Nel secondo caso, invece, viene esplicitamente indicato un valore anche per $stringa_1, che verrà quindi utilizzato dalla funzione e stampato a video.

Ambito delle variabili nelle funzioni

Abbiamo visto fino ad ora, come sia possibile utilizzare, all'interno di una funzione, delle variabili definite al suo esterno semplicemente passandole alla stessa come argomenti. Questo introduce ad un discorso molto importante, noto come ambito (scope) di operatività o campo d'azione delle variabili.

Di default, una variabile dichiarata all'esterno di una funzione non può essere utilizzate all'interno della stessa (a meno che non la si passi come argomento, ovviamente). Viceversa, una variabile definita in una funzione non è accessibile al suo esterno perchè esistono due distinti campi di azione della variabile.
Illustriamo tutto con un esempio:

<?php

$var = 10;

function test_scope() {
$var += 5;
return $var;
}

echo "$var<br>n";
echo test_scope();

?>

Eseguendo questo semplicissimo script si vede chiaramente come la variabile $var, definita all'esterno della funzione,
sia diversa da quella dichiarata al suo interno e questo appunto perchè le variabili, a seconda se si trovino fuori
o dentro una funzione, hanno differenti ambiti di operatività.

Ma allora come fare per rendere accessibile all'interno di una funzione, una variabile dichiarata al suo esterno ?
È necessario assegnarle un campo d'azione globale, tramite la parola chiave global, all'interno della funzione.
Riprendendo l'esempio precedente:

<?php

$var = 10;

function test_scope() {
global $var;
$var += 5;
return $var;
}

echo "$var<br>n";
echo test_scope();

?>

In questo caso la variabile $var, dichiata come global, è direttamente accessibile dalla funzione. Da notare a questo
proposito come, a partire dalla versione 4.1.0 di PHP (al momento in cui scrivo è stata da poco rilasciata la 4.3.0),
i cosiddetti array predefiniti, come ad esempio $_GET o $_POST, sono anche superglobali ossia direttamente
disponibili all'interno delle funzioni, senza la necessità di dichiararli esplicitamente come globali.

Variabili statiche

Per concludere il discorso relativo all'uso delle variabili nelle funzioni, è necessario accennare alle variabili statiche. Di norma una variabile dichiarata all'interno di una funzione, viene distrutta quando la funzione stessa esaurisce il suo compito, per cui la variabile viene reinizializzata alla successiva chiamata della stessa funzione. Se si vuole invece condividere l'inizializzazione di una variabile in successive invocazioni di funzioni (all'interno dello stesso script, ovviamente), è necessario dichiarare la stessa come statica, tramite la parola chiave static. Vediamo un esempio:

<?php

function test_static() {
static $var = 0;
return $var++;
}

function test_not_static() {
$var = 0;
return $var++;
}

// chiamiamo più volte la funzione test_static() con un ciclo for
for($i = 0; $i < 5; $i++) {
echo test_static() . " ";
}

echo "n<br><br>n";

// chiamiamo più volte la funzione test_not_static() con un ciclo for
for($i = 0; $i < 5; $i++) {
echo test_not_static() . " ";
}

?>

In questo esempio, nella prima funzione, la variabile viene dichiarata come static e di conseguenza nel primo ciclo
"for" la sua successiva invocazione (per cinque volte) produce come output 1 2 3 4 5.
Nella seconda funzione, invece, la variabile viene dichiarata ed inizializzata semplicemente,
per cui le 5 chiamate alla funzione test_not_static() restituiranno come output 0 0 0 0 0.

Valore (eventualmente) restituito da una funzione

È il momento ora di approfondire un importante aspetto delle funzioni, appena accennato all'inizio di questo articolo.

Nello schema di funzione presentato il quarto punto era l'eventuale valore restituito tramite l'istruzione
return ("eventuale" perchè una funzione può anche non restituire niente, ad esempio stampando direttamente a video un risultato).

Restituire un risultato significa, per così dire, "mettere a disposizione" dell'istruzione chiamante
un dato valore (il valore della funzione, appunto) e ritornare ad essa.
Anche qui aiutiamoci con degli esempi:

<?php

function print_or_return($stringa, $return) {
if($return == 1) {
return $stringa;
} else {
echo $stringa
}
}

?>

La funzione presentata nell'esempio restituisce o stampa direttamente a video la stringa passata a seconda del
valore attribuito al parametro return. La differenza è evidente perchè nel caso in cui si opti per la restituzione del valore, per stampare lo stesso, si dovrebbe usare echo (o print) in questo modo:

echo print_or_return($stringa, 1)

Se invece si optasse per far stampare direttamente la stringa alla funzione non sarebbe necessaria alcuna
istruzione, essendo sufficiente scrivere:

print_or_return($stringa, 0)

Importante notare come return può restituire solo un valore, per cui se si vuole ritornare più valori, è necessario usare un array, ma è possibile inserire più istruzioni return, ovviamente all'interno di costrutti di controllo del flusso, come if/else o switch.

Altresì da rimarcare il fatto che di norma viene sempre restituito una copia del valore, a meno che non si anteponga la e commerciale (&) al nome della funzione, come detto in precedenza.

Funzioni variabili e funzioni per le funzioni

Php comprende una serie di funzioni per le funzioni, fra cui vanno evidenziate function_get_arg() e function_num_args() per ottenere gli argomenti (o il numero di argomenti) di una funzione;
le funzioni function_exists() che restituisce true se una funzione esiste; get-defined-functions() che restituisce un array con tutte le funzioni, sia quelle interne a PHP, sia quelle definite dall'utente.

Per un panorama completo delle funzioni di funzioni, potete seguire questo link.

In conclusione di questo articolo mi preme accennare ad un aspetto delle funzioni personalizzate in PHP di cui forse non tutti sono a conoscenza. Alludo alle cosiddette funzioni variabili, ossia quelle funzioni che possono essere richiamate tramite il nome di una variabile precedentemente inizializzata. Vediamone un esempio:

<?php

// dichiariamo una semplice funzione
function print_something($stringa) {
echo $stringa;
}

// assegniamo alla variabile $var il nome della funzione
$var = 'print_something';

// richiamiamo la funzione con il nome della variabile $var
$var('Che belle le funzioni variabili !');

?>

I commenti all'interno dello script, dovrebbero essere sufficienti ad illustrare questa particolarità delle funzioni variabili, va solo aggiunto che questo sistema funziona solo con le funzioni e non con i costrutti del linguaggio, come echo ad esempio.

Ti consigliamo anche