Enrera
Mòdul 3
Creació i gestió d'entorns web dinàmics (PHP)
  Pràctica
1
2
3
4
   
Exercicis
Exercicis
 
 

 

  Funcions
   
  L'objectiu d'aquesta pràctica és veure la implementació que el PHP fa de les funcions. El PHP té una gran quantitat de funcions que ens permeten dur a terme tasques molt diverses. Hi ha, a més, la possibilitat que l'usuari es creï les funcions que necessiti.
   
   
  Funcions del llenguatge
   

El PHP té, com hem dit, una gran quantitat de funcions definides. Podem trobar funcions per a la comunicació amb les diferents bases de dades, matemàtiques, per treballar amb cadenes, amb dates, amb matrius, amb correu, amb ftp, etc.

A la pàgina del PHP, a l'adreça: http://www.php.net/manual/es/funcref.php, us podeu fer una idea de la gran quantitat de funcions, classificades temàticament. Igualment, a la casella search for podreu buscar qualsevol funció i hi trobareu la sintaxi, els paràmetres requerits i què retorna.

Les funcions definides per l'usuari en PHP actuen de manera semblant a d'altres llenguatges. Es tracta de fragments de codi als quals podem enviar paràmetres i que poden retornar algun valor o fer alguna tasca concreta. Utilitzar funcions és una bona idea pel que tenen de reutilització de codi i pels avantatges que comporta en el procés de depuració.

   
Atenció !
Recordeu que a mòdul 1, a la pràctica 6 i la pràctica 7, hem vist com instal·lar la referència de PHP en format d'ajuda de Windows en els dos editors explicats (Maguma i HAPedit). Podeu trobar-hi les funcions de PHP ordenades per temes i, a més, quan us col·loqueu sobre el nom de les funcions escrites en el codi, apareix dinàmicament una ajuda amb la seva sintaxi.
   
  Declaració i paràmetres
   
 

Cal declarar la funció abans de qualsevol crida que se'n vulgui fer. En l'exemple següent veurem com definir una funció, així com la utilització d'algunes de les funcions de cadena estàndards.

Ho posarem en pràctica definint la nostra funció TornaNom, que retornarà el nom i els cognoms que li passem amb tres possibilitats de conversió:

  • A minúscules (opció 'L')
  • A majúscules (opció 'U')
  • Inicials de cada nom o cognom en majúscula i la resta en minúscula (opció 'M')
Pràctica

Copieu el codi següent al vostre editor i deseu-lo amb el nom de m3p11.php. Comproveu-ne el funcionament i aneu seguint els comentaris posteriors i els del mateix codi.

   
Veure codi

Executar codi

<?php
/*---------------------------------------------------------------
* Mòdul: 3 Pràctica: 1 Fitxer: m3p11.php
* Autor: D116 Data:
* Descripció: Definició de funcions
* Pre condi.:
* Post cond.:
-----------------------------------------------------------------*/

// Definició de la funció
// Els paràmetres per defecte els definim aquí mateix, si cal.
// Aquí per defecte $lletres ="U"
function TornaNom($nom, $cognom1, $cognom2, $lletres="U" )
{
// ajuntem les tres variables en una sola cadena
$torna = $nom." ".$cognom1." ". $cognom2;

// en funció de l'opció fem una cosa o altra...
if (strtoupper($lletres) == "U"){
$torna = strtoupper($torna); // passem tot a majúscules
}elseif (strtoupper($lletres) == "L"){
$torna = strtolower($torna); // passem tot a minúscules
}else{
$torna = ucwords(strtolower($torna)); // Primera lletra en majúscula
}
return $torna; //retorna la nova cadena
}


// Inici del codi
$nom = "Joan";
$cognom1 = "SALELLES";
$cognom2 = "maeso";
$opcio = "u"; // Opcions (U)pper (L)ower (M)ixed


echo "<b>================= Funció TornaNom() =================</b> <br><br><br> \n";

//Comprovem que les variables estiguin definides amb funció isset()
if ( isset($nom) && isset($cognom1) && isset($cognom2)) {
echo "Inici: <b>".$nom." ".$cognom1." ".$cognom2." </b><br><br> \n" ;
echo "Opció utilitzada: <b>".$opcio." </b><br> \n" ;
echo "Transformació: <b>".TornaNom($nom, $cognom1, $cognom2, $opcio)." </b> \n";
echo "<br><br>";

$opcio = "l";
echo "Opció utilitzada: <b>".$opcio." </b><br> \n" ;
echo "Transformació: <b>".TornaNom($nom, $cognom1, $cognom2, $opcio)." </b> \n";
echo "<br><br>";

$opcio = "m";
echo "Opció utilitzada: <b>".$opcio." </b><br> \n" ;
echo "Transformació: <b>".TornaNom($nom, $cognom1, $cognom2, $opcio)." </b> \n";
}else{
echo "Alguna variable no està definida!";
}
?>

  Llistat 3.1.1. Declaració de funcions
   
 

