Модераторы: skyboy, MoLeX, Aliance, ksnk
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> foreach, кэшируется ли массив 
:(
    Опции темы
z-END
Дата 26.11.2012, 16:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прафесар™
****


Профиль
Группа: Комодератор
Сообщений: 3014
Регистрация: 13.3.2003
Где: Венья, Пиетари

Репутация: 5
Всего: 102



собственно изучая код, наткнулся на конструкцию такого вида:
Код

foreach (coresystem::get('accounts') as $account) 
....

и взгрыз меня вопрос - а кэшируется ли массив полученный из данной функции, или при каждой итерации форыча заново вызывается coresystem::get('accounts') ? 
сейчас на отдыхе и профайлера нет, но вопрос не дает покоя)))



--------------------
Каждый чилавек пасвоему праф...а памоему НЕТ! 

PM WWW ICQ   Вверх
Sanchezzz
Дата 26.11.2012, 23:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1670
Регистрация: 19.11.2006
Где: Voronezh

Репутация: 41
Всего: 60



скорее всего в память загоняет если нету указателя на переименую. затем при итерации сдвигает указатель возможно даже потихоньку освобождает память что я сомневаюсь. Но после выполнения цикла освобождается память почти вся у меня оставалось 168байт не освобожденных. 

Дебагером не прогонял ручками замер сделал.



--------------------
Понравился ответ "+" по репе, не забываем закрывать тему, заказы в LS.
PM MAIL Skype GTalk   Вверх
Arantir
Дата 26.11.2012, 23:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Рыбак без удочки
**


Профиль
Группа: Участник
Сообщений: 960
Регистрация: 18.11.2012

Репутация: 16
Всего: 55



Тоже заинтриговало =)
Код

$test = array(0, 1, 2, 3, 4, 5);
function get()
{
    global $test;
    echo "array was got\n";
    return $test;
}
foreach(get() as $t)
{
    echo $t." ";
}

И результат!
Код

array was got
0 1 2 3 4 5



--------------------
interface Жопа {
    // ATTENTION: has to be implemented by every class of the project for proper project work
}
PM   Вверх
z-END
Дата 27.11.2012, 10:35 (ссылка)    | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


прафесар™
****


Профиль
Группа: Комодератор
Сообщений: 3014
Регистрация: 13.3.2003
Где: Венья, Пиетари

Репутация: 5
Всего: 102



Arantir, не совсем по моему вопросу.
я говорил о том, что например в функции get результат -каждый раз новый массив.
например так:
Код

function get() {
    return array(rand(1,100), rand(100,200), rand(200,300), rand(300,400));
}



--------------------
Каждый чилавек пасвоему праф...а памоему НЕТ! 

PM WWW ICQ   Вверх
Fortop
Дата 27.11.2012, 14:22 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2200
Регистрация: 13.11.2007
Где: Донецк

Репутация: 20
Всего: 42



z-END, внимательнее разберите код Arantir


--------------------
Мир это Я.
Живее всех живых.
PM MAIL   Вверх
baldina
Дата 27.11.2012, 16:35 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 26
Всего: 101



по определению
Цитата

оператор foreach опирается на внутренний указатель массива

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

для примера рассмотрите 
Код

foreach (array(1, 2, 3, 4) as $value) {
    ...
}


coresystem::get('accounts') однократно возвращает массив, foreach использует ссылку на него

ЗЫ:
если бы 
Цитата(z-END @  26.11.2012,  16:58 Найти цитируемый пост)
при каждой итерации форыча заново вызывается coresystem::get('accounts')

то это  get должен был бы иметь внутреннее состояние, не так ли smile

Цитата(z-END @  27.11.2012,  10:35 Найти цитируемый пост)
 в функции get результат -каждый раз новый массив.
например так:

ваши rand() вызовутся один раз, в момент создания массива.
если нужен ленивый массив, можете создать свой Iterator. 

 smile 
летом дискутировался вопрос о включении в php генераторов с поддержкой yeld (т.е. сопрограмм)
https://wiki.php.net/rfc/generators
PM MAIL   Вверх
Arantir
Дата 27.11.2012, 18:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Рыбак без удочки
**


Профиль
Группа: Участник
Сообщений: 960
Регистрация: 18.11.2012

Репутация: 16
Всего: 55



z-END, как раз по вашему вопросу =) Функция get() вызывается всего один раз, что видно из моего примера. И какой бы разный массив там не был, вы получите только первый.
Ну могу для наглядности немного изменить код:
Код
$test = array(0, 1, 2, 3, 4, 5);
function get($c)
{
    global $test;
    echo "array was got with code '$c'\n";
    return $test;
}
$c = 0;
foreach(get($c) as $t)
{
    $c = $t;
    echo $t." ";
}

Код

array was got with code '0'
0 1 2 3 4 5


