Post on 05-Dec-2014
description
©All rights reserved. Zend Technologies, Inc.
Funzioni Anonime in PHP 5.3
Elena Maria Brambilla 18 Luglio 2011
Guarda il seminario web registrato: http://bit.ly/nM64No
©All rights reserved. Zend Technologies, Inc.
Ma prima, alcuni termini
©All rights reserved. Zend Technologies, Inc.3 Funzioni anonime in PHP 5.3
Lambda
• Da “lambda calcolo”
• I nomi delle funzioni sono di pura “convenienza” e perciò tutte le funzioni sono considerate anonime
• A meno che si stia utilizzando un vero linguaggio di programmazione funzionale con funzioni di prima classe, generalmente si usano funzioni anonime o espressioni lambda
©All rights reserved. Zend Technologies, Inc.4 Funzioni anonime in PHP 5.3
Closure (o chiusure)
• Una funzione che contiene un ambiente a riferimento Ciascuna funzione ha il suo scope
Permette lo stato nascosto
• Un fattore di differenziazione è che le closure permettono i riferimenti collegati che esistono all’atto della creazione, da utilizzare quando sono chiamate
©All rights reserved. Zend Technologies, Inc.5 Funzioni anonime in PHP 5.3
Funzioni anonime
• Ciascuna funzione definita e/o chiamata senza essere collegata a un identificatore
• Si può assegnare la funzione a una variabile, ma non si dà il nome proprio
©All rights reserved. Zend Technologies, Inc.
Cosa offre PHP
©All rights reserved. Zend Technologies, Inc.7 Funzioni anonime in PHP 5.3
Funtori
• Ciascun oggetto che definisce un metodo __invoke()
• Le istanze oggetto possono ora essere chiamate come se fossero funzioni
• class Command
• {
• public function __invoke($name)
• {
• echo "Ciao, $name";
• }
• }
• $c = new Command();
• $c(’Elena’); // "Ciao, Elena"
©All rights reserved. Zend Technologies, Inc.8 Funzioni anonime in PHP 5.3
Funzioni anonime
• Nuova classe Closure che definisce __invoke()
• Il corpo __invoke() è “sostituito” con la funzione definita
• Possibilità di collegare le variabili tramite importazioni, permettendo la creazione di closure
©All rights reserved. Zend Technologies, Inc.9 Funzioni anonime in PHP 5.3
Importante da sapere:
• Proprio come le normali funzioni PHP, le funzioni anonime esistono nel loro scope
• Non è possibile importare $this
• Non è possibile l’alias delle variabili importate
©All rights reserved. Zend Technologies, Inc.
La sintassi delle funzioni anonime e delle closure
©All rights reserved. Zend Technologies, Inc.11 Funzioni anonime in PHP 5.3
Concetti di base
• Semplicemente, come una normale dichiarazione di funzione, tranne per fatto che non c’è il nome:
• function($value1[, $value2[, ... $valueN]]) { };
©All rights reserved. Zend Technologies, Inc.12 Funzioni anonime in PHP 5.3
Assegnamento di variabile
• Assegnamento di funzioni a variabili; non dimenticare il punto e virgola alla fine !
• $greet = function($name) {
• echo "Ciao, $name";
• };
• $greet(’Elena’); // "Ciao, Elena "
©All rights reserved. Zend Technologies, Inc.13 Funzioni anonime in PHP 5.3
Passaggio come argomento ad altri chiamabili
• Permette un’altra funzionalità per chiamare la funzione
• function say($value, $callback)
• {
• echo $callback($value);
• }
• say(’Elena’, function($name) {
• return "Ciao, $name";
• }); // "Ciao, Elena"
©All rights reserved. Zend Technologies, Inc.14 Funzioni anonime in PHP 5.3
Creazione di closure
• Collegare le variabili alla creazione e usarle all’atto della chiamata
• $log = Zend_Log::factory($config);
• $logger = function() use($log) {
• $args = func_get_args();
• $log->info(json_encode($args));
• };
• $logger(’foo’, ’bar’); // ["foo", "bar"]
©All rights reserved. Zend Technologies, Inc.
Da provare
©All rights reserved. Zend Technologies, Inc.16 Funzioni anonime in PHP 5.3
Operazioni su array
• Ordinamento (usort, uasort, etc.)
• Scansione, mappatura, riduzione
• Filtraggio
©All rights reserved. Zend Technologies, Inc.17 Funzioni anonime in PHP 5.3
Ordinamento
• $stuff = array(’apple’, ’Anise’, ’Applesauce’, ’appleseed’);
• usort($stuff, function($a, $b) {
• return strcasecmp($a, $b);
• });
• // ’Anise’, ’apple’, ’Applesauce’, ’appleseed’
©All rights reserved. Zend Technologies, Inc.18 Funzioni anonime in PHP 5.3
Scansione
• • La scansione permette di cambiare i valori di un array
• • Se non si utilizzano oggetti, allora è necessario passare per riferimento per poter modificare i valori
• $stuff = array(’apple’, ’Anise’, ’Applesauce’, ’appleseed’);
• array_walk($stuff, function(&$value) {
• $value = strtoupper($value);
• });
• // ’APPLE’, ’ANISE’, ’APPLESAUCE’, ’APPLESEED’
©All rights reserved. Zend Technologies, Inc.19 Funzioni anonime in PHP 5.3
Mappatura
• La mappatura esegue un lavoro su ciascun elemento dell’array, il risultato sarà un nuovo array che contiene i valori restituiti
• $stuff = array(’apple’, ’Anise’, ’Applesauce’, ’appleseed’);
• $mapped = array_map(function($value) {
• $value = strtoupper($value);
• return $value;
• }, $stuff);
• // $stuff: array(’apple’, ’Anise’, ’Applesauce’, ’appleseed’)
• // $mapped: array(’APPLE’, ’ANISE’, ’APPLESAUCE’, ’APPLESEED’)
©All rights reserved. Zend Technologies, Inc.20 Funzioni anonime in PHP 5.3
Riduzione
• “Combina” gli elementi e restituisce un valore o un dataset
• Il valore restituito è passato come primo argomento della chiamata successiva
• Effettua il seeding sul valore restituito passando un terzo argomento ad array_reduce()
• $stuff = array(’apple’, ’Anise’, ’Applesauce’, ’appleseed’);
• $reduce = array_reduce($stuff, function($count, $input) {
• $count += substr_count($input, ’a’);
• return $count;
• }, 0);
• // $stuff: array(’apple’, ’Anise’, ’Applesauce’, ’appleseed’)
• // $reduce: 3
©All rights reserved. Zend Technologies, Inc.21 Funzioni anonime in PHP 5.3
Filtraggio
• Restituisce solo gli elementi che sono riconosciuti come true
• Spesso questa è considerata una forma di mappatura ed è utilizzata per rifilare un dataste, solo su quegli elementi che sono di interesse primario per la riduzione
• $stuff = array(’apple’, ’Anise’, ’Applesauce’, ’appleseed’);
• $reduce = array_reduce($stuff, function($count, $input) {
• $count += substr_count($input, ’a’);
• return $count;
• }, 0);
• // $stuff: array(’apple’, ’Anise’, ’Applesauce’, ’appleseed’)
• // $reduce: 3
©All rights reserved. Zend Technologies, Inc.22 Funzioni anonime in PHP 5.3
Operazioni su stringa
• Espressioni regolari (preg_replace_callback)
• Applicazione parziale (currying) degli argomenti
©All rights reserved. Zend Technologies, Inc.23 Funzioni anonime in PHP 5.3
preg_replace_callback()
• Permette di trasformare le corrispondenze estratte
• $string = "Today’s date next month is " . date(’Y-m-d’);
• $fixed = preg_replace_callback(’/(\d{4}-\d{2}-\d{2})/’,
• function($matches) {
• $date = new DateTime($matches[1]);
• $date->add(new DateInterval(’P1M’));
• return $date->format(’Y-m-d’);
• }, $string);
• // "Today’s date next month is 2011-05-26"
©All rights reserved. Zend Technologies, Inc.24 Funzioni anonime in PHP 5.3
Applicazione parziale (currying) degli argomenti
• In alcuni casi si possono fornire argomenti predefiniti:
• Per ridurre il numero di argomenti di cui si ha bisogno
• Per fornire valori ad argomenti opzionali
• Per fornire una signature unificata per le callback
• $hs = function ($value) {
• return htmlspecialchars($value, ENT_QUOTES, "UTF-8", false);
• };
• $filtered = $hs("<span>Matthew Weier O’Phinney</span>");
• // "<span>Matthew Weier O'Phinney</span>"
©All rights reserved. Zend Technologies, Inc.
ATTENZIONE
©All rights reserved. Zend Technologies, Inc.26 Funzioni anonime in PHP 5.3
Riferimenti
• Le variabili passate alle callback, come argomenti o come importazioni, non sono passate per riferimento
• Utilizzare oggetti, oppure
• Passare per riferimento • $count = 0;
• $counter = function (&$value) use (&$count) {
• if (is_int($value)) {
• $count += $value;
• $value = 0;
• }
• };
• $stuff = array(’foo’, 1, 3, ’bar’);
• array_walk($stuff, $counter);
• // $stuff: array(’foo’, 0, 0, ’bar’)
• // $count: 4
©All rights reserved. Zend Technologies, Inc.27 Funzioni anonime in PHP 5.3
La combinazione con altri chiamabili
• Problemi e considerazioni:
• Closure è un “dettaglio di implementazione”; il typehinting (suggerimento di tipo) esclude gli altri tipi callback
• is_callable()dice solo che può essere chiamato, ma non in che modo
• is_callable() && is_object()dice che abbiamo un funtore, ma omette altri tipi callback
©All rights reserved. Zend Technologies, Inc.28 Funzioni anonime in PHP 5.3
La combinazione con altri chiamabili
• Tre modi per la chiamata (1/3):
• $o($arg1, $arg2)
• Vantaggi: velocità
• Problemi: non funzionerà a meno che si abbiano un funtore, una closure o una chiamata a metodo statico
©All rights reserved. Zend Technologies, Inc.29 Funzioni anonime in PHP 5.3
La combinazione con altri chiamabili
• Tre modi per la chiamata (2/3):
• call_user_func($o, $arg1, $arg2)
• Vantaggi: velocità, funziona con tutti i chiamabili
• Problemi: se il numero di argomenti è sconosciuto fino al runtime, diventa difficile la gestione
©All rights reserved. Zend Technologies, Inc.30 Funzioni anonime in PHP 5.3
La combinazione con altri chiamabili
• Tre modi per la chiamata (3/3):
• call_user_func_array($o, $argv)
• Vantaggi: funziona con tutti i chiamabili, funziona con un numero di argomenti variabile
• Problemi: lentezza (impiega fino a 6 volte di più di una chiamata diretta)
©All rights reserved. Zend Technologies, Inc.31 Funzioni anonime in PHP 5.3
Non si può importare $this
• Gli sviluppatori creativi vorrebbero usare le closure per il monkey-patch degli oggetti
• (Nota: Monkey patching è un modo per ampliare o modificare il runtime codice di linguaggi dinamici senza alterare la fonte originale codice)
©All rights reserved. Zend Technologies, Inc.32 Funzioni anonime in PHP 5.3
Non si può importare $this
• Gli sviluppatori creativi vorrebbero usare le closure per il monkey-patch degli oggetti
• È possibile. Solo che non si può usare $this, ciò significa che si presentano dei limiti ai metodi pubblici
©All rights reserved. Zend Technologies, Inc.33 Funzioni anonime in PHP 5.3
Non si può importare $this
• Gli sviluppatori creativi vorrebbero usare le closure per il monkey-patch degli oggetti
• È possibile. Solo non si può usare $this, il che significa che si presentano dei limiti ai metodi pubblici
• Inoltre non è possibile auto-dereferenziare le closure assegnate alle proprietà
©All rights reserved. Zend Technologies, Inc.34 Funzioni anonime in PHP 5.3
Esempio: Monkey-Patching
• class Foo
• {
• public function __construct()
• {
• $self = $this;
• $this->bar = function () use ($self) {
• return get_object_vars($self);
• };
• }
• public function addMethod($name, Closure $c)
• {
• $this->$name = $c;
• }
• public function __call($method, $args)
• {
• if (property_exists($this, $method) &&
• is_callable($this->$method)) {
• return call_user_func_array($this->$method, $args);
• }
• }
• }
©All rights reserved. Zend Technologies, Inc.35 Funzioni anonime in PHP 5.3
Serializzazione
• Le funzioni anonime non si possono serializzare
©All rights reserved. Zend Technologies, Inc.
Alcuni casi d’uso
©All rights reserved. Zend Technologies, Inc.37 Funzioni anonime in PHP 5.3
Aspect Oriented Programming
• Il codice definisce “aspetti,” oppure codice che taglia attraverso i limiti di più componenti
• AOP formalizza un modo per congiungere gli aspetti ad altro codice.
• Spesso, si potrebbe aver bisogno di effettuare il curry su argomenti per mantenere le signature.
©All rights reserved. Zend Technologies, Inc.38 Funzioni anonime in PHP 5.3
Esempio Gestione Eventi
• $front->events()->attach(’dispatch.router.post’, function($e) use
• ($cache) {
• $request = $e->getParam(’request’);
• if (!$request instanceof Zend\Http\Request || !$request->isGet())
• {
• return;
• }
• $metadata = json_encode($request->getMetadata());
• $key = hash(’md5’, $metadata);
• $backend = $cache->getCache(’default’);
• if (false !== ($content = $backend->load($key))) {
• $response = $e->getParam(’response’);
• $response->setContent($content);
• return $response;
• }
• return;
• });
©All rights reserved. Zend Technologies, Inc.
È tutto!
©All rights reserved. Zend Technologies, Inc.40 Funzioni anonime in PHP 5.3
Riferimenti
• Manuale PHP: http://php.net/functions.anonymous
©All rights reserved. Zend Technologies, Inc.
Grazie!
Guarda il seminario web registrato: http://bit.ly/nM64No