Salta el contingut

UT02 El llenguatge PHP

portada

RAs

Resultat d'aprenentatge:

RA2. Escriu sentències executables per un servidor Web reconeixent i aplicant procediments d'integració del codi en llenguatges de marques. RA3. Escriu blocs de sentències embeguts en llenguatges de marques, seleccionant i utilitzant les estructures de programació.


PHP

PHP

  • Acrònim de Personal Home Page
  • Llenguatge de propòsit general, tot i que el seu fort és el desenvolupament web.
  • Sintaxis similar a C / Java
  • El codi s'executa en el servidor (en Apache mitjançant mod_php)
  • El client rep el resultat generat després d'interpretar el codi en el servidor.
  • El codi s'emmagatzema en arxiu amb extensió .php.

La seva documentació és extensa i està traduïda: https://www.php.net/manual/es/.

Codi incrustat

Els blocs de codi s'escriuen entre <?php i ?>, mentre que les sentències se separen mitjançant ;.

<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<title>PHP fàcil</title>
</head>
<body>
<!-- Mostra una frase amb HTML -->
Hola món<br>
<!-- Mostra una frase amb PHP -->``` { .php title=""}
<?php echo "És molt fàcil programar amb PHP."; ?>
</body>
</html>

Només etiquetes d'obertura

Si el nostre codi només ha de contenir codi PHP i res d'html, com per exemple, quan codifiquem classes o interfícies, només posarem l'etiqueta d'obertura, per així indicar que és un arxiu de php pur.

Generant contingut

Tenim tres possibilitats a l'hora de generar contingut en els nostres documents PHP:

  • echo expresio;
  • print (expresio);
  • <?= expresio ?>

Les que utilitzarem són echo quan ho facem dins d'un bloc d'instruccions i <?= quan només hàgim de mostrar el valor d'una variable dins d'un fragment HTML.

<!DOCTYPE html>
<html lang="ca">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Echo i print</title>
</head>
<body>
<p><?php echo "Aquest text es mostrarà a la pàgina web." ?></p>
<p><?= "Aquest text es mostrarà a la pàgina web." ?></p>
<p><?php print("Aquest text es mostrarà a la pàgina web.") ?></p>
</body>
</html>

Comentaris

Podem utilitzar comentaris d'una línia o de bloc:

<?php
// Aquest és un comentari d'una sola línia
/*
  Aquest és
  un comentari
  que ocupa
  diverses línies
*/ 
?>

Errors

Si hi ha un error d'execució, es produeix un Fatal Error.

Fatal error: Uncaught Error: Call to undefined function plint() in ...echo.php:11
 Stack trace:
 #0 {main}
    thrown in ...echo.php on line 11

Des de PHP 5 es llancen com una excepció. Més endavant veurem l'ús de try / catch.

Variables

  • No cal declarar-les prèviament.
  • Comencen per $, per exemple $nom. Després del $, el següent caràcter ha de ser una lletra en minúscula (recomanació) o guió baix _. Després ja es poden posar números.
  • Són case sensitive: $var != $vAR
  • No se declara el seu tipus, el tipat és dinàmic. S'assigna en temps d'execució depenent del valor assignat.
  • Convenient inicialitzar-les, sinó donen error.
<?php
$nom = "Tofol";
$nomComplet = "Tofol Verdera";
$numero = 123;
$numero2 = 456;
$pi = 3.14;
$sort = true;
$senseValor;

echo $senseValor;
?>

Tipus

Tot i que a priori no hi ha tipus de dades, internament PHP treballa amb quatre tipus escalars: boolean, integer, float i string i quatre tipus compostos: array, object, callable i iterable. Existeix un tipus especial per a null (més informació en http://php.net/manual/es/language.types.null.php).

Constants

Són variables el valor de les quals no varien. Hi ha dues possibilitats:

  • define(NOM, valor);
  • const NOM; // PHP > 5.3
<?php
define("PI", 3.1416);
const IVA = 0.21;

echo PI, " ", IVA; // No es posa el símbol dolar
?>

Operadors

Arimètics

Exemple Nom Resultat
-$a Negació Oposat de $a.
$a + $b Suma Suma de $a i $b.
$a - $b Resta Diferència de $a i $b.
$a * $b Multiplicació Producte de $a i $b.
$a / $b Divisió Quocient de $a i $b.
$a % $b Mòdul / Resta Resta de $adividit per$b.
$a ** $b Potència Resultat de$a elevat a $b. PHP >= 5.6.

En el cas de strings, si volem concatenar-les, s'utilitza l'operador .:

<?php
$x = 33;
$y = 11;
$z = $x + $y;
echo "La suma de 33 i 11 és ".44."<br />";
echo "La suma de ".$x." i ".$y." és ".(33 + 11)."<br />";
echo "La suma de ".$x." i ".$y." és ".$z."<br />";
?>

Realment, en comptes de concatenar cadenes amb variables, les podem imprimir directament ja que s'expandeixen automàticament:

<?php
echo "La suma de $x i $y és $z <br />";
?>

Realment, en comptes de concatenar cadenes amb variables, les podem imprimir directament ja que s'expandeixen automàticament:

<?php
$color = "vermell";
echo "El plural de $color és ${color}s";
?>

Més endavant estudiarem algunes funcions per al tractament de cadenes.

Comparació

Exemple Nom Resultat
$a == $b Igual veritat i $a és igual a $b després de la conversió de tipus.
$a === $b Idèntic, Comparació estricta veritat i $a és igual a $b, i són del mateix tipus de dada.
$a != $b, $a <> $b Diferent veritat i $a no és igual a $b després de la conversió de tipus.
$a !== $b No idèntic veritat i $a no és igual a $b, o si no són del mateix tipus.
$a < $b Menor que veritat i $a és estrictament menor que $b.
$a > $b Major que veritat i $a és estrictament més gran que $b.
$a <= $b Menor o igual a veritat i $a és menor o igual que $b.
$a >= $b Major o igual que veritat i $a és més gran o igual que $b.
$a <=> $b Nau espacial Retorna -1, 0el1 quan $a és respectivament menor, igual, o més gran que $b. PHP >= 7.
$a ?? $b ?? $c Fusió de nul·la El primer operand d'esquerra a dreta que existeixi i no sigui nul·la. nul·la si no hi ha valors definits i no són nul·la. PHP >= 7.

Lògics

Exemple Nom Resultat
$a i $b, $a && $b I (i) veritatsi tant$acom$b fill veritat.
$a o $b, `$a $b`
$a xor $b Gratuït(l'exclusiu) veritat i $ael$b ca veritat, però no tots dos.
!$a No (no) veritat i $a no és veritat.

Assignació

Exemple Nom Resultat
$a = $b Assignació Asigna a$a el valor de $b
$a += $b Assignació de la suma La suma a $a el valor de $b. Equivalent a $a = $a + $b
$a -= $b Assignació de la resta Li queda a ella$a el valor de $b. Equivalent a $a = $a - $b
$a *= $b Assignació del producte Asigna a$a el producte de $a per $b. Equivalent a $a = $a * $b
$a /= $b Assignació de la divisió Asigna a$a el conscient de $aentre$b. Equivalent a $a = $a / $b
$a %= $b Assignació de la resta Asigna a$a la resta de dividir $aentre$b. Equivalent a $a = $a % $b
$a .= $b Concatenació Concatena a $a la cadena $b. Equivalent a $a = $a. $b
$a++ Increment Incrementa $a en una unitat. Equivalent a $a = $a + 1
$a-- Disminuir Disminueix$a en una unitat. Equivalent a $a = $a - 1

Prioritat dels operadors

Recorda la prioritat. Primer els parèntesis, després la negació (!), productes/divisions, sumes/restes, comparacions, lògics i finalment es realitza l'assignació. Més informació a https://www.php.net/manual/es/language.operators.precedence.php

Autoavaluació

Si $a=5 i $b=4, esbrina el valor de $c i $c = $a*2 > $b+5 && !($b<>4)

Treballant amb formularis

Les dades s'envien via URL amb el format var1=valor1&var2=valor2.... Per exemple: exemple.php?nom=Tofol+cognom1=Verdera Es divideix en dos passos:

Generar un formulari amb action=arxiu.php method=GET

A larxiu .php llegir les dades amb $_GET[nomVar`]