Я вам даже еще более интересный пример приведу, который полностью подтверждает слова baldina
Код

$test = array(0, 1, 2, 3, 4, 5);
foreach($test as $t)
{
    $test[] = $t;
    echo $t." ";
}
echo "\n";
foreach($test as $t)
{
    $test[] = $t;
    echo $t." ";
}
echo "\n";
foreach($test as $t)
{
    $test[] = $t;
    echo $t." ";
}

Код

0 1 2 3 4 5 
0 1 2 3 4 5 0 1 2 3 4 5 
0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 


Ну и напоследок:
Код

$test = array(0, 1, 2, 3, 4, 5);
foreach($test as $t)
{
    $test[5] = 'Hello';
    echo $t." ";
}
echo "\n";
foreach($test as $t)
{
    $test[4] = 'Hello';
    echo $t." ";
}
echo "\n";
foreach($test as $t)
{
    $test[3] = 'Hello';
    echo $t." ";
}

Код

0 1 2 3 4 5 
0 1 2 3 4 Hello 
0 1 2 3 Hello Hello 


foreach не использует даже тот массив, который в нем задан непосредственно. Он использует копию этого массива. Вот так вот.

Это сообщение отредактировал(а) Arantir - 27.11.2012, 18:29


--------------------
interface Жопа {
    // ATTENTION: has to be implemented by every class of the project for proper project work
}
PM   Вверх
skyboy
Дата 27.11.2012, 19:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 75
Всего: 260



Цитата(Arantir @  27.11.2012,  17:19 Найти цитируемый пост)
Он использует копию этого массива

копия — ленивая. только при изменении элемента. именно поэтому можно изменять исходный массив при помощи ссылки:
Код

foreach($arr as &$el) {
$el *= 2;
}

PM MAIL   Вверх
baldina
Дата 27.11.2012, 19:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 26
Всего: 101



Цитата(Arantir @  27.11.2012,  18:19 Найти цитируемый пост)
foreach не использует даже тот массив, который в нем задан непосредственно. Он использует копию этого массива. 

это потому что у массива есть состояние - внутренний указатель на текущий элемент, используемый foreach
иначе такой код не смог бы работать
Код

$a = array(1,2,3);
foreach ($a as $x) {
  foreach ($a as $y) {
    echo $x, $y, ' ';
  }
}


Добавлено через 2 минуты и 19 секунд
Цитата(skyboy @  27.11.2012,  19:15 Найти цитируемый пост)
копия — ленивая. 

не совсем  smile 
иначе не смог бы работать код
Код

$a = array(1,2,3);
foreach ($a as &$x) {
  foreach ($a as &$y) {
    ++$x; ++$y;
  }
}


Добавлено через 7 минут и 20 секунд
skyboy, примеры у нас одинаковые, видимо вы имели в виду не ленивое, а неполное копирование.
PM MAIL   Вверх
skyboy
Дата 27.11.2012, 19:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 75
Всего: 260



Цитата(baldina @  27.11.2012,  18:22 Найти цитируемый пост)
видимо вы имели в виду не ленивое

не знаю, с чего я вообще ленивое копирование взял. спишем на шумы в голове smile
PM MAIL   Вверх
MoLeX
Дата 28.11.2012, 05:21 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Местный пингвин
****


Профиль
Группа: Модератор
Сообщений: 4076
Регистрация: 17.5.2007

Репутация: 46
Всего: 140



 smile 
Ну наконец-то хоть какое-то интересное обсуждение, а не тысяча вопросов о том как воспользоваться стандартной ф-цией


--------------------
Amazing  smile 
PM MAIL WWW ICQ   Вверх
Sanchezzz
Дата 28.11.2012, 06:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1670
Регистрация: 19.11.2006
Где: Voronezh

Репутация: 41
Всего: 60



 smile  угу некоторые вопросы изрян вот тупые(


--------------------
Понравился ответ "+" по репе, не забываем закрывать тему, заказы в LS.
PM MAIL Skype GTalk   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "PHP"
Aliance
IZ@TOP
skyboy
SamDark
MoLeX

Новичкам:

  • PHP редакторы собираются и обсуждаются здесь
  • Электронные книги по PHP, документацию можно найти здесь
  • Интерпретатор PHP, полную документацию можно скачать на PHP.NET

Важно:

  • Не брезгуйте пользоваться тегами [code=php]КОД[/code] для повышения читабельности текста/кода.
  • Перед созданием новой темы воспользуйтесь поиском и загляните в FAQ
  • Действия модераторов можно обсудить здесь

Внимание:

  • Темы "ищу скрипт", "подскажите скрипт" и т.п. будут переноситься в форум "Web-технологии"
  • Темы с именами: "Срочно", "помогите", "не знаю как делать" будут УДАЛЯТЬСЯ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, IZ@TOP, skyboy, SamDark, MoLeX, awers.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | PHP: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0945 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.