PHP, kas yra uždaryta ir kodėl ji naudoja naudojimo identifikatorių?

Žiūriu į kai kurias PHP 5.3.0 ir žiūriu į tam tikrą kodą svetainėje, kuri atrodo gana juokinga:

 public function getTotal($tax) { $total = 0.00; $callback =  function ($quantity, $product) use ($tax,  { $pricePerItem = constant(__CLASS__ . "::PRICE_" . strtoupper($product)); $total += ($pricePerItem * $quantity) * ($tax + 1.0); }; array_walk($this->products, $callback); return round($total, 2); } 

kaip anoniminių funkcijų pavyzdys.

Ar kas nors apie tai žino? Bet kokie dokumentai? Ir ar tai atrodo bloga, jei kada nors ją naudosite?

346
30 июня '09 в 21:21 2009-06-30 21:21 SeanDowney rinkosi birželio 30 d. 09:21 21:21 2009-06-30 21:21
@ 6 atsakymai

Taigi PHP išreiškia uždarymą . Tai nėra bloga, bet iš tikrųjų tai gana galinga ir naudinga.

Iš esmės tai reiškia, kad leisite anoniminei funkcijai „užfiksuoti“ vietinius kintamuosius (šiuo atveju $tax ir nuorodą į $total ) už taikymo srities ribų ir išsaugoti jų vertes (arba, jei yra, iš $total nuoroda į $total ), kaip būseną viduje anonimiškiausią funkciją.

305
30 июня '09 в 21:24 2009-06-30 21:24 atsakymą pateikė Andrew Hare birželio 30 d., 09:21, 2009-06-30 21:24

Paprastas atsakymas.

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

border=0
  • Uždarymas yra funkcija, priskirta kintamajam, todėl galite jį perduoti
  • Uždarymas yra atskira vardų sritis, paprastai negalite pasiekti kintamųjų, apibrėžtų už šios vardų srities. Naudojamas raktinis žodis:
  • naudojimas leidžia naudoti (naudoti) šiuos kintamuosius uždaroje dalyje.
  • naudojimas - ankstyvas įpareigojimas. Tai reiškia, kad COPIED kintamųjų vertės nustatomos nustatant uždarymą. Todėl $tax keitimas grandinėje neturi išorinio poveikio, nebent jis yra rodyklė, kaip objektas.
  • Kintamuosius galite perduoti kaip nuorodas, pvz., Jei > . Taigi $total vertės keitimas turi išorinį efektą - pradinė kintamųjų pokyčių vertė.
  • Uždarymo metu nustatyti kintamieji taip pat nepasiekiami dėl uždarymo.
  • Uždarymas ir funkcijos turi tokį pat greitį. Taip, juos galite naudoti visuose scenarijuose.

Kaip pažymėjo @Mytskine, geriausias geriausias paaiškinimas yra uždarymo RFC . (Pakelkite jį.)

404
24 апр. atsakymas pateikiamas zupa 24 d. 2012-04-24 21:39 '12 at 9:39 pm 2012-04-24 21:39

uždarymas yra puikus! jie išsprendžia daugybę problemų, susijusių su anoniminėmis funkcijomis, ir leidžia tikrai elegantišką kodą (bent jau kalbant apie php).

„Javascript“ programuotojai visą laiką naudoja uždarymus, kartais net nežinant, nes ribiniai kintamieji nėra aiškiai apibrėžti - tai, kas naudojama php.

Yra geresnių realaus pasaulio pavyzdžių, nei nurodyta pirmiau. Tarkime, jums reikia surūšiuoti daugiamatę masyvą pagal sub-vertę, bet pagrindinius pakeitimus.

 <?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); ?> 

įspėjimas: nepažymėtas kodas (neturiu įdiegto php5.3 atminties), tačiau jis turėtų atrodyti panašus.

Yra vienas trūkumas: daugelis php kūrėjų gali būti šiek tiek bejėgiai, jei sugalvosite uždarymą.

daugiau suprasti, tuo daugiau uždarymo, duosiu jums dar vieną pavyzdį - šį kartą „JavaScript“. Viena iš problemų yra asinchroninė aprėptis ir būdinga naršyklei. ypač kai kalbama apie window.setTimeout(); (arba -interval). taigi, jūs perduodate funkciją setTimeout, bet negalite pateikti jokių parametrų, nes parametro atvaizdavimas atlieka kodą!

 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 grąžina funkciją su konkrečiu iš anksto nustatytu parametru!

Sąžiningai, man patinka php daug daugiau su 5.3 ir anoniminėmis funkcijomis / uždarymais. vardų erdvės gali būti svarbesnės, tačiau jos yra mažiau seksualios.

49
01 июля '09 в 0:38 2009-07-01 00:38 atsakymas pateikiamas stefs liepos 1 d., 09:38, 2009-07-01 00:38

function () use () {} yra PHP uždarymas, turite naudoti pagrindinio function kintamojo įgalinimą.

34
30 мая '15 в 17:45 2015-05-30 17:45 Atsakymą pateikė Steely Wing gegužės 30 d. 15 val. 17:45 2015-05-30 17:45

„Zupa“ atliko puikų darbą, paaiškindamas uždarymą naudojant „naudojimą“ ir skirtumą tarp „EarlyBinding“ ir nuorodos į „naudojamus“ kintamuosius.

Taigi, aš padariau pavyzdinį kodą su ankstyvuoju kintamuoju privalomuoju (= kopija):

 <?php $a = 1; $b = 2; $closureExampleEarlyBinding = function() use ($a, $b){ $a++; $b++; echo "Inside \$closureExampleEarlyBinding() \$a = ".$a."<br />"; echo "Inside \$closureExampleEarlyBinding() \$b = ".$b."<br />"; }; echo "Before executing \$closureExampleEarlyBinding() \$a = ".$a."<br />"; echo "Before executing \$closureExampleEarlyBinding() \$b = ".$b."<br />"; $closureExampleEarlyBinding(); echo "After executing \$closureExampleEarlyBinding() \$a = ".$a."<br />"; echo "After executing \$closureExampleEarlyBinding() \$b = ".$b."<br />";  ?> 

Pavyzdys su nuoroda į kintamąjį (pažymėkite „ simbolį prieš kintamąjį);

 <?php $a = 1; $b = 2; $closureExampleReferencing = function() use (  $a++; $b++; echo "Inside \$closureExampleReferencing() \$a = ".$a."<br />"; echo "Inside \$closureExampleReferencing() \$b = ".$b."<br />"; }; echo "Before executing \$closureExampleReferencing() \$a = ".$a."<br />"; echo "Before executing \$closureExampleReferencing() \$b = ".$b."<br />"; $closureExampleReferencing(); echo "After executing \$closureExampleReferencing() \$a = ".$a."<br />"; echo "After executing \$closureExampleReferencing() \$b = ".$b."<br />";  ?> 
11
17 марта '15 в 4:05 2015-03-17 04:05 Atsakymą davė joronimo kovo 17 d. 15 val. 04:05 2015-03-17 04:05

$tax ir $total yra getTotal () funkcijoje. Jame skambinate atgalinio ryšio funkcija. Todėl nereikia skambinti use .

0
26 июля '17 в 15:55 2017-07-26 15:55 atsakymą pateikė vartotojo8278407 liepos 26 d. 17:55 15:55 2017-07-26 15:55

Kiti klausimai apie žymes arba klausimo pateikimas