Separem sempre que puguem el codi HTML del de PHP.

Per exemple, el formulari el col·loquem a saluda.html:

<form action="saluda.php" method="get">
    <p><label for="nom">Nom: </label>
    <input type="text" name="nom" id="nom"></p>
    <p><label for="cognom1">Primer cognom:</label> 
    <input type="text" name="cognom1" id="cognom1"></p>
    <p><input type="submit" value="enviar"></p>
</form>

I recollim les dades en saluda.php:

<?php
$nom = $_GET["nom"];
$cognom1 = $_GET["cognom1"];

echo "Hola $nom $cognom1";
?>

Si ho volguéssim realitzar tot en un únic arxiu (la qual cosa no és recomanable), podem fer-ho així:

<form action="" method="get">
    <p><label for="nom">Nom: </label>
    <input type="text" name="nom" id="nom"></p>
    <p><label for="cognom1">Primer cognom:</label>
    <input type="text" name="cognom1" id="cognom1"></p>
    <input type="submit" value="enviar">
</form>
<p>
    <?php
    if(isset($_GET['nom'])) {
        $nom = $_GET["nom"];
        $cognom1 = $_GET["cognom1"];

        echo "Hola $nom $cognom1";
    }
    ?>
</p>

El treball amb formularis l'estudiarem en profunditat en la unitat 4, i veurem que a més de GET, podem enviar les dades amb POST.

Condicions

La condició simple es realitza mitjançant la instrucció if. Entre parèntesis es posa la condició que s’avalua a true o false. Si no es posen claus, en comptes d’obrir un bloc, s’executarà només la següent instrucció.

Sempre claus

És recomanable posar claus sempre encara que en el moment de codificar només hi hagi una única instrucció. D'aquesta manera, es queda preparat per afegir més contingut en el futur sense provocar bugs.

<?php
$hora = 8; // L’hora en format de 24 hores
if ($hora === 8) {
    echo "Sona el despertador.";  
}

echo "<br>";
if ($hora === 8)
    echo "Sona el despertador.";  
?>  

Les condicions compostes mitjançant if-else:

<?php
$hora = 17; L’hora en format de 24 hores
if ($hora <= 12) {
    echo "Són les " . $hora . " del matí";  
} else {
    echo "Són les " . ($hora - 12) . " de la tarda";  
}
?>  

Les condicions anidades mitjançant if-else if-else:

<?php
$hora = 14; L’hora en format de 24 hores
if ($hora === 8) {
    echo "És l'hora d'esmorzar.";  
} else if ($hora === 14) {
    echo "És l'hora del dinar.";  
} else if ($hora === 21) {
    echo "És l'hora del sopar.";  
} else {
    echo "Ara no toca menjar.";  
}
?>  

La sentència switch també permet treballar amb condicions múltiples:

<?php

$hora = 14; L’hora en format de 24 hores

