Taula de continguts

PHP

PHP és el llenguatge de programació web entorn servidor més popular des de fa molts anys. La web de referència és http://php.net i on haurem de consultar de forma oficial sempre que tinguem dubtes.

Les sigles PHP ténen el què es coneix per definició recursiva. «PHP» significa, literalment, «PHP Hypertext Preprocessor».

Aquest article està pensat per a gent que coneix les bases de la programació i que s'està iniciant en l'àmbit web, pel què no ens detindrem en conceptes de variable, funció, array, diccionari/map, etc. sinó que suposem que es coneixen prèviament.

, , , , ,

Referències


Instal·lació de PHP i primeres passes

Treballarem PHP sobre GNU/Linux Debian/Ubuntu. Instal·lar PHP és tan fàcil i obvi com:

$ sudo apt install php

En aquest article no necessitem parar massa atenció a les versions ja que treballarem amb els bàsics del llenguatge, però si estem instal·lant programari tipus CMS i similars caldrà que revisem bé la versió instal·lada i les llibreries afegides.

PHP es pot executar de diferents maneres:


Variables

Les variables en PHP van sempre precedides del símbol $.

PHP és un llenguatge de tipatge dinàmic, el què significa que una variable pot canviar el seu tipus de dades en temps d'execució. És una característica habitual dels llenguatges interpretats (i no gens habitual en els llenguatges compilats).

Entrem en la consola en mode interactiu per fer les primeres proves amb php -a:

$ php -a
Interactive mode enabled

php > $a = 1;
php > echo $a;
1
php > var_dump($a);
int(1)
php > $a = "hola";
php > echo $a;
hola
php > var_dump($a);
string(4) "hola"
php > echo gettype($a);
string

Instruccions vistes:

Respon:


Strings

Els strings o cadenes de caràcters mereixen un parell de comentaris abans de continuar.

Per mostrar text (que és la operació més habitual en PHP ja que la seva principal missió és construir un HTML) utilitzem echo i posem el text entre cometes dobles o simples. Ambdues funcionen, però tenen efectes diferents:

Exemple:

php > $usuari = "Enric";
 
php > echo "Hola, $usuari";
Hola, Enric
 
php > echo 'Hola, $usuari';
Hola, $usuari

Com podem veure, un mostra el contingut de la variable (Enric) i l'altre no.

També funciona amb arrays (ho veurem més endavant).

Concatenació de strings

Podem concatenar strings i variables amb el caràcter punt (.)

Per exemple, el què hem fet abans ho podem fer també així:

php > echo "Hola, ".$usuari;
Hola, Enric

D'acord que es pot posar la variable dins de les cometes dobles i ens apareixerà, però sovint és més clar a l'hora de llegir el codi concatenar amb el punt i així també el syntax highlight de l'editor ens ressaltarà de forma més clara què estem fent.

Escape

A més, és molt comú necessitar fer escape de determinats caràcters com l'apòstrof. Si estem utilitzant cometes simples i necessitem escriure un apòstrof (és el mateix caràcter) podem escapar amb una contrabarra i es mostrarà l'apòstrof.

php > echo 'Vivim a l'Hospitalet';
php ' 
php ' ';
PHP Parse error:  syntax error, unexpected 'Hospitalet' (T_STRING), expecting ';' or ',' in php shell code on line 1
php > echo 'Vivim a l\'Hospitalet';
Vivim a l'Hospitalet

Com podem veure, l'apòstrof em tanca el string i llavors em dona un error (a part de liar la consola). Si necessito un apòstrof entre cometes simples, utilitzem la contrabarra (escape) abans.

Combinació de cometes

Com que sovint estem construint un HTML amb PHP, es dona que per aconseguir un doc del tipus HTML ens convé utilitzar una combinació de cometes simples i dobles. Per exemple, per aconseguir això:

<input type="text" name="nom" />

La forma més fàcil per fer-ho seria aquesta:

echo '<input type="text" name="nom" />';

Però si volem ficar pel mig alguna variable, les cometes simples no ens deixaran fer-ho dins del string. Per tant, serà més fàcil fer les cometes simples dins del HTML:

