409 votos

En PHP 5.3.0, ¿cuál es la función de "utilizar" identificar?

Estoy chequeando algunos de php 5.3.0 características y corrió a través de algún código en el sitio que se ve bastante divertido:

public function getTotal($tax)
{
    $total = 0.00;

    $callback =
        /* This line here: */
        function ($quantity, $product) use ($tax, &$total)
        {
            $pricePerItem = constant(__CLASS__ . "::PRICE_" .
                strtoupper($product));
            $total += ($pricePerItem * $quantity) * ($tax + 1.0);
        };

    array_walk($this->products, $callback);
    return round($total, 2);
}

como en los ejemplos : http://www.php.net/manual/en/functions.anonymous.php

¿Alguien sabe acerca de esto ? Toda la documentación? Y se ve mal, Debe ser usado alguna vez?

478voto

zupa Puntos 2634

Una simple respuesta.

function ($quantity) use ($tax, &$total) { .. };

  1. El cierre es una función asignada a una variable, así que puede pasar de todo
  2. Un cierre a un espacio de nombres separado, normalmente, no se puede acceder a las variables definidas fuera de este espacio de nombres. De ahí viene el uso de la palabra clave:
  3. uso permite el acceso (uso) de las siguientes variables en el interior del cierre.
  4. el uso es el enlace. Eso significa que los valores de las variables se COPIAN en la definición del cierre. Para la modificación de dólares de impuestos en el interior de la clausura no tiene ningún efecto en el exterior.
  5. Puede pasar en variables como punteros como en el caso de &$total. De esta manera, se modifica el valor de $total TIENE un efecto externo, el original valor de la variable cambia.
  6. Las Variables definidas dentro de la clausura no son accesibles desde fuera de la clausura.
  7. Los cierres y las funciones tienen la misma velocidad. Sí, usted puede hacer uso de ellos en todo su scripts.

Como @Mytskine señaló probablemente la mejor explicación detallada es el RFC por los cierres. (Upvote él).

363voto

Andrew Hare Puntos 159332

Esta es la forma en PHP expresa un cierre. Esto no es malo en absoluto y, de hecho, es bastante potente y útil.

Básicamente lo que esto significa es que están permitiendo que la función anónima para "capturar" las variables locales (en este caso, $tax y una referencia a $total) fuera del alcance y de preservar sus valores (o, en el caso de $total la referencia $total sí mismo) como estado dentro de la función anónima en sí.

53voto

stefs Puntos 8257

los cierres son hermosas! resolver un montón de problemas que vienen con funciones anónimas, y hacer realidad el código elegante posible (al menos mientras hablamos de php).

javascript, los programadores utilizan cierres de todo el tiempo, a veces incluso sin saberlo, debido a variables enlazadas no están explícitamente definidos - que es lo que el "uso" está en php.

hay mejores ejemplos del mundo real que la de arriba. digamos que usted tiene que ordenar una matriz multidimensional por un sub-valor, pero la clave de los cambios.

<?php
    function generateComparisonFunctionForKey($key) {
        return function ($left, $right) use ($key) {
            if ($left[$key] == $right[$key])
                return 0;
            else
                return ($left[$key] < $right[$key]) ? -1 : 1;
        };
    }

    $myArray = array(
        array('name' => 'Alex', 'age' => 70),
        array('name' => 'Enrico', 'age' => 25)
    );

    $sortByName = generateComparisonFunctionForKey('name');
    $sortByAge  = generateComparisonFunctionForKey('age');

    usort($myArray, $sortByName);

    usort($myArray, $sortByAge);
?>

advertencia: el código no probado (no tengo php5.3 instalado atm), pero debería parecerse a algo como eso.

hay un inconveniente: una gran cantidad de desarrolladores de php puede ser un poco inútil si quieres enfrentarte a ellos con los cierres.

para entender el agradable-dad de los cierres más, te voy a dar otro ejemplo, esta vez en javascript. uno de los problemas es la definición del alcance y el navegador inherente asynchronity. especialmente, si se trata de window.setTimeout(); (o intervalo). así, se pasa a una función setTimeout, pero realmente no se puede dar cualquiera de los parámetros, debido a proporcionar parámetros se ejecuta el código!

function getFunctionTextInASecond(value) {
    return function () {
        document.getElementsByName('body')[0].innerHTML = value; // "value" is the bound variable!
    }
}

var textToDisplay = prompt('text to show in a second', 'foo bar');

// this returns a function that sets the bodys innerHTML to the prompted value
var myFunction = getFunctionTextInASecond(textToDisplay);

window.setTimeout(myFunction, 1000);

myFunction devuelve una función con un tipo de parámetro predefinidos!

para ser honesto, me gusta php mucho más desde 5.3 y funciones anónimas/cierres. los espacios de nombres pueden ser más importantes, pero son mucho menos sexy.

-2voto

JMHeap Puntos 66

PHP tiene varios "uso", uno de aliasing/importar (http://php.net/manual/en/language.namespaces.importing.php) y otro para los cierres.

Que es muy confuso.

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X