switch ($hora) {
    case 9:  
        echo "És l'hora d'esmorzar.";  
        break;  
    case 14: 
        echo "És l'hora del dinar.";  
        break;  
    case 21:  
        echo "És l'hora del sopar.";  
        break;  
    default:  
        echo "Ara no toca menjar";
}
?>  

No oblidis el break

Un error molt comú és oblidar la instrucció break després de cada cas. Si no el posem, executarà el següent cas automàticament.

Finalment, també tenim l'operador ternari ? valorTrue : valorFalse:

<?php

$hora = 14;

$formato = ($hora > 12) ? 24 : 12;
echo "El format és de $formato hores"
?>  

Si volem comprovar si una variable té valor i si no donar-li un valor determinat, farem servir l'operador ?: (es coneix com l 'operador Elvis - https://en.wikipedia.org/wiki/Elvis_operator) amb la sintàxia ?: valorSiBuit:

<?php

$nom = $_GET['nom'] ?: "desconegut"

?>  

Bucles

Mitjançant la instrucció while:

<?php

$i = 1;
while ($i <= 10) {
    echo "Línia " . $i;  
    echo "<br>";  
    $i ++; 
}

?>  

Mitjançant la instrucció do-while:

<?php
do {
    $dau= rand( 1, 6);  
    rand() retorna un valor aleatori  
    echo "Tirant el dau... ";  
    "ha sortit un " . $dau. ".";  
    echo "<br>";  
} while ($dau!= 5);

echo "Bé! Trec una fitxa de casa.";
?>  

Mitjançant la instrucció for:

<?php

// Bucle ascendent

for ($i = 1; $i <= 10; $i++) 
    echo "Línia " . $i;  
    echo "<br>";  
}

// Bucle descendent

for ($i = 10; $i >= 0; $i--) {
    echo "Línia " . $i;  
    echo "<br>";  
}
?>  

Més endavant estudiarem el bucle foreach per recórrer arrays.

PHP, de la mateixa manera que Java i C, permet trencar els bucles mitjançant la instrucció break. Al seu torn, continue permet saltar a la següent iteració.

Si pots, evita break i continue

Personalment, no m'agrada el seu ús. Prefereixo l'ús de variables flag per controlar la sortida dels bucles. Per exemple:

<?php

$sortir= false;

for ($i = 1; $i <= 10 && !$salir; $i++) {
    if ($i === 5) {
        echo "Salgo cuando i=5";
        $sortir= true;
    }
}

?>  

Arrays

Per emmagatzemar dades compostes, podem utilitzar tant arrays senzills com arrays associatius (similars a un mapa). En realitat tots els arrays són mapes ordenats compostos de parells clau-valor.

Alerta amb barrejar tipus

Com que el tipat és dinàmic, els nostres arrays poden tenir dades de diferents tipus. No es recomana barrejar els tipus.

De la mateixa manera que Java, es defineixen mitjançant corxets, són 0-index, i es pot assignar un valor a una posició determinada:

<?php

$fruites = array("taronja", "pera", "poma");
$fruites2 = ["taronja", "pera", "poma"];
$fruites3 = [];
$fruites3[0] = "taronja";
$fruites3[1] = "pera";
$fruites3[] = "poma"; // ho afegeix al final  

Podem obtenir la mida del vector mitjançant la funció count(array). Per recórrer el vector farem ús d'un bucle for:

<?php
$tam = count( $fruites); // mida del vector
for ($i=0; $i<count($fruites); $i++) {
    echo "Elemento $i: $fruites[$i] <br />";  
}  

Una altra manera de recórrer els arrays, fins i tot més elegant, és fer ús de foreach. La seva sintaxi és foreach (array as element):

<?php

// Mitjançant foreach no necessitem saber la mida del vector

foreach ($fruites as $fruita) {
    echo "$fruita <br/>";  
}  

Arrays associatius

Cada element és un parell clau-valor. En comptes d'accedir per la posició, ho fem mitjançant una clau. Així doncs, per a cada clau s’emmagatzema un valor.

A l'hora de recórrer aquest tipus de vectors, mitjançant foreach separem cada element en una parella clau => valor:

<?php

$capitals = [
    "Itàlia" => "Roma",
    "França" => "Paris",  
    "Portugal" => "Lisboa"
    ];  

$capitalFrancia = $capitals["França"];  // s’accedeix a l’element per la clau, no la posició
$capitals["Alemanya"] = "Berlín";       //hi afegim un element
echo "La capital de França és $capitalFrancia <br />";
echo "La capital de França és {$capitals["França"]} <br />";
$capitals[] = "Madrid"; // s’afegeix amb la clau 0 !!! No assignar valors sense clau!!!
foreach ($capitals as $valor) { // si recorrem un vector associatiu, mostrarem els valors
    echo "$valor <br />";  
}
foreach ($capitals as $pais => $ciutat) { // separem cada element en clau => valor
    echo "$pais : $ciutat <br />";  
}  

Operacions

Les operacions més importants que podem realitzar amb arrays són:

  • print_r($array): mostra el contingut de tot el vector. Si volem mostrar el contingut amb un format determinat, hem de recórrer el vector amb foreach.
  • var_dump($mixed): mostra el contingut de l’element rebut. Mostra més informació que print_r.
  • $elem = array_pop( $array): elimina l’últim element
  • array_push($array, $elem): afegeix un element al final
  • $booleano = in_array( $elem, $array): esbrina si $elem està en el vector $array
<?php

$fruites = ["taronja", "pera", "poma"];

array_push($fruites, "pinya");

print_r($fruites);