La definició es fa, com en altres llenguatges, donant el nom de la funció després de function i posant entre els parèntesis els paràmetres demanats.

Al darrer paràmetre ($lletres) li donem un valor per defecte ("U"). Això vol dir que si no li passem cap valor, la funció tirarà endavant amb el valor definit. Podeu provar de no passar-li el quart valor i veureu que no hi ha error. Proveu, en canvi, de no passar-li tampoc el tercer.

Atenció !
Fixeu-vos que els paràmetres als quals assignem un valor per defecte han d'estar col·locats al final de tot.
   
  Utilitzem algunes de les funcions estàndards per a la conversió de cadenes: strtoupper() (conversió a majúscules), strtolower() (conversió a minúscules), ucwords() (primera lletra de cada paraula en majúscula).
   
Atenció !
Observeu que les funcions strtoupper() i strtolower() no funcionen amb caràcters accentuats. Caldria, si ens interessés, definir una funció que "ampliés" també la conversió a les lletres accentuades.
   
 

També hem utilitzat la funció isset(), que serveix per saber si una variable ha estat definida o no. En aquest cas, valorem mitjançant if si estan totes tres variables definides; en cas contrari, apareixerà un missatge d'advertència. Proveu de comentar la línia de declaració de la variable $nom, per exemple.

La funció definida torna la nova cadena mitjançant la clàusula return.

A la segona part del codi hi ha la "crida" a la funció amb
TornaNom($nom, $cognom1, $cognom2, $opcio), que retorna els valors dels paràmetres que li hem passat ja transformats.

   
   
  Pas de paràmetres per referència
   
 

El PHP permet passar els paràmetres de les funcions de tres maneres diferents:

  • Per valor: s'envia una còpia de la variable i, per tant, si fem canvis en el seu valor no afectaran la variable original.
  • Per defecte: es preveu la possibilitat que no es passi cap valor per a aquest paràmetre i es proporciona un valor per defecte.
  • Per referència: si volem que els canvis en el valor que es produeixen en el cos de la funció afectin la variable que li hem passat.

El primer i segon cas són els que hem vist a l'exemple del llistat 3.1.1.

Amb el pas per referència, aconseguirem que les modificacions en el valor d'una variable dins d'una funció continuïn vigents fora de la funció. Per indicar que passem el paràmetre per referència, cal que davant del seu nom posem ampersand (&) a la definició de la funció.

En el codi següent veurem a la pràctica com passem variables per referència. Hi definim una funció Comprova() que rep tres paràmetres:

  • $nota una nota numèrica.
  • &$aprovats i &$suspesos definides com a paràmetre per referència, és a dir, la variable que enviem en aquestes dues posicions es veurà modificada cada vegada que entrem a la funció i des de fora podrem accedir al seu valor. Aniran acumulant el total de notes suspeses o aprovades.

Per simular l'ús de la funció, definirem un for que anirà incrementant en 0,5 el valor de la nota simulada. A cada iteració de la funció es mostra la nota i els totals d'aprovats i suspesos.

   
Veure codi

Executar codi

<?php
/*---------------------------------------------------------------
* Mòdul: 3 Pràctica: 1 Fitxer: m3p12.php
* Autor: D116 Data:
* Descripció: Funcions: pas de paràmetres per referència
* Pre condi.:
* Post cond.:
-----------------------------------------------------------------*/

// Definim variables que recolliran el nombre de notes
// que superen o no
$superen = 0;
$nosuperen = 0;

// Funció comprova()
// Fa una comprovació sobre si la nota passada és aprovada o no
// i incrementa en una unitat les variables $superen o $nosuperen
// que han estat passades per referència
function Comprova($nota, &$aprovats, &$suspesos)
{
if ($nota < 5){
$suspesos++;
}else{
$aprovats++;
}
}


// Simulem mitjançant un for el pas de paràmetres
// a la funció comprova()
for ( $i = 0; $i <= 10; $i+=0.5){
Comprova($i, $superen, $nosuperen);
echo "Nota = $i Aprovats: $superen Suspesos: $nosuperen<br>" ;
}
?>

  Llistat 3.1.2. Pas de paràmetres per refència a les funcions
   
 

Copieu aquest codi a l'editor i deseu-lo amb el nom m3p12.php. Executeu-lo i observeu el resultat i com les variables $superen i $nosuperen van incrementant els seus valors. Comproveu com això no passa si traiem el signe & del davant de $aprovats o $suspesos en la definició de la funció.

   
   
  Àmbit de les variables
   
 

A la pràctica 2 del mòdul 2 hem parlat de les variables, però: què passa quan treballem amb variables dins de les funcions? Quin és el seu àmbit de validesa?

