2010-12-29 3 views
12

В чем разница между

foreach ($my_array as $my_value) { 
} 

И:

foreach ($my_array as &$my_value) { 
} 

?

Могу ли я попросить вас дать мне два реальных примера, когда их использовать, а когда вы используете другой?

+1

Как правило, никогда не используйте ссылки. – troelskn

+4

@troelskn: Это глупое правило. Иногда вам приходится их использовать. Если вы не знаете, следует ли им их использовать, то, вероятно, вам этого не нужно. Но всякий раз, когда вы хотите изменить фактическое значение, вам нужно использовать ссылки. –

+0

@ Феликс Клинг: Я согласен с @troelskn. Мне никогда не приходилось изменять фактическое значение массива. Каждый раз, когда я должен был, вы можете сделать гораздо более приятный код, чем использовать ('& $ var'). Единственный способ, которым я могу думать, может быть ... оптимизация: если вы используете «&», я полагаю (исправьте меня, если я ошибаюсь), что нет необходимости делать копию во временную переменную. При этом увеличивается время выполнения. Если у вас есть пример, где вы не можете избегать циклов, подобных тому, что есть в вопросе «&», могу ли я попросить вас показать их в качестве комментария здесь? Большое спасибо! –

ответ

21

Первый пример создает копию значения, а второй использует ссылку на исходное значение. Итак, после первого запуска foreach исходный массив по-прежнему остается нетронутым. После второго foreach исходный массив мог быть изменен, так как он обрабатывался ссылкой.

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

$myArray = array('foo', 'bar', 'fizz', 'buzz'); 
shuffle($myArray); 
// $myArray is now shuffled 

И это работает его волшебство, так как он работает с массивом по ссылке, а не создавать его копию.

Тогда существуют функции, которые ничего не проходят по ссылке а имеют дело с копией исходного значения, такие как ucwords(), который возвращает новую результирующую строку:

$myString = "hello world"; 
$myString = ucwords($myString); 
// $myString is now capitalized 

См Passing by Reference.

+2

, если $ my_value является объектом, он неизбежно передается по ссылке. – Epharion

+1

@Epharion: Нет, PHP всегда проходит мимо val, если только ему не передано ref. И объекты не являются исключением из этого. Только с объектами pass by val выполняет очень похожее на pass by ref из-за того, как PHP хранит объекты;) – NikiC

5

Jonathan's answers описывает это очень хорошо. Просто для полноты картины, вот ваши два примера:

  1. Только чтение значения:

    $my_array = range(0,3); 
    foreach ($my_array as $my_value) { 
        echo $my_value . PHP_EOL; 
    } 
    
  2. Добавление некоторого числа к каждому элементу (таким образом модифицирующие каждое значение):

    foreach ($my_array as &$my_value) { 
        $my_value += 42; 
    } 
    

    Если вы не используете &$my_value, то добавление не будет влиять на $my_array. Но вы могли бы написать те же не с помощью ссылки:

    foreach($my_array as $key=>$value) { 
        $my_array[$key] = $value + 42; 
    } 
    

    Разница заключается в том, что мы доступа/изменения исходного значения непосредственно с $my_array[$key].

DEMO

+0

Большое спасибо, ваши примеры понятны как вода. –

0

Когда префикс переменной амперсанд, вы создаете «ссылку.» Ссылки PHP, как ярлыки или символические ссылки на вашем компьютере. Вы можете создать переменную указателя, которая является просто другим именем для одних и тех же данных.

Я не вижу большой разницы в их использовании, за исключением того, что вы НЕ ДОЛЖНЫ КОПИРОВАТЬ переменную, сохраняющую память. Когда вы передаете переменные, вы можете просто передать ссылку, а контрольные точки - на исходный объект.

+0

Типичная ошибка начинающего: думать, что PHP глуп. PHP не слепо копирует значения. Он использует концепцию копирования на запись, т. Е. Что значение копируется только при его изменении. Обычно создание ссылок по причинам производительности является только контрпродуктивным, потому что часто PHP вызывает только большее копирование. – NikiC

0

Реальный пример мира для & использования, когда вам нужно, чтобы изменить содержимое массива с очень несколько строк кода

foreach($arrFeed as &$objFeed) 
    $objFeed['externalSrc'] = convertToLocalImage($objFeed['externalSrc']); 
Смежные вопросы