$ultFruita = array_pop($fruites);

if (in_array("pinya", $fruites)) {

    echo "<p>Queda pinya</p>";  

} else {

    echo "<p>No queda pinya</p>";  

}

print_r($fruites);
Array
(
[0] => taronja
[1] => pera
[2] => illa
[3] => pinya
)
<p>No queda pinya</p>

Array
(
[0] => taronja
[1] => pera
[2] => illa
)
  • $claus = array_keys($array): retorna les claus del $array associatiu
  • $tam = count($array): retorna la mida de $array
  • sort($array): ordena els elements del $array
  • isset($array[element]): indica si existeix/té valor element dins el vector
  • unset($array[element]): elimina l'element del vector (deixa un buit)
<?php

$capitals = array("Itàlia" => "Roma",
"França" => "Paris",
"Portugal" => "Lisboa");
$paises = array_keys($capitals);
print_r($paises);
sort($paises);
print_r($paises);
unset($capitals["França"]);
print_r($capitals);
Array
(
[0] => Itàlia
[1] => França
[2] => Portugal
)

Array
(
[0] => França
[1] => Itàlia
[2] => Portugal
)

Array
(
[Itàlia] => Roma
[Portugal] => Lisboa
)

En assignar un vector a un altre es realitza una còpia. Cura amb aquesta operació que pot consumir molts recursos.

<?php

$noms = ["Joan", "Ana", "Pedro", "Laura"];

$copia = $noms;

sort($noms);

print_r($noms);

print_r($copia);
Array
(
    [0] => Ana
    [1] => Joan
    [2] => Laura
    [3] => Pedro
)

Array

(
    [0] => Joan
    [1] => Ana
    [2] => Pedro
    [3] => Laura  

)

Hi ha moltíssimes més funcions per treballar amb arrays. Pots consultar la informació en la documentació oficial.

Articles per aprofundir en les operacions amb arrays

Un article molt complet (en anglès) de Com treballar amb arrays en PHP de la manera correcta.* Un altre article recomanable (en anglès) és Com ordenar arrays en PHP.

Arrays bidimensionals

Consisteix en un vector de vectors, ja siguin vectors seqüencials o associatius. Hi pot haver N dimensions.

prova2.php
<?php
$persona["nom"] = "Tofol Verdera";
$persona["telefons"] = ["966 123 456", "636 636 636"]; // array d’arrays ordinaris
$persona["professio"] = ["dia" => "filantrop", "nit" => "cavaller fosc"]; // array de arrays associatius
echo $persona['nom']." a la nit treballa de ".$persona['professio']['nit'];

Combinant els arrays associatius en diverses dimensions podem emmagatzemar la informació com si fos una taula:

<?php

$menu 1 = ["Plat1" => "Macarrons amb formaix", "Plato2" => "Pescat asado", "Beguda" => "Coca-Cola", "Postre" => "Gelat de vainilla"];

$menu 2 = ["Plat1" => "Sopa", "Plato2" => "Lomo con patatas", "Bebida" => "Agua", "Postre" => "Arròs amb llet"];

$menus = [$menu 1, $menu 2]; creem un vector a partir d'arrels associatius

foreach ($menus as $menudeldia) {

echo "Menú del dia<br/>";

foreach ($menudeldia as $platos => $comida) {

    echo "$platos: $comida <br/>";  

}

}

Per accedir a un element concret s'anen els corxets

$postre 0 = $menus[0]["Postre"];

Encara que pugui semblar una bona idea crear aquest tipus d'estructures, és millor utilitzar objectes conjuntament amb arrays (possiblement vectors d'altres objectes) per crear estructures complexes que permetin modelar millor els problemes.

Funcions

En no declarar-se els tipus de dades, els paràmetres de les funcions no tenen tipus ni s’indica el tipus de dada que retornen. El pas de paràmetres es realitza per valor, és a dir, es realitza una còpia de la variable.

UT02funcions01.php
<?php
function nomFuncio($par 1, $par 2, ...) {
 // codi
return $valor;

}

$resultado = nomFuncio($arg 1, $arg 2, ...);

?>

Per exemple:

UT02funcions02.php
<?php

function diaSetmana() {
    $setmana = [ "dilluns", "dimarts", "dimecres",
        "dijous", "divendres", "dissabte", "diumenge" ];
    $dia = $setmana[0]; // de 0 a 6
    return $dia;
}

$diaCine = diaSetmana();
echo "El pròxim $diaCine vaig al cinema.";

?>

Paràmetres per referència

Si volem passar un paràmetre per referència, en la declaració de la funció, indicarem els paràmetres mitjançant l'operador & per indicar la direcció de memòria de la variable.

UT02funcions03.php
<?php
function duplicarPerValor($argument)
{
    $argument = $argument * 2;
    echo "Dins de la funció: $argument.<br>";
}

function duplicarPerReferencia(&$argument)
{
    $argument = $argument * 2;
    echo "Dins de la funció: $argument.<br>";
}

$numero1 = 5;

echo "Abans de cridar: $numero1.<br>";
duplicarPerValor($numero1);
echo "Després de cridar: $numero1.<br>";
echo "<br>";
$numero2 = 7;
echo "Abans de cridar: $numero2.<br>";
duplicarPerReferencia($numero2);
echo "Després de cridar: $numero2.<br>";

?>

Paràmetres per defecte / opcionals

Permeten assignar valors en la declaració, i posteriorment, deixar l’argument en blanc.

UT02funcions04.php
<?php
function obtenirCapital($pais = "tots") {
    $capitals = array("Itàlia" => "Roma",
        "França" => "Paris",
        "Portugal" => "Liboa");
    if ($pais == "tots") {
        return array_values($capitals);
    } else {
        return $capitals[$pais];
    }
}

