💻

PHP

File PHP

Un file PHP termina con l’estensione .php ed il codice all’interno è di default HTML. Per inserire uno script PHP bisogna utilizzare delle particolari keyword che possono essere:

<?php
// Codice php
?>
<div>
	Ritorno all'html
</div>

<!-- Se ho bisogno di mostrare solamente una variabile posso usare una shorthand -->
<div>
	Contenuto html con variabile php di valore <?= $variabile ?>
	È uguale a <?php echo $variabile; ?>
</div>

È possibile inserire dei commenti in tre modi diversi

<?php
# Commento a singola linea

// Commento a singola linea

/*
	Commento 
	multilinea
*/
?>

Variabili

$a = 5;
$b = 3;
$testo = "Ciao testo";
// Il tipo è gestito dal linguaggio in automatico, tipo js
$c= $a / $b;

Output

echo $c;

echo "stampa con variabile $c";
echo 'stampa senza variabile $c (singoli apici)';

// Concatenazione stringhe
echo "ciao ".($c+1)." mondo";

// Visualizza tipo + valore variabile
var_dump($c);
// Più leggibile
print_r($c);

// Forzo la variabile come intero
var_dump((int)$c);

Array

$array = array(1, 2, 3, 4, 5, 6);
$array = [1, 2, 3, 4, 5 ,6];

// Array con indice custom
$array_indice_custom = ["indice" => 1, "ciao" => 2, 3, 4, 5];
echo $array_indice_custom["indice"]

// Iterare un array
for ($i=0; $i < count($array); $i++) {
	// ...
}

foreach ($array as $key => $val) {
    echo "Chiave $key - valore: $val";
}

// Controllare contenuto array
// Se è vuoto
echo empty($array)
echo count($array) == 0
// Se un elemento con una certa chiave esiste
echo isset($array["chiave"])

Funzioni

function ciao() {
    echo "Ciao";
}
ciao();

function scambia_non_funziona($v1, $v2) {
    // Se si modificano le variabili all'interno delle funzioni i cambiamenti non sono applicati al di fuori della funzione
    // Le variabili ora sono copie di quelle ricevute non referenze
    $tmp = $v1;
    $v1 = $v2;
    $v2 = $tmp;
}
function scambia(&$v1, &$v2) {
    // I cambiamenti alle variabili hanno effetto anche all'esterno della funzione
    // Con la & si ricevono referenze alle variabili
    $tmp = $v1;
    $v1 = $v2;
    $v2 = $tmp;
}

$v1 = 1;
$v2 = 2;

echo "v1 $v1 - v2 $v2";
scambia_non_funziona($v1, $v2);
echo "v1 $v1 - v2 $v2";
scambia($v1, $v2);
echo "v1 $v1 - v2 $v2";

Input

<!-- $_SERVER è una variabile globale utilizzabile ovunque -->
<form method="post" action="<?= $_SERVER['PHP_SELF'] ?>">
    <label for="fname">Nome</label>
    <input type="text" id="fname" name="fname" value="Giulio">
    <input type="submit" value="Invia">
</form>

<?php
/*
	$_GET e $_POST sono delle variabili globali presenti di default.
	Sono sotto forma di array e come chiave per ogni elemento hanno il `name` dell'elemento del form html
*/
if(!empty($_POST))
    echo $_POST["fname"];

Session

La $_SESSION è una variabile temporanea che contiene informazioni diverse per ogni utente. Le informazioni sono temporanee perché una volta che l’utente termina la sessione, ossia chiude il browser, esse non saranno più disponibili.

// Starto la sessione
session_start();

// Imposto delle variabili alla sessione
$_SESSION["tema"] = 1;

// Prendo una variabile dalla sessione
$tema = $_SESSION["tema"];

// Rimuovo tutte le variabili dalla sessione
session_unset();

// Distruggo la sessione
session_destroy();

Classi

/*
	All'interno della classe si può usare la variabile $this come istanza della classe
	e le frecce per le funzioni -> per accedere alle variabilie.
	Per le costanti invece c'è la keyword self che va seguita dai doppi due punti ::
*/
class Articolo {
	// Costanti
	CONST PREZZO_MINIMO = 1;
	CONST TIPI_PRODOTTO = ['a', 'b', 'c', 'd'];

	// Variabili statiche
	public static $info = "Informazioni su articoli";
	

	// Variabili della classe
	private $nome;
	public $prezzo;

	// Costruttore della classe
	function __construct($nome, $prezzo) {
    $this->nome = $nome;
		$this->prezzo = $prezzo;
  }

	public function get_nome($nome) {
		return $this->nome;
	}

	private function set_nome($nome) {
		$this->nome = $nome;
	}

	// Utilizzo delle costanti e funzioni statiche
	public static function lista_tipi_prodotto() {
		return "Lista tipi prodotto".self::TIPI_PRODOTTO;
	}

	public function controllo_prezzo_minimo() {
		return $this->prezzo >= self::PREZZO_MINIMO;
	}
}

// Utilizzo di costanti e funzioni statiche
echo "Prezzo minimo articoli:".Articolo::PREZZO_MINIMO;
echo Articolo::lista_tipi_prodotto();
// Utilizzo di variabili statiche
echo Articolo::$info;

$articolo1 = new Articolo("maionese", 200);
$articolo2 = new Articolo("fiorentina", 4);

Serializzazione

class Data {
	public $dato;
}

$data = new Data();
// Serializzo
$_SESSION["ds"] = serialize($data);
// Deserializzo
$data_deserializzata = unserialize($_SESSION["ds"]);

Password

È importante criptare le password per evitare che se un malintenzionato accede al database egli possa vedere tutte le password in chiaro.

$testo_password = "1234";
// Cripto la password in chiaro
/*
	Per criptarla uso una funzione di php default che "hasha" la password.
	Una funzione di hash darà sempre lo stesso output se l'input è lo stesso
	l'output sarà diverso se l'input è diverso.
	Esempio:
	hash(cane) = aaa1
	hash(gatto) = 22a1
	hash(cane) = aaa1
	hash(gato) = 56aa
*/
$password_criptata = password_hash($testo_password, PASSWORD_DEFAULT);

/*
	Per verificare che una password coincida con quella criptata
	la devo passare attraverso lo stesso algoritmo di hash.
	PHP ha una funzione di default che controlla se un testo corrisponde alla password corretta
	e restituisce un booleano
*/
$corretto = password_verify($input, $password_criptata)
// Sostanzialmente fa
function password_verify($input, $hash) {
	return password_hash($input, PASSWORD_DEFAULT) == $hash;
}

Database

Per connettersi ad un database usiamo la classe mysqli presente di default in php.

class DbManager {
	// Host del database
	CONST DB_HOST = "localhost";
	// Utente con cui autenticarsi, in genere 'root'
	CONST DB_USER = "root";
	// Password dell'utente, in genere vuota ''
	CONST DB_PASSWORD = "password";
	// Nome del database a cui connettersi
	CONST DB_NAME = "dipendenti";

/*
	Utilizzo del pattern singleton per creare una classe
	che può avere una sola istanza di se stessa.
	In questo modo useremo sempre la stessa istanza della classe
	per interfacciarci al database senza doverci ricollegare ad esso
	ogni volta.
*/
	// Istanza della classe
	private static $dbManager = null;
	
	// Connessione al database
	private $connection;
	
	// Costruttore private per non rendere possibile l'istanziamento della classe all'esterno di essa
	private function __construct() {
		$this->connection = new mysqli(
			self::DB_HOST,
			self::DB_USER,
			self::DB_PASSWORD,
			self::DB_NAME
		);
		if ($this->connection->connect_error)
			die("Si è verificato un errore: ". $this->connection->connect_error);
	}

	// Metodo statico che permette di prendere l'istanza della classe
	public static function getInstance() {
		if (self::$dbManager == null)
			self::$dbManager = new DbManager();
		
		return self::$dbManager;
	}

	// Esempio di metodo che prende dati dal db
	public function get_utente($id) {
		$query = "SELECT * FROM utenti WHERE id=?";
		$prepared = $this->connection->prepare($query);
		// "s" sta per stringa come tipo di valore del parametro
		$prepared->bind_param("s", $id);
		$prepared->execute();

		$result = $prepared->get_result();
		$assoc = $result->fetch_assoc();

		if ($result == false || $assoc == null)
			return null;
		else
			return new Utente($id, $assoc['nome'], $assoc['cognome']);
	}

	// Esempio d'uso di multiple righe
	public function stampa_utenti() {
		$result = $this->connection->query("SELECT * FROM utenti");
		$rows = $result->num_rows;
	
		if ($rows > 0) {
			while ($row = $result->fetch_assoc()) {
				echo "ID: $row[id], nome: $row[nome] <br>";
			}
		}
	}

	// Esempio di metodo che inserisce dati nel db
	public function registra_utente($id, $nome, $cognome) {
		$query = "INSERT INTO utenti (id, nome, cognome) VALUES (?, ?, ?)";
		$prepared = $this->connection->prepare($query);
		$prepared->bind_param("s", $id, $nome, $cognome);
		$prepared->execute();
		$result = $prepared->get_result();

		if ($result == false)
			return false;
		else
			return true;
	}
}

Autoloader

Un autoloader serve a caricare e rendere disponibili tutte le classi di un progetto in un file php di esso.

<!-- File: autoloader.php -->
<?php
session_start();

spl_autoload_register(function ($class_name) {
    include $class_name . '.php';
});
?>

<!-- File: index.php -->
<?php
include "autoloader.php";
// tuttecosse
?>

Altri esempi

https://github.com/5A-Informatica-IIS-Silva-Ricci/PHP