Categorie
PHP

I Named Arguments in PHP 8: come utilizzare gli argomenti per nome per migliorare la leggibilità del codice

PHP 8 ha introdotto una nuova caratteristica chiamata “named arguments“, che consente di passare argomenti a una funzione utilizzando il nome dell’argomento invece della posizione.

In precedenza, quando si chiamava una funzione in PHP, gli argomenti dovevano essere passati nello stesso ordine in cui erano dichiarati nella funzione. Con l’introduzione dei “named arguments“, è possibile specificare il nome dell’argomento seguito dal valore, indipendentemente dalla posizione nella chiamata della funzione.

Categorie
PHP

Come utilizzare le nuove funzioni di manipolazione delle stringhe in PHP – str_contains, str_starts_with e str_ends_with

PHP è un linguaggio di programmazione popolare utilizzato per lo sviluppo di siti web e applicazioni web. Con PHP 8, sono state introdotte alcune nuove funzioni per lavorare con stringhe, che possono essere molto utili per gli sviluppatori e i programmatori. In questo articolo, esploreremo le nuove funzioni str_contains, str_starts_withe str_ends_with e vedremo come possono essere utilizzate per semplificare alcuni compiti comuni di manipolazione delle stringhe.

Categorie
PHP

Che cos’è e come utilizzare il null safe operator in PHP 8

Il null safe operator in PHP è stato introdotto a partire dalla versione 8.0 e serve a semplificare l’accesso a proprietà o metodi di un oggetto evitando il controllo della presenza del valore null.

In precedenza, per invocare un metodo di un oggetto che potrebbe essere null era necessario controllare prima la sua presenza, utilizzando ad esempio l’operatore ternario o la funzione “isset“. Ad esempio:

Categorie
PHP

Destrutturazione di un array in PHP: cos’è e come funziona

La destrutturazione è una caratteristica di PHP che permette di assegnare i valori di un array a delle variabili. A partire da PHP 7.4, è possibile utilizzare la destrutturazione anche per gli array associativi.

Per capire meglio, immagina di avere una scatola piena di biglie colorate. Con la destrutturazione, puoi prendere una biglia alla volta e metterla in una tua scatola personale senza dover svuotare la scatola originale.

Categorie
PHP

ZF2 Navigation Menu con integrazione di Twitter Bootstrap

Dato che Twitter Boostrap (v3) è il front-end framework più utlizzato, nonchè quello “installato” di default con la ZendSkeletonApplication vediamo come aggiornare il Navigation Menu Helper affinchè si adatti alla Navbar di Boostrap.

Categorie
PHP

Come far comprendere al mio IDE il Dependency Injection Container

Recentemente in un mio progetto con Zend Framework 1 ho implementato Pimple, il noto DIC progettato da Fabien Potencier.
Una delle lacune di ZF1, difatti, è la mancanza di un meccanismo interno di supporto alla Dependency injection.

Il problema

In giro ci sono altri DIC ben costruiti, tuttavia la mia scelta e caduta su Pimple grazie alla sua semplicità di utilizzo ed alla sua robustezza (nochè alla fiducia sull’autore nonostante non sia un “Symfoniano”).

Tuttavia quando si lavora con Pimple ci si accorge subito di un problema, l’impossibilità di usare l’autocompletamento con l’IDE.
Difatti a causa dell’astrazione offerta dal DIC, l’IDE che sto usando (Netbeans) non capisce più quello che sta succedendo nel mio codice.
Non capisce ad esempio che $container['myService'] contiene un oggetto.

Questo per me è realmente un bel problema. Programmare senza suggerimenti sul codice e completamento automatico non è piacevole ed il mio IDE diventa inutile.

Categorie
PHP

Zend Framework controller con più parole

Oggi ho avuto la necessità di creare all’interno di una mia applicazione (sviluppata con Zend Framework 1) un URL composto da due parole.

Categorie
PHP

PHP – Design Pattern Abstract Factory

Si tratta sicuramente di uno dei design pattern fondamentali introdotti dalla GoF.
Come il factory method rientra nella categoria dei pattern creazionali, cioè tra i modelli che forniscono meccanismi per la creazione di oggetti.