print_r(obtenirCapital());
echo "<br/>";
echo obtenirCapital("França");

En el cas de conviure amb un altre tipus de paràmetres, els paràmetres que tenen el valor assignat per defecte sempre es col·loquen al final.

<?php

function saluda($nom, $prefijo = "Sr") {

    echo "Hola ".$prefijo." ".$nom;  

}

saluda("Aitor", "Mr");

saluda("Aitor");

saluda("Marina", "Srta");

Paràmetres variables

Podem tenir funcions on en la declaració no indiquem la quantitat de dades d'entrada.

  • $arrayArgs = func_get_args(); → Obté un vector amb els paràmetres
  • $quantitat = func_num_args(); → Obté la quantitat de paràmetres rebuts
  • $valor = func_get_arg(numArgument); → Obté el paràmetre que ocupa la posició numArgument.

Aquestes funcions no es poden passar com a paràmetre a una altra funció (com a funcions variable, que veurem més endavant). Per a això, hem de guardar prèviament la funció en una variable.

<?php

function sumaParametros() {

    if (func_num_args() == 0) {  

        return false;  

    } else {  

        $suma = 0;  

        for ($i = 0; $i < func_num_args(); $i++) {  

            $suma + = func_get_arg( $i);  

        }  

        return $suma;  

    }  

}

echo sumaParametros(1, 5, 9); // 15

?>

Des de PHP 5.6, es pot utilitzar l'operador ... (variadics) el qual "disfressa" els paràmetres com un array:

<?php

function sumaParametrosMejor(...$numeros) {

    if (count($numeros) == 0) {  

        return false;  

    } else {  

        $suma = 0;  

        foreach ($numeros as $num) {  

            $suma + = $num;  

        }  

        return $suma;  

    }  

}

echo sumaParametrosMejor(1, 5, 9); // 15

?>

Més usos de ...

També es pot utilitzar per dividir un vector en variables separades per proporcionar arguments

<?php

function suma($a, $b) {

    return $a + $b;  

}

echo suma(... [1, 5])." <br />";

$a = [1, 5];

echo suma(...$a);

?>

Arguments amb nom

Des de PHP 8.0 podem passar els arguments amb el nom (a més de per posició, com hem fet fins ara). Els arguments amb nom es passen posant el nom com a prefix del paràmetres separat per dos punts: $resultado = funcion( arg1 : valor1, arg2 : valor2);

Aquesta característica complementa els parametres opcionals permetent-nos saltar el seu valor:

<?php

function funcioArgumentsNom($a, $b = 2, $c = 4) {

echo "$a $b $c";

}

funcioArgumentsNom( c: 3, a: 1); // "1 2 3"

Tant els paràmetres opcionals com els obligatoris poden tenir nom, però els arguments amb nom s’han de posar després dels que no en tenen.

<?php

funcioArgumentsNom( 1, c: 3); // "1 2 3"

Funcions tipades

Des de PHP7 en les funcions, tant els paràmetre com la seva devolució, permeten la definició de tipus. Això es coneix com a strict_types (tipificació estricta) i cal definir-lo en la primera línia de cada arxiu .php perquè el mateix interpreti PHP comprovi els tipus i llanci errors si els tipus són incorrectes, mitjançant la sentència

<?php

declare( strict_types = 1);

Així doncs, vam definir els tipus dels paràmetres i dels valors retornats mitjançant els tipus: int, float, string, bool, object i array.

Si una funció no retorna res s’indica mitjançant el tipus void.

<?php

declare( strict_types = 1);

function suma(int $a, int $b) : int {

    return $a + $b;  

}

$num = 33;

echo suma(10, 30);

echo suma(10, $num);

echo suma("10", 30); error per tipificació estricta, sinó en donaria 40

?>

Abast

Les variables definides fora de les funcions tenen abast global: accessibles des de qualsevol funció. Els paràmetres d'una funció i les variables declarades dins d'una funció (es coneixen com a variables locals) només són accessibles des de dins de la mateixa funció → abast de funció.

En cas de conflicte, tenen prioritat les variables locals. Per evitar el conflicte, dins de la funció, podem declarar la variable com a global.

<?php

function laMevaCiutat() {

    $ciutat = "Elche";  

    echo "Dins de la funció: $ciutat.<br>";  

}

$ciutat = "Alacant";

echo "Abans de la funció: $ciutat.<br>";

miCiutat();

echo "Després de la funció: $ciutat.<br>"

?>

