Intereting Posts
Gettext не работает, никаких сообщений об ошибках, используя php 5.3 Сделать массив из формы флажка Запуск скрипта Python из PHP Преобразование значений разделенных запятыми значений в двойные кавычки Поиск последнего сообщения из таблицы, сгруппированного пользователем в mysql Как сайты, такие как геолокация сегмента Groupon, основаны на городах, в которых они имеют дело? Как вытащить друзей пользователя из Facebook (с v 2.0 Facebook Auth) Могу ли я поменять цвета в изображении с помощью библиотеки GD в PHP? Свяжитесь с нами по электронной почте не работает в codeigniter php PHP POST не работает Почему var_dump не работает с объектами DomDocument, а print ($ dom-> saveHTML ())? Backbone + RequireJS: файлы HTML, загруженные RequireJS, интерпретируются как файлы JS Удалить символы мусора в utf jquery – первый клик будет привязан ко всем элементам Почему переменные среды Python различаются при выполнении с веб-сервера?

Закрытие в PHP … что, собственно, они и когда вам нужно их использовать?

Поэтому я программирую в приятной, современной, объектно-ориентированной моде. Я регулярно использую различные аспекты ООП, которые реализует PHP, но мне интересно, когда мне нужно использовать закрытие. Любые эксперты, которые могут пролить свет на то, когда было бы полезно осуществить закрытие?

Related of "Закрытие в PHP … что, собственно, они и когда вам нужно их использовать?"

PHP будет поддерживать закрытие изначально в 5.3. Закрытие хорошо, когда вы хотите использовать локальную функцию, которая используется только для небольшой, конкретной цели. Примером может служить RFC для замыканий :

function replace_spaces ($text) { $replacement = function ($matches) { return str_replace ($matches[1], ' ', ' ').' '; }; return preg_replace_callback ('/( +) /', $replacement, $text); } 

Это позволяет локально определять функцию replacement внутри replace_spaces() , так что это не так:
1) Затухание глобального пространства имен
2) Заставляя людей на три года спуститься с пути, задайтесь вопросом, почему существует глобальная функция, которая используется только внутри одной функции

Он держит вещи организованными. Обратите внимание, как сама функция не имеет имени, она просто определяется и присваивается как ссылка на $replacement .

Но помните, вы должны ждать PHP 5.3 🙂

Когда вам понадобится функция в будущем, которая выполняет задание, которое вы решили сейчас.

Например, если вы читаете конфигурационный файл, и один из параметров говорит вам, что hash_method для вашего алгоритма multiply а не square , вы можете создать закрытие, которое будет использоваться везде, где вам нужно что-то делать.

Закрытие может быть создано в (например) config_parser() ; он создает функцию do_hash_method() используя переменные local для config_parser() (из файла конфигурации). Когда do_hash_method() , он имеет доступ к переменным в локальной области config_parser() даже если он не config_parser() в этой области.

Надеюсь, хороший гипотетический пример:

 function config_parser() { // Do some code here // $hash_method is in config_parser() local scope $hash_method = 'multiply'; if ($hashing_enabled) { function do_hash_method($var) { // $hash_method is from the parent's local scope if ($hash_method == 'multiply') return $var * $var; else return $var ^ $var; } } } function hashme($val) { // do_hash_method still knows about $hash_method // even though it's not in the local scope anymore $val = do_hash_method($val) } 

Помимо технических деталей, закрытие является фундаментальным предварительным условием для стиля программирования, называемого функционально-ориентированным программированием. Закрытие используется примерно так же, как вы используете объект для объектно-ориентированного программирования; Он связывает данные (переменные) вместе с некоторым кодом (функцией), который затем можно передать в другое место. Таким образом, они влияют на то, как вы пишете программы, или – если вы не меняете способ написания своих программ – они вообще не имеют никакого влияния.

В контексте PHP они немного странные, поскольку PHP уже тяжело относится к основанной на классе, объектно-ориентированной парадигме, а также к более старой процедурной. Обычно языки, имеющие закрытие, имеют полный лексический охват. Чтобы поддерживать обратную совместимость, PHP не получит этого, поэтому это означает, что закрытие здесь немного отличается, чем на других языках. Я думаю, нам еще предстоит увидеть, как они будут использоваться.

Мне нравится контекст, предоставленный сообщением troelskn. Когда я хочу сделать что-то вроде примера Дэн Удей в PHP, я использую шаблон стратегии OO. На мой взгляд, это намного лучше, чем введение новой глобальной функции, поведение которой определяется во время выполнения.

http://en.wikipedia.org/wiki/Strategy_pattern

Вы также можете вызывать функции и методы, используя переменную, содержащую имя метода в PHP, что отлично. так что другой пример Дэна будет примерно таким:

 class ConfigurableEncoder{ private $algorithm = 'multiply'; //default is multiply public function encode($x){ return call_user_func(array($this,$this->algorithm),$x); } public function multiply($x){ return $x * 5; } public function add($x){ return $x + 5; } public function setAlgorithm($algName){ switch(strtolower($algName)){ case 'add': $this->algorithm = 'add'; break; case 'multiply': //fall through default: //default is multiply $this->algorithm = 'multiply'; break; } } } $raw = 5; $encoder = new ConfigurableEncoder(); // set to multiply echo "raw: $raw\n"; // 5 echo "multiply: " . $encoder->encode($raw) . "\n"; // 25 $encoder->setAlgorithm('add'); echo "add: " . $encoder->encode($raw) . "\n"; // 10 

конечно, если вы хотите, чтобы он был доступен повсюду, вы могли бы просто сделать все статичным …

Закрытие – это в основном функция, для которой вы пишете определение в одном контексте, но выполняете его в другом контексте. Javascript помог мне с пониманием, потому что они используются в JavaScript повсюду.

В PHP они менее эффективны, чем в JavaScript, из-за различий в объеме и доступности «глобальных» (или «внешних») переменных изнутри функций. Тем не менее, начиная с PHP 5.4, закрытие может получить доступ к этому объекту при запуске внутри объекта, что делает их намного более эффективными.

Это то, что закрывает, и этого должно быть достаточно, чтобы понять, что написано выше.

Это означает, что нужно где-то написать определение функции и использовать переменную $ this в определении функции, затем назначить определение функции переменной (другие приводили примеры синтаксиса), затем передать эту переменную объекту и вызывать его в контексте объекта, функция может затем получить доступ и манипулировать объектом через $ this, как если бы это был просто еще один из его методов, когда на самом деле он не определен в определении класса этого объекта, а где-то еще.

Если это не очень понятно, тогда не беспокойтесь, это станет ясно, как только вы начнете их использовать.

Вот примеры закрытия в php

 // Author: HishamDalal@gamil.com // Publish on: 2017-08-28 class users { private $users = null; private $i = 5; function __construct(){ // Get users from database $this->users = array('a', 'b', 'c', 'd', 'e', 'f'); } function displayUsers($callback){ for($n=0; $n<=$this->i; $n++){ echo $callback($this->users[$n], $n); } } function showUsers($callback){ return $callback($this->users); } function getUserByID($id, $callback){ $user = isset($this->users[$id]) ? $this->users[$id] : null; return $callback($user); } } $u = new users(); $u->displayUsers(function($username, $userID){ echo "$userID -> $username<br>"; }); $u->showUsers(function($users){ foreach($users as $user){ echo strtoupper($user).' '; } }); $x = $u->getUserByID(2, function($user){ return "<h1>$user</h1>"; }); echo ($x); 

Вывод:

 0 -> a 1 -> b 2 -> c 3 -> d 4 -> e 5 -> f ABCDEF c