echo "<input type='text' name='nom' value='$nom_usuari' />";

Com alternativa, o si volem fer servir cometes simples, haurem de concatenar:

echo '<input type="text" name="nom" value="'.$nom_usuari.'" />';


Servidor intern PHP

Ara treballarem amb el servidor intern de PHP (mes tard ja veurem com treballar amb Apache).

Crearem una carpeta php1 en el nostre home directory on hi posarem els arxius PHP (en aquest exemple creem un arxiu index.php) i posem en marxa el servidor:

$ mkdir php1
$ cd php1
$ echo "<h1>PHP quick</h1>" > index.php
$ php -S 0:8080
[Thu Sep  9 16:45:10 2021] PHP 7.4.9 Development Server (http://0:8081) started
...

Ara podem apuntar el browser al port 8080 de la nostra màquina per veure si es mostra alguna cosa:

http://localhost:8080

Per visualitzar la web cal mantenir la shell oberta. Si la parem, el servidor intern es pararà i no deixarem de tenir disponible la web.


Primera pàgina PHP

Edita index.php i ara posa-hi aquest contingut:

<p>En un arxiu PHP es comença escrivint en HTML</p>

<?php
# dins el tag ?php podem escriure codi incrustat
# comentaris amb el sostingut #

echo "<p>Aquesta línia l'hem escrita en PHP</p>";
?>

<p style="color:orange;">Aquesta línia torna a ser HTML</p>

Accedeix amb el navegador a localhost:8080 i observa el resultat i el codi generat amb CTRL+U.

Utilitzar CTRL+U és una eina imprescindible per veure quin és el codi que hem generat finalment després de l'execució del PHP.


Mostrar els errors del codi

Si introduïm errors al nostre codi no es veuran al navegador. Això és habitual ja que si la nostra web té algun error no volem mostrar-ho a l'usuari «tal qual», sinó que hauriem de fer algun post-processament del tipus captura d'excepcions, etc.

A més, mostrar els errors del nostre codi pot oferir informació interna de la nostra web que la podrien fer vulnerable a usuaris malintencionats ja que revela com està feta la web.

Per veure els errors podem mirar la consola. Introdueix algun error a la part PHP (per exemple, afegeix una línia amb lletres aleatòries) i visualitza per veure com va.

Si igualment vols fer mostrar els errors al browser, pots introduir aquestes línies a l'inici del codi PHP:

# codi PHP per mostrar els errors al browser
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);


Estructures de control

Les estructures principals de control son els habituals bucles i condicionals. La web de referència és http://php.net :

Exercicis

Fes els següents exercicis en PHP.

Cal que a tots els exercicis hi hagi variables per als límits (N,M).


Estructures de dades

En els llenguatges interpretats moderns com Python o Javascript es solen utilitzar dues estructures bàsiques molt importants (amb diverses variacions):

Arrays i llistes

Els arrays ja sabem que son conjunts de dades estructurats de forma consecutiva. Això era veritat en llenguatges compilats com C/C++ o Java, però en PHP o Python ja no és així ben bé. La primera diferència és que els arrays de llenguatges compilats han de ser del mateix tipus de dades, i son estàtics. En canvi, els arrays en PHP o Python poden contenir elements heterogenis (strings, sencers i floats barrejats), i que son estructures dinàmiques (tipus llista) on podem afegir i eliminar elements.

Es pot definir i inicialitzar un array de diverses maneres, bàsicament aquestes:

$a = [];                  # array buit
$b = array();
$c = ["gos","gat"];       # array inicialitzat amb 2 elements
$d = array("gos","gat");

Prova d'inicialitzar arrays utilitzant la consola de PHP amb php -a i visualitzar els continguts amb var_dump.

Per afegir elements a un array es pot fer amb la funció array_push o amb els claudàtors [ ]:

$a = ["gos","gat"];
array_push($a,"elefant");
$a[] = "jirafa";
var_dump($a);
array(4) {
  [0]=>
  string(3) "gos"
  [1]=>
  string(3) "gat"
  [2]=>
  string(7) "elefant"
  [3]=>
  string(6) "jirafa"
}