``` { .php title=""} <?php

function laMevaCiutat() {

global $ciutat;

$ciutat = "Elche";

echo "Dins de la funció: $ciutat.<br>";

}

$ciutat = "Alacant";

echo "Abans de cridar: $ciutat.
";

miCiutat();

echo "Després de cridar: $ciutat.
"

?> ``

No globals

Per favor, cal evitar l'ús de variables globals dins de les funcions.

En el cas de necessitar-les, és millor passar-les com a paràmetre a les funcions.

Funcions variable

  • Permet assignar una funció a una variable.
  • Nom de la funció entre cometes.
  • Si una variable va seguida de parèntesi, PHP buscarà una funció amb el seu valor.
<?php

$miFuncioSuma = "suma";

echo $miFuncioSuma(3,4); invoca la funció suma

?>

Funcions anònimes

PHP permet la definició i ús de funcions anònimes, és a dir, funcions que no tenen nom, i s'utilitzen principalment per gestionar els callbacks. Aquest tipus de funcions s'utilitza molt en Javascript per gestionar els esdeveniments i promeses.

<?php

$anonima = function() {

    echo "Hola";  

};

$anonima();

$anonimaAmbParametre = function($nom) {

    echo "Hola ".$nom;  

};

$anonimaAmbParametre("Aitor");

Ús de variables externes a la funció anònima → use

$missatge = "Hola";

$miClosure = function() use ($missatge) {

    echo $missatge;  

};

$miClosure();

Ús de paràmetres

$holaPHP = function($arg) use ($missatge) {

    echo $missatge." ".$arg;  

};

$holaPHP("PHP");

?>

Des de PHP 7.4 s'han introduït les funcions fletxa (arrow functions) per simplificar la seva definició i ús.

Teniu més informació sobre funcions anònimes i fletxa en el següent article (en anglès): Funcions anònimes i fletxa a PHP

Biblioteca de funcions

Podem agrupar un conjunt de funcions en un arxiu, per permetre la seva reutilització. Posteriorment, s’inclou amb:

  • include(arxiu); / include_once(arxiu);
  • require(arxiu); / require_once(arxiu);

Si no troba l'arxiu, require un error fatal, include l'ignora Les funcions _once només es carreguen una vegada, si ja ha estat inclosa prèviament, no ho torna a fer, evitant bucles.

Per exemple, col·loquem les funcions a l'arxiu biblioteca.php:

<?php

function suma(int $a, int $b) : int {

    return $a + $b;  

}

function resta(int $a, int $b) : int {

    return $a - $b;  

}

?>

I posteriorment en un altre arxiu:

<?php

include_once("biblioteca.php");

echo suma(10,20);

echo resta(40,20);

?>

Plantilles mitjançant include

Mitjançant l'ús de la instrucció include també podem separar fragments de codi PHP/HTML que vulguem reutilitzar als nostres llocs web i crear un sistema molt senzill de plantilles. Per exemple, anam separar una pàgina en tres parts, primer la part superior en capsalera.php:

<! DOCTYPE html>

<html lang="és">

<head>

<meta charset="UTF-8">

<meta name="viewport" content="width=device-width, initial-scale=1.0">

<title><?= $titol ?></title>

</head>

<body>

La part de baix, per exemple, només ha de contenir HTML i la col·loquem en peu.html:

<footer>Tofol</footer>

</body>

</html>

I després ens centrem únicament en el contingut que canvia en pagina.php:

<?php

$titol = "Pàgina amb includes";

include("capsalera.php");

?>

<h1><?= $titol ?></h1>
<?php

include("peu.html");

?>

Funcions predefinides

El llenguatge ofereix un ventall de funcions ja definides, agrupades per la seva funcionalitat: https://www.php.net/manual/es/funcref.php

Cadenes

Ja hem vist que es poden crear amb cometes simples ('', sense interpretació) o cometes dobles ("", interpreten el contingut i les seqüències d'escapament \n, \t, \$, {, … - magic quotes)

UT02funcionspredefinides01.php
<?php
$nom="Tofol";
$moneda="Euro";
echo "El meu nom $nom";
echo "<br/>";
echo "Son 30 {$moneda}s";
?>```

S'accedeixen als caràcters com si fos un vector.