Partecipanti

  • AbstractFactory: Dichiara l’interfaccia per i metodi che creano i prodotti astratti.
  • ConcreteFactory: Implementa l’interfaccia AbstractFactory per creare i prodotti concreti.
  • AbstractProduct: Dichiara l’interfaccia per un tipo di oggetto prodotto.
  • ConcreteProduct: Implementa l’interfaccia AbstractProduct e definisce l’oggetto prodotto che deve essere creato dalla factory concreta corrispondente (ConcreteFactory).
  • Client: Utilizza solo le interfacce dichiarate da AbstractFactory e AbstractProduct.

Riassumendo, la responsabilità della creazione dei prodotti (ConcreteProduct) è dei ConcreteFactory, mentre AbstractFactory funge soltanto da interfaccia per questi.

Struttura

Abstract Factory

Obiettivo

Supponiamo che abbiamo varie famiglie di prodotti… il nostro scopo sarà quello di sostituire facilmente una famiglia con un’altra evitando una chiamata esplicita ai costruttori delle classi prodotto.
Possiamo raggiungere tale obiettivo rendendo astratto il processo di creazione degli oggetti.
Prendiamo in considerazione il diagramma del pattern, ci sono due famiglie di prodotti la famiglia1 (ProductA1 e ProductB1) e la famiglia2 (ProductA2 e ProductB2).
Il nostro obiettivo quindi sarà quello, previa configurazione del sistema con una famiglia prodotto, di renderlo indipendente da come gli oggetti vengono creati.

AbstractFactory

Rappresenta l’interfaccia utilizzata dai client per creare i prodotti concreti.
I client utilizzeranno questa interfaccia per creare famiglie di oggetti connessi tra loro in modo che non gli venga richiesto di specificare esplicitamente il nome delle classi concrete all’interno del proprio codice.

interface AbstractFactory
{
    //AbstractFactory
    public function createProductA();
    public function createProductB();
}

ConcreteFactory

Implementano l’interfaccia AbstractFactory e servono per creare i prodotti concreti. Ogni ConcreteFactory sarà responsabile della creazione di una famiglia di prodotti ed avrà tanti metodi quanti sono i prodotti concreti da creare.

//ConcreteFactory (fabbrica per la famiglia 1)
class ConcreteFactory1 implements AbstractFactory
{
   public function createProductA()
   {
      return new ProductA1();
   }

   public function CreateProductB()
   {
      return new ProductB1();
   }
}

//ConcreteFactory (fabbrica per la famiglia 2)
class ConcreteFactory2 implements AbstractFactory
{
   public function createProductA()
   {
      return new ProductA2();
   }

   public function CreateProductB()
   {
      return new ProductB2();
   }
}

AbstractProduct

Dichiara l’interfaccia per i prodotti concreti. I client utilizzeranno questa interfaccia indipendentemente dalla famiglia di prodotto con cui stiamo lavorando.

//AbstractProduct
interface AbstractProductA 
{     
    public function foo();
}

//AbstractProduct
interface AbstractProductB
{
    public function baz();
}

ConcreteProduct

Rappresenta un prodotto concreto, cioè l’oggetto che abbiamo bisogno di istanziare attraverso le fabbriche. Naturalmente ogni ConcreteProduct dovrà implementare l’interfaccia AbstractProduct corrispondente.

//Famiglia1
class ProductA1 implements AbstractProductA
{
    public function foo()
    {
        echo 'Prodotto A famiglia 1';
    }
}

class ProductB1 implements AbstractProductB
{
    public function baz()
    {
        echo 'Prodotto B famiglia 1';;
    }
}
//Famiglia2
class ProductA2 implements AbstractProductA
{
    public function foo()
    {
        echo 'Prodotto A famiglia 2';
    }
}

class ProductB2 implements AbstractProductB
{
    public function baz()
    {
        echo 'Prodotto B famiglia 2';
    }
}

Client

Infine vediamo come il client utilizzerà questa struttura.
Come detto il nostro obiettivo sarà quello di rendere il sistema indipendente dalla creazione degli oggetti (prodotti) al fine permettere un’agile sostituzione di una famiglia di prodotti con un’altra.