Com es pot veure, els índexs de l'array s'incrementen correlativament.

Per esborrar un element d'un array, es pot fer amb la instrucció unset:

php > unset( $a[2] );
php > var_dump($a);
array(3) {
  [0]=>
  string(3) "gos"
  [1]=>
  string(3) "gat"
  [3]=>
  string(6) "jirafa"
}

Primera cosa sorprenent de PHP: quan s'esborra un element d'un array, els índexs no es renumeren. En aquest exemple, a l'esborrar l'element 2, els índexs que queden son 0,1,3 (sense el 2).

Si volem redefinir els índexs, ho podem fer amb la instrucció array_values(), i el índexs tornaran a ser correlatius:

php > $b = array_values($a);
php > var_dump($b);
array(3) {
  [0]=>
  string(3) "gos"
  [1]=>
  string(3) "gat"
  [2]=>
  string(6) "jirafa"
}

Al tanto, que com podeu veure en realitat no es reordena l'array inicial, sinó que es crea un de nou ($b) amb els índexs ordenats.


Diccionaris o Arrays Associatius

L'altra estructura de dades superutilitzada és el diccionari o array associatiu. Aquest es defineix com un array al que accedim mitjançant una clau. Per tant, un array associatiu serà un conjunt de parells clau/valor.

En PHP els arrays associatius es poden definir similarment a l'array posicional, però ara definint els índexs amb la fletxa (⇒) i accedint amb claudàtors (tant per escriure com per llegir):

php > $sons = [ "gos" => "bup" , "gat" => "miau" ];
php > var_dump($sons);
array(2) {
  ["gos"]=>
  string(3) "bup"
  ["gat"]=>
  string(4) "miau"
}
php > echo $sons["gat"];
miau

I afegim elements de forma similar a Python o Javascript

php > var_dump($sons);
array(3) {
  ["gos"]=>
  string(3) "bup"
  ["gat"]=>
  string(4) "miau"
  ["vaca"]=>
  string(2) "mu"
}

La bottom line sobre arrays vs arrays associatius en PHP és que en realitat són la mateixa estructura de dades, i un array sempre es pot tractar com a array associatiu on els índexs son la clau.

Per iterar un array associatiu sol ser més fàcil utilitzar el foreach enlloc del clàssic for:

foreach( $sons as $animal => $so )
{
    echo "El $animal fa $so.<br>\n";
}


Exercicis

Batalla Naval

Anem a fer una aproximació a un joc de batalla naval. Els típics elements de joc son:

Realitza els següents exercicis:

  1. Utilitza l'exercici 4 dels taulells de jocs amb el nom de les files (lletres) i columnes (números).
  2. Crea un array amb un submarí i mostra-ho al taulell.
    • Col·loca'l en una posició aleatòria cada cop que es carrega.
    • Comprova que funciona en horitzontal i vertical.
    • Comprova que no surt dels límits de la quadrícula.
    • L'algorisme ha de funcionar amb qualsevol tipus de longitud de vaixell.
  3. Pensa en 2 maneres diferents per definir una partida sencera amb diversos vaixells i justifica pros i contres. En concret es recomana analitzar array de vaixells vs matriu de caselles.
  4. Crea una matriu per a la partida amb un vaixell de cada tipus (fixe) i mostra-ho al taulell.
  5. Omple ara la matriu amb tota una partida amb valors aleatoris: 4 fragates, 3 submarins, 2 destructors i 1 portaavions.
    • Els vaixells han de tenir col·locació aleatòria, incloent que puguin estar en vertical o en horitzontal.
    • Comprova que cada cop que recarregueu el tauler et surt una partida diferent.
    • No importa si els vaixells es solapen o si surten dels límits.
  6. Ajusta el generador de partida anterior aplicant aquestes millores:
    • Evitar que cap vaixell surti dels límits del taulell.
    • Evitar que es solapin els vaixells.
    • Evitar que els vaixells es «toquin» (cel·les adjacents).


Formularis, GET, POST i PHP

Referències bàsiques a W3Schools:

Altres:

Vés a les fites sobre formularis de la UF1 de MP07 de DAW i realitza els exercicis.


Arxius

Si volem guardar dades en arxius en PHP, disposem de diverses funcions per a realitzar aquestes operacions.

Funcions «a lo bèstia» (carreguen tot en RAM, oju peligru):

Funcions més «fines»:

Si volem guardar les dades d'un array, no tindrem prou amb aquestes funcions, ja que al guardar les dades d'un array les concatena totes juntes.

Per solventar-ho i poder guardar correctament les dades d'un array, utilitzem les funcions serialize i unserialize.

php > var_dump($sons);
array(3) {
  ["gos"]=>
  string(3) "bup"
  ["gat"]=>
  string(4) "miau"
  ["vaca"]=>
  string(2) "mu"
}
php > file_put_contents( "sons.txt", serialize($sons) );
php > $sons2 = unserialize( file_get_contents("sons.txt") );
php > var_dump($sons2);
array(3) {
  ["gos"]=>
  string(3) "bup"
  ["gat"]=>
  string(4) "miau"
  ["vaca"]=>
  string(2) "mu"
}

Examina l'arxiu «sons.txt» que has creat i explica què significa cada valor que hi apareix.


Sessions

Les sessions ens faciliten que cada usuari pugui disposar d'una àrea per emmagatzemar variables: la variable $_SESSION[].

Aquest mecanisme utilitza les cookies del navegador web per identificar l'usuari que es connecta a cada request.

PHP Sessions a W3Schools.


Més coses


Carregar imatges

Aquí tens un tutorial per carregar imatges en PHP.

També es poden enviar múltiples arxius en un sol input field.

  1. Implementa una pàgina de càrrega d'imatges al teu servidor en producció.
  2. Visualitza les imatges carregades.
  3. Afegeix un camp de descripció per a la imatge. Les imatges s'han de mostrar amb la seva descripció al costat o a sota.
  4. Arranja-ho perquè permeti la càrrega de vídeos.

    Per augmentar el límit de dades que pot carregar PHP, hauràs de modificar l'arxiu php.ini i ampliar les variables max_upload_size i post_max_size.


Enviar emails

Disposar d'un servidor d'email s'ha convertit en una tasca complicada degut a les grans quantitats de Spam que circulen. Disposar d'un servidor d'email que passi els controls antispam és força complicat. Podeu conèixer mes detalls a l'article email Linux Docker.

Disposem, al menys, de dos maneres de fer-ho:

  1. Tenint un servidor d'email local com postfix i enviant mitjançant la comanda PHP mail().
  2. Utilitzant les llibreries phpmailer: amb aquesta llibreria podem enviar mitjançant un servidor extern (caldran credencials).


Opció 1: Servidor local

És important que tinguem obert el port 25 de sortida. Tots els servidors de Cloud ho estan limitant per evitar spammers, i cal demanar un permís especial perquè funcioni.

Si disposem d'aquest servidor resulta relativament senzill.

Instal·lem postfix i mailutils:

$ sudo apt install postfix mailutils

Chequejem la instal·lació enviant un email:

$ mail [email protected]
Cc:
Subject: prova de correu
aqui poso el text de l'email
pot tenir diverses línies
acabem l'email amb un "." o bé amb CTRL+D

…i s'enviarà l'email. Comproveu la carpeta de Spam perquè probablement vagi a parar allà.


Opció 2: libs PHPMailer

Amb aquesta llibreria podem enviar mitjançant un servidor extern (caldran credencials).

Utilitza el tutorial indicat més amunt per enviar un email. Fes un formulari que permeti ajustar destinatari, títol i contingut del missatge.

Per carregar les llibreries al vostre codi cal canviar els require que hi ha per:

require "vendor/autoload.php";

Utilitza l'email de l'institut. Un Gmail normal no et permetrà enviar emails amb autenticació usuari/password (el què anomenen «less secure apps»), ja que no compleix amb les mesures de seguretat mínimes. De moment, a data de gener de 2023, als comptes corporatius els permeten les less secure apps.