Podem distingir dos tipus de variables pel que fa al seu àmbit:

  • Globals
  • Locals

Si volem que una variable que definim en una funció sigui global, cal que ho indiquem posant global davant de la seva definició. Això farà que estigui diponible de manera global.

Les variables locals són les que definim dins d'una funció:

  • El seu àmbit és la funció mateixa, és a dir, si la cridem des de fora de la funció no ens respondrà.
  • Si no indiquem res, una variable definida dins d'una funció sempre serà local (i no pas estàtica o global).
  • Si definim una variable local amb el mateix nom que una variable global, dins la funció treballarem amb la seva versió local que tindrà, per tant, un contingut diferent.
  • Cada vegada que cridem la funció, la variable local es reinicialitza al seu valor inicial.

Una excepció a això últim són les variables locals estàtiques que definim posant static davant del nom de la variable. Aquest tipus de variable:

  • Són locals, perquè el seu àmbit d'actuació és la funció (no funcionaran si les cridem des de fora).
  • No perden el valor en diferents crides a la funció i mantenen el valor assignat en l'últim canvi.
   
  Un exemple
Pràctica

Veurem un exemple en què utilitzarem tots tres tipus de variables dins d'una funció Mitjana(), definida per nosaltres mateixos.

Aquesta funció recull un únic paràmetre que és un array (aElements) amb contingut de diferents valors numèrics. A partir d'aquests valors, calcularà la mitjana aritmètica i la tornarà.

Copieu el codi que segueix en el vostre editor i deseu-lo amb el nom de m3p13.php.

   
Veure codi

Executar codi

<?php
/*---------------------------------------------------------------
* Mòdul: 3 Pràctica: 1 Fitxer: m3p13.php
* Autor: D116 Data:
* Descripció: Àmbit dels diferents tipus de variables
* Pre condi.:
* Post cond.:
-----------------------------------------------------------------*/

$comptador = 0;

// Definim funció Mitjana() que calcularà la mitjana d'un array amb valors numèrics
function Mitjana($aElements)
{
// variable global
global $comptador; // la podrem veure des de fora de la funció
// variable estàtica
static $vegades = 0; //la podrem veure des de la funció mantenint valors
// variable local
$total = 0; // la podrem veure des de la funció sense acumular valors ant.

if (count($aElements) > 0) {
for( $i = 0 ; $i < count($aElements); $i++ )
{
echo $i." ------ ". $aElements[$i]. "<br>";
$total = $total + $aElements[$i];
}

$mitjana = $total / count($aElements);
}else{
echo "No hi ha valors <br>";
}

$comptador++; // incrementem variable global
$vegades++; // incrementem variable estàtica

// Retorna la mitjana dels valors passats i també el nombre
// de vegades que s'ha executat la funció
return round($mitjana,2)."<br> Funció executada: ".$vegades." vegades<br>";
}
// Fi de la definció de la funció Mitjana()


//Cridem la funció tres vegades consecutives amb diferents valors
$aElements = array(6,6,2,5,4,4,1,3,2);
echo "<br>Mitjana de valors: ".Mitjana($aElements);
echo "Comptador (variable global): ".$comptador."<br><br>";

$aElements = array(9,5,7,0,3,4,4,5,3,9);
echo "<br>Mitjana de valors: ".Mitjana($aElements);
echo "Comptador (variable global): ".$comptador."<br><br>";

$aElements = array(9,6,7,8,3,4,4,5,3,9,8,2);
echo "<br>Mitjana de valors: ".Mitjana($aElements);
echo "Comptador (variable global): ".$comptador."<br><br>";
?>

  Llistat 3.1.3. Àmbit de les variables
   
 

Si estudiem el codi veurem que, en primer lloc, definim la funció i després la cridem tres vegades consecutives. Això ens permetrà observar el comportamment dels diferents tipus de variable:

  • $comptador és una variable definida global que compta les vegades que hem executat la funció; ja està definida abans de la funció i a dins li indiquem que és d'aquest tipus. Hi podem accedir des de fora de la funció i el valor es va acumulant en les diferents crides.
  • $vegades és una variable estàtica que compta igualment les vegades que hem cridat Mitjana(); veiem que hi podem accedir des de dins de la funció però no des de fora; veiem també que no es redefineix cada vegada, sinó que guarda el valor de la darrera execució de la funció.
  • $total és una variable local; cada vegada que cridem la funció es reinicialitza.
   
Atenció !
Una manera alternativa i més aconsellable de treballar amb les variables globlals és mitjançant $_GLOBALS. Es tracta d'un array associatiu que té com a clau el nom de les diferents variables globals. En el nostre cas, seria $_GLOBALS["comptador"].
   
 
Amunt
Pràctica
1
2
3
4
   
Exercicis
Exercicis