//client
//instanzio la fabbrica
$factory = new ConcreteFactory1();
//creo i prodotti
$productA = $factory->createProductA();
$productB = $factory->CreateProductB();
$productA->foo();
$productB->baz();

//cambio famiglia
$factory = new ConcreteFactory2();
$productA = $factory->createProductA();
$productB = $factory->CreateProductB();
$productA->foo();
$productB->baz();

L’esempio, anche se completamente privo di senso, ci dimostra come sia semplice passare da una famiglia ad un’altra, e come per il client non faccia nessuna distinzione la creazione di un oggetto sia quello di una famiglia piuttosto che di un’altra.
Senza il pattern se avessimo voluto creare il prodottoA della famiglia1 avremmo utilizzato il seguente codice:

$productA = new ProductA1();

Questo è proprio quello che vogliamo evitare, al fine di minimizzare la dipendenza con un particolare tipo di famiglia.
Con il nostro approccio:

$productA = $factory->createProductA();

abbiamo evitato la chiamata diretta al costruttore di ProductA1 ottenendo lo stesso risultato ma con una differenza sostanziale.
L’oggetto factory astrae completamente il processo di creazione non solo del prodotto A della famiglia1, ma per qualsiasi prodotto A, di qualsiasi famiglia.
Non solo, factory non è limitata al prodotto A ma può gestire la creazione dell’intero set di prodotti.
Possiamo raggiungere questo risultato grazie al fatto che factory implementa l’interfaccia AbstractFactory. AbstractFactory implementa difatti tutti i metodi necessari alla creazione delle diverse tipologie di prodotto (createProductA(), createProductB()).

Quando e come istanziare la fabbrica?

Una delle domande ricorrenti circa questo pattern è quella di stabilire in che punto dobbiamo istanziare la factory concreta. Quelli della banda dei quattro suggeriscono l’utilizzo del pattern singleton di modo da avere una sola istanza della fabbrica condivisa tra gli ambienti che la utilizzano.
Tuttavia nel corso degli anni abbiamo imparato come il pattern singleton sia considerato una cattiva pratica e possibilmente da evitare.
Quindi la risposta è: dipende dal contesto. Tuttavia deve essere fatto ragionevolmente presto e comunque prima che il programma abbia bisogno di usarla per la creazione dei prodotti.

Conclusioni

Il pattern Abstract Factory è un modello creazionale, utilizzato per costruire oggetti.
Tutti i linguaggi OO hanno un idioma per la creazione di oggetti. In PHP l’idioma è l’operatore new.
I pattern creazionali ci permettono di scrivere metodi che creano nuovi oggetti senza utilizzare esplicitamente tale operatore.
Questo ci porta ad uno dei principali vantaggi del pattern, e cioè che il client è totalmente disaccoppiato dai prodotti concreti.

Una volta inizializzata la fabbrica, saremo sicuri che l’applicazione sarà in grado di creare gli oggetti (prodotti) appropriati senza bisogno di modifiche.

Inoltre, possono essere aggiunte facilmente al sistema nuove famiglie di prodotti, semplicemente aggiungendo un nuovo tipo di ConcreteFactory che implementa AbstractFactory, e creando le specifiche implementazioni del prodotto.

Anche il factory method è un pattern avente come obiettivo la creazione di prodotti tuttavia l’abstract factory è particolarmente indicato quando il sistema deve creare più famiglie di prodotti, di cui ne sarà utilizzata solo una alla volta.

Categorie
PHP

PHP – Design Pattern Decorator

Nell’object-oriented programming il pattern Decorator è un design pattern strutturale, che ci permette di aggiungere funzionalità ad un oggetto dinamicamente in fase di runtime.
Detto anche Wrapper è di uno dei pattern fondamentali definiti dalla GoF.

Categorie
PHP

PHP – Design Pattern Strategy

Si tratta probabilmente di uno dei pattern (comportamentali) più famosi tra quelli teorizzati dalla banda dei quattro sul loro libro.
Il modello ha come scopo, una volta individuata una famiglia di algoritmi, di incapsularli rendendoli intercambiabili.