``` { .php title="UT02funcionspredefinides02.php"}
<?php
$cadena = "Jo sóc Batman";
$igrega = $cadena[0];
echo $igrega;
$igrega = $cadena[1];
echo $igrega;
?>

A més de echo, podem mostrar les cadenes mitjançant la funció printf. Aquesta funció ve heretada del llenguatge C, ya la cadena s'indica el tipus de dada a formatejar i genera una sortida. Si vull guardar el resultat en una variable, podem utilitzar sprintf.

UT02funcionspredefinides03.php
<?php
$num = 33;
$nom = "Larry Bird";
printf("%s portava el número %d", $nom, $num); // %d -> número decimal, %s -> string
echo "<br/>";
$frase = sprintf("%s portava el número %d", $nom, $num);
echo $frase;
?>

Teniu molts més exemples en https://www.w3schools.com/php/func_string_printf.asp

Operacions bàsiques

Totes les funcions es poden consultar en https://www.php.net/manual/es/ref.strings.php

Les més importants són:

  • strlen: obté la longitud d'una cadena i retorna un nombre sencer
  • substr: retorna una subcadena de la cadena original
  • str_replace: reemplaça caràcters en una cadena
  • strtolower i strtoupper: Transformen una cadena de caràcters a la mateixa cadena en minúscules o majúscules respectivament.
UT02funcionspredefinides04.php
<?php
$cadena = "El caballero oscuro";
$tam = strlen($cadena);
echo "La longitud de '$cadena' es: $tam <br />";

echo "Això és un substring des del caracter 13 fins al final: ";
$oscuro = substr($cadena, 13); // desde 13 al final
echo "<br/>";
echo "Això és un substring des del caracter 3 fins al 4: ";
$caba = substr($cadena, 3, 4); // desde 3, 4 letras
echo "<br/>";
echo "Ara farem un replace de c per k: ";
$katman = str_replace("c", "k", $cadena);
echo "$oscuro $caba ara és $katman";
echo "<br/>";
echo "i ara en majúscula ".strtoupper($cadena);
?>

Si volem treballar amb caràcters ASCII de forma individual, són útils les funcions:

  • chr: obté el caràcter a partir d'un ASCII
  • ord: obté l'ASCII d'un caràcter
UT02funcionspredefinides05.php
<?php
function despres(string $lletra): string {
    $asciiLletra = ord($lletra);
    return chr($asciiLletra + 1);
}

echo despres("B");
?>

Si volem netejar cadenes, tenim les funcions:

  • trim: elimina els espais al principi i al final
  • ltrim / rtrim o chop: Elimina els espais inicials / finals d'una cadena.
  • str_pad: emplena les cadenes fins a una longitud especificada i amb el caràcter o caràcters especificats.
UT02funcionspredefinides06.php
<?php
$cadena = " Programant en PHP ";
$neta = trim($cadena); // "Programant en PHP"
echo $neta;
echo "<br/>";
$bruta = str_pad($neta, 23, "."); // "Programant en PHP....."
echo $bruta;
?>

Comparant i buscant

La comparació de cadenes pot ser amb conversió de tipus mitjançant == o estricta con ===. També funcionen els operadors < i > si totes dues són cadenes. En comparar cadenes amb valors numerics podem utilitzar:

  • strcmp: 0 iguals, <0 si a<b o >0 si a>b
  • strcasecmp: passa a minúscules i compara
  • strncmp / strncasecmp: compara els N primers caràcters
  • strnatcmp: comparacions naturals
UT02funcionspredefinides07.php
<?php
$frase1 = "Alfa";
$frase2 = "Alfa";
$frase3 = "Beta";
$frase4 = "Alfa5";
$frase5 = "Alfa10";

var_dump( $frase1 == $frase2 ); // true
var_dump( $frase1 === $frase2 ); // true
var_dump( strcmp($frase1, $frase2) ); // 0
var_dump( strncmp($frase1, $frase5, 3) ); // 0
var_dump( $frase2 < $frase3 ); // true
var_dump( strcmp($frase2, $frase3) ); // -1
var_dump( $frase4 < $frase5 ); // false
var_dump( strcmp($frase4, $frase5) ); // 4 → f4 > f5
var_dump( strnatcmp($frase4, $frase5) ); // -1 → f4 < f5
?>

Si el que volem és buscar dins d'una cadena, tenim:

  • strpos / strrpos: busca en una cadena i retorna la posició de la primera/última ocurrència.
  • strstr / strchr(alias): busca una cadena i retorna la subcadena a partir d'on l'ha trobat
  • stristr: ignora les majúscules
UT02funcionspredefinides08.php
<?php
$frase = "Qui busca troba, això diuen, de vegades";
$pos1 = strpos($frase, ","); // troba la primera coma
echo $pos1."<br/>";
$pos2 = strrpos($frase, ","); // troba l'última coma
echo $pos2."<br/>";
$despresDeComa = strstr($frase, ","); // ", això diuen, de vegades"
echo $despresDeComa."<br/>";
?>

Si volem esbrinar que conté les cadenes, tenim un conjunt de funcions de comprovacions de tipus, es coneixen com les funcions ctype que retornen un booleà:

  • ctype_alpha → Lletres
  • ctype_alnum → alfanumèrics
  • ctype_digit → dígits
  • ctype_punct → caràcters de puntuació, sense espais
  • ctype_space → són espais, tabulador, salt de línia
UT02funcionspredefinides09.php
<?php
$prova1 = "hola";
$prova2 = "hola33";
$prova3 = "33";
$prova4 = ",.()[]";
$prova5 = " ,.()[]";

if (ctype_alpha($prova1)) { // true
    echo "vertader<br>"; 
}
else {
    echo "false<br>";
}
if (ctype_alnum($prova2)) { // true
    echo "vertader<br>"; 
}
else {
    echo "false<br>";
}
if (ctype_digit($prova3)) { // true
    echo "vertader<br>"; 
}
else {
    echo "false<br>";
}
if (ctype_punct($prova4)) { // true
    echo "vertader<br>"; 
}
else {
    echo "false<br>";
}
if (ctype_space($prova5)) { // false
    echo "vertader<br>"; 
}
else {
    echo "false<br>";
}
if (ctype_space($prova5[0])) { // true
    echo "vertader<br>"; 
}
else {
    echo "false<br>";
}
?>

Treballant amb subcadenas

Si volem trencar les cadenes en trossos, tenim:

  • explode: converteix en vector la cadena mitjançant un separador.
  • implode / join: passa un vector a cadena amb un separador
  • str_split / chunk_split: passa una cadena a un array/cadena cada X caràcters
UT02funcionspredefinides10.php
<?php
$frase = "Qui cerca troba, aixo diuen, de vegades";
$parts = explode(",", $frase);
print_r($parts);
echo "<br/>";
// Array ( [0] => Qui cerca troba [1] => aixo diuen [2] => de vegades )
$ciutats = ["Inca", "Manacor", "Buger"];
$cadenaCiutats = implode(">", $ciutats);
// Inca>Manacor>Buger
echo $cadenaCiutats."<br/>";
$parts3cadena = chunk_split($frase, 3);
// Qui ce rca tr oba , a ixo di uen , d e v ega des
echo $parts3cadena."<br/>";
$parts3vector = str_split($frase, 3);
// Array ( [0] => Qui [1] => ce [2] => rca [3] => tr [4] => oba [5] => , a [6] => ixo [7] => di [8] => uen [9] => , d [10] => e v [11] => ega [12] => des )
print_r($parts3vector);
?>

Si volem treballar amb tokens:

  • strtok(cadena, separador)
  • i dins del bucle: strtok(separador)

Finalment, per separar-la en base al format:

  • sscanf: al revés que sprintf, crea un vector a partir de la cadena i el patró.

Finalment, altres operacions que podem realitzar per treballar amb subcadenas són:

  • substr_count: nombre de vegades que apareix la subcadena dins de la cadena
  • substr_replace: reemplaça part de la cadena a partir de la seva posició, i opcionalment, longitud
UT02funcionspredefinides11.php
<?php
$batman = "Tofol Verdera es Batman";
$subcadena = substr($batman, 6, 7); // Verdera
echo $subcadena."<br/>";
$bes = substr_count($batman, "a"); // 3
echo $bes."<br/>";
// Tofol Verdera es camarero
$cambrer1 = substr_replace($batman, "cambrer", 17);
echo $cambrer1."<br/>";
// Tofol Verdera es cambrer
$cambrer2 = substr_replace($batman, "cambrer", -6); // quita 6 desdel final
echo $cambrer2."<br/>";
// Tofol Verdera es cambrer
$bruno = substr_replace($batman, "Bruno", 0, 13);
// Bruno es Batman
echo $bruno."<br/>";
?>

També disposem d'una sèrie de funcions que faciliten les codificacions des de i cap a HTML:

  • htmlentities: converteix entitats HTML, per exemple, á per &aacute;, ñ per &ntilde;, < per &lt;, etc..
  • htmlspecialchars: idem però només amb els caràcters especials (&, ", ', <, >, ...)
  • striptags: elimina etiquetes HTML.
  • nl2br: canvia salts de línia per <br/>.
  • rawurlencode / rawurldecode: codifica/decodifica una URL (espais, ...).
UT02funcionspredefinides12.php
<?php
// Text original amb alguns caràcters especials HTML i salts de línia
$input = "<h1>Hello & welcome!</h1>\nAquest és un text amb <b>HTML</b> i & caràcters especials.";

// 1. htmlentities
// Converteix caràcters especials a entitats HTML (serveix per evitar interpretació HTML)
echo "htmlentities():<br>";
echo htmlentities($input);
echo "<hr>";

// 2. htmlspecialchars
// Converteix només alguns caràcters especials (<, >, &, ", ') a entitats HTML
echo "htmlspecialchars():<br>";
echo htmlspecialchars($input);
echo "<hr>";

// 3. strip_tags
// Elimina totes les etiquetes HTML del text (només queda el contingut)
echo "strip_tags():<br>";
echo strip_tags($input);
echo "<hr>";

// 4. nl2br
// Converteix salts de línia (\n) en <br> per mantenir la separació de línies en un HTML
echo "nl2br():<br>";
echo nl2br(strip_tags($input));  // sovint es fa servir combinat amb strip_tags
echo "<hr>";

// 5. rawurlencode i rawurldecode
// Codifica i decodifica una cadena per a ús segura en URL, codificant caràcters especials
$url_string = "Hola món! / Aquí: 100% #100";
$encoded = rawurlencode($url_string);
$decoded = rawurldecode($encoded);

echo "rawurlencode():<br>";
echo $encoded . "<br><br>";

echo "rawurldecode():<br>";
echo $decoded . "<br>";
?>

````

Aquestes funcions les utilitzarem en unitats posteriors, quan construim pàgines html.

### Matemàtiques

Disposem tant de constants com funcions ja definides per treballar amb operacions matemàtiques: <https://www.php.net/manual/es/ref.math.php>

* Constants ja definides
    * `M_PI`, `M_E`, `M_EULER`, `M_LN2`, `M_LOG2E`
    * `PHP_INT_MAX`, `PHP_FLOAT_MAX`
* Funcions de càlcul
    * `pow`, `sqrt`, `log`, `decbin`, `bindec`, `decoct`, `dechex`, `base_convert`, `max`, `min`
* Funcions trigonomètriques
    * `sin`, `cos`, `tan`, `deg2rad`, `rad2deg`
* Funcions per treballar amb números aleatoris
    * `rand`, `mt_rand` (més ràpida)

Tot i que la majoria d'elles són molt específiques de problemes matemàtics / estadístics, és molt comú que haguem d'arrodonir i/o formatejar els càlculs abans de mostrar-los a l'usuari.

Mitjançant la funció `number_format(numero, quantitatDecimals, separadorDecimals, separadorMiles)` poderem passar números a cadena amb decimals i/o separadors de decimals i/o de milers.

``` { .php title="UT02funcionspredefinides13"}
<?php
$nf = 1234.5678;
echo number_format($nf, 2); // 1,234.57
echo number_format($nf, 2, "M", "#"); // 1#234M57
?>

Per arrodonir, tenim abs per al valor absolut i round per arrodonir, ceil per a aproximació per excés i floor per defecte.

UT02funcionspredefinides14.php
<?php
$num = 7.7;
$set = floor($num);
echo $set."<br/>";
$vuit = ceil($num);
echo $vuit."<br/>";
$unAltre = 4.49;
$quatre = round($unAltre);
echo $quatre."<br/>";
$quatrecinc = round($unAltre, 1);
echo $quatrecinc."<br/>";
$cinc = round($quatrecinc);
echo $quatrecinc."<br/>";
?>

Tipus de dades

Finalment, per realitzar conversions de dades o si volem treballar amb tipus de dades, tenim les següents funcions:

  • floatval, intval, strval: retorna una variable del tipus de la funció indicada
  • settype: força la conversió
  • gettype: obté el tipus
  • is_int, is_float, is_string, is_array, is_object: retorna un booleà a partir del tipus rebut
<?php
$un = 1;
var_dump(is_int($un)); // true
$unfloat = floatval($un);
settype($un, "string");
var_dump(is_int($un)); // false
var_dump(is_string($un)); // true
settype($un, "float");
var_dump(is_int($un)); // false
var_dump(is_float($un)); // true
var_dump(is_int(intval($un))); // true
?>

Referències