Home
Home
Tutorials
   PHP
   Java
   Tutti...
Manuali
SmartImage
Marketing
Downloads
Contatti
Affiliati

  Da vedere
Hosting
Statistiche per siti
Corsi per webmaster
Hardware
Processori


  OnFocus
Creare date casuali con MySql

asdsad

PHP 5 ad oggetti: il modificatore "static"

  Siti Amici
Miki News
Giochi gratis
Areagratis
Baratto Online
AI Machines
Guide e Manuali Gratis
SpazioLink.com
Egregio Directory
e-DAI.org
Rotondella
Abbassa la vista
Twago
Add to Technorati Favorites

Tutti i siti amici
Diventa Affiliato

 


Autore: Claudio Venturini
Categoria: php
Livello: base Livello base

Implementare il pattern Singleton in script PHP

Perchè un oggetto singleton non è poi così unico

Il design pattern Singleton è uno dei pattern fondamentali dell'ingegneria del software. Se ne era già accennato negli articoli riguardanti la programmazione ad oggetti in PHP, precisamente qui, e qui, rimandando però sempre la questione.

Do per scontato che chi sta leggendo conosca il pattern. In ogni caso Wikipedia nè dà, come sempre, una spiegazione perfetta. Ho scelto di scrivere un articolo apposta, piuttosto che parlarne negli articoli sulla programmazione ad oggetti, non tanto perchè il singleton sia un pattern complicato da implementare (anzi, è il più banale), ma perchè in PHP il singleton ha un comportamento "anomalo".

In pratica un singleton in PHP è singolo solo all'interno della stessa esecuzione dello script. Ovvero è valido solo per la singola richiesta. Per chiarire meglio basta eseguire questo codice: è una classe singleton più alcune istruzioni che creano un oggetto singolo e ne richiamano il metodo getVar() due volte di seguito.

<?php

class Single {

  private static $singleton null;
  private $var;

  static function getInstance(){
    if (Single::$singleton == null){
      Single::$singleton = new Single();
    }
    return Single::$singleton;
  }

  function __construct(){
    $this->var rand();
  }

  function getVar(){
    return $this->var;
  }
}

$single Single::getInstance();
echo 
"Primo get: ".$single->getVar()."<br />";

$single Single::getInstance();
echo 
"Secondo get: ".$single->getVar()."<br />";

?> 

Nel costruttore dell'oggetto viene generato un numero random, memorizzato nella variabile $var. Il metodo getVar() ritorna semplicemente questa variabile. Se provate ad eseguire lo script, vi verrà stampato:

Primo get: xxxxx
Secondo get: xxxxx

dove xxxxx è il numero casuale generato. In pratica le due chiamate del metodo getVar() restituiscono, ovviamente, lo stesso valore. Fin qui tutto ok.
Provate però ora a fare un refresh della pagina. Lo script viene eseguito nuovamente, e, a sorpresa, è stato generato un altro numero. Notare che la richiesta viene sempre dallo stesso utente (stesso client, stesso browser, stessa finestra del browser) e ancora in un momento in cui la sessione precedente è ancora valida. Questa è l'anomalia.

In una normale applicazione il singleton rimane unico dall'inizio al termine del processo. Il problema in PHP è che non esiste il concetto di applicazione. Ovvero, ogni script è come se un'applicazione a sè stante. Per questo ad ogni nuova esecuzione il singleton precedente è sparito. Esso è stato creato, e poi eliminato al termine dello script. Per questo all'esecuzione successiva è sparito.
Se provaste ad implementare un singleton ad esempio tramite dei servlet Java, notereste che questo inconveniente non esiste. Perchè il deploy di un servlet Java avviene in un application server, che provvede a crearle un "ambiente" che gli permette di comportarsi come una applicazione vera e propria. Ecco che quindi il singleton continuerebbe a vivere anche dopo l'esecuzione del servlet, indipendentemente che le richieste arrivino da browser diversi, client diversi, o in momenti diversi.

Per questo motivo il singleton in PHP non è utile come in molti altri linguaggi di programmazione. Ad esempio non è possibile utilizzarlo per implementare una cache, perchè essa verrebbe persa alla fine dello script. Ovviamente esistono dei rimedi. Eccone alcuni, con pro e contro, ma ognuno può pensare alla soluzione che più gli piace:

  • Memorizzare il singleton, ad esempio in un database al momento della creazione, e poi recuperarlo ad ogni richiesta. Valutata la capacità di caching dei DBMS, potrebbe essere una soluzione da non scartare, soprattutto se è possibile utilizzare MySQL con engine Memory, che non richiede accessi al disco.
  • Se il singleton deve essere relativo ad un utente, può essere in qualche modo serializzato e memorizzato in cookies sul client. Ma ovviamente non è un metodo da usare per dati sensibili, come login, e soprattutto password.
  • Se il singleton deve esistere per una sessione, può essere memorizzato tra i dati della sessione dell'utente.
  • qualsiasi altra cosa vi viene in mente...

Ora che abbiamo fatto chiarezza sul problema del singleton in PHP, è possibile capire che questo problema si presenta anche nel caso di attributi statici delle classi, per il medesimo motivo. Quindi, pensare di usare una classe con variabili statiche al posto di un singleton, non cambierebbe il risultato. Anche queste classi sono allocate e deallocate ad ogni richiesta.

Aggiungere motori di ricerca italiani a Mint Precedente Indice Successivo Il pattern Singleton in PHP: persistenza durante una sessione
Aggiungere motori di ricerca italiani a Mint Il pattern Singleton in PHP: persistenza durante una sessione