Есть ли способ передать массив, как список аргументов, в функцию?
Она получает, в качестве аргументов, некоторое число массивов, первый из которых содержит данные для сравнения, а второй и последующие проверяются на наличие в них совпадений. Есть игровое поле 10×10 клеток, данные о котором хранятся в соответствующем двухмерном массиве. Мне требуется посчитать, сколько клеток определённого типа есть на всём поле. Функция предполагалась как универсальная, для подсчёта количества совпадений в любом массиве, и переписывать её для проверки массива двухмерного мне не очень хочется. Очевидное решение состоит в том, что бы переписать функцию для получения ею двух массивов, второй из которых будет содержать массивы для проверки, или ввести ещё один обязательный аргумент, содержащий указание глубины погружения, но я не уверен, что это — оптимальный вариант. Поэтому вопрос: Нет ли способа передать все элементы массива в функцию, в качестве независимых аргументов? Есть функция list() , но она просто превратит массив из десяти элементов в десять отдельных переменных, которые всё равно придётся передавать функции вручную, как и если бы я просто перечислил все элементы массива. Хотелось бы что-то более элегантное, тем более, что я почти уверен, что такое решение есть, просто я его не нашёл.
Как передать массив в функцию php
To experiment on performance of pass-by-reference and pass-by-value, I used this script. Conclusions are below.
#!/usr/bin/php
function sum ( $array , $max ) < //For Reference, use: "&$array"
$sum = 0 ;
for ( $i = 0 ; $i < 2 ; $i ++)#$array[$i]++; //Uncomment this line to modify the array within the function.
$sum += $array [ $i ];
>
return ( $sum );
>
$max = 1E7 //10 M data points.
$data = range ( 0 , $max , 1 );
$start = microtime ( true );
for ( $x = 0 ; $x < 100 ; $x ++)$sum = sum ( $data , $max );
>
$end = microtime ( true );
echo «Time: » .( $end — $start ). » s\n» ;
/* Run times:
# PASS BY MODIFIED? Time
— ——- ——— —-
1 value no 56 us
2 reference no 58 us
3 valuue yes 129 s
4 reference yes 66 us
1. PHP is already smart about zero-copy / copy-on-write. A function call does NOT copy the data unless it needs to; the data is
only copied on write. That’s why #1 and #2 take similar times, whereas #3 takes 2 million times longer than #4.
[You never need to use &$array to ask the compiler to do a zero-copy optimisation; it can work that out for itself.]
2. You do use &$array to tell the compiler «it is OK for the function to over-write my argument in place, I don’t need the original
any more.» This can make a huge difference to performance when we have large amounts of memory to copy.
(This is the only way it is done in C, arrays are always passed as pointers)
3. The other use of & is as a way to specify where data should be *returned*. (e.g. as used by exec() ).
(This is a C-like way of passing pointers for outputs, whereas PHP functions normally return complex types, or multiple answers
in an array)
5. Sometimes, pass by reference could be at the choice of the caller, NOT the function definitition. PHP doesn’t allow it, but it
would be meaningful for the caller to decide to pass data in as a reference. i.e. «I’m done with the variable, it’s OK to stomp
on it in memory».
*/
?>
Копируются ли массивы в PHP как значения или как ссылки на новые переменные при передаче в функции
1) Когда массив передается в качестве аргумента методу или функции, он передается по ссылке или по значению?
2) Когда массив присваивается переменной, является ли новая переменная ссылкой на исходный массив, или это новая копия?
А если сделать следующее:
$a = array(1,2,3);
$b = $a;
Является ли $b ссылкой на $a?
Ответ 1
Что касается второй части вашего вопроса — обратитесь к странице руководства, посвященной массивам, где говорится (цитирую):
Присвоение массива всегда включает копирование значения. Для копирования массива по ссылке используйте оператор ссылки.
А в приведенном примере:
$arr1 = array(2, 3);
$arr2 = $arr1;
$arr2[] = 4; // $arr2 изменяется,
// $arr1 все еще массив(2, 3)
$arr3 = &$arr1;
$arr3[] = 4; // теперь $arr1 и $arr3 одинаковы
?>
Что касается первой части, то лучший способ определить — попробовать 😉
Рассмотрим этот пример кода:
function my_func($a)
$a[] = 30;
>
$arr = array(10, 20);
my_func($arr);
var_dump($arr);
Это даст следующий результат:
array
0 => int 10
1 => int 20
Это указывает на то, что функция не модифицировала «внешний» массив, который был передан в качестве параметра: он передан как копия, а не как ссылка. Если вы хотите, чтобы он передавался по ссылке, вам придется модифицировать функцию таким образом:
function my_func(& $a)
$a[] = 30;
>
И на выходе получится:
array
0 => int 10
1 => int 20
2 => int 30
поскольку на этот раз массив был передан «по ссылке». Не поленитесь прочитать раздел руководства «Объяснение ссылок», он должен ответить на некоторые из ваших вопросов.
Ответ 2
Что касается вашего первого вопроса : массив передается по ссылке, пока он не изменен в методе/функции, которую вы вызываете. Если вы пытаетесь изменить массив внутри метода/функции, сначала создается его копия, а затем изменяется только копия. Это создает впечатление, что массив передается по значению, хотя на самом деле это не так.
Например, в первом случае, несмотря на то, что вы не определяете свою функцию как принимающую $my_array по ссылке (используя символ & в определении параметра), он все равно передается по ссылке (т . е . вы не тратите память на ненужную копию).
function handle_array($my_array)
// . читать, но не изменять $my_array
print_r($my_array);
// . $my_array фактически передается по ссылке, поскольку копия не создается
>
Однако если вы изменяете массив, сначала создается его копия (что использует больше памяти, но не затрагивает исходный массив).
function handle_array($my_array)
// . изменяем $my_array
$my_array[] = «New value»;
// . $my_array эффективно передается по значению, так как требует локальной копии
>
К сведению, это известно как «ленивое копирование» или «копирование при записи».
Ответ 3
a) метод/функция только читает аргумент массива => неявная (внутренняя) ссылка
b) метод/функция изменяет аргумент массива => значение
c) аргумент массива метода/функции явно помечен как ссылка (амперсандом) => явная (пользовательская) ссылка
Или так:
— неамперсандный массив param: передается по ссылке; операции записи изменяют новую копию массива, копия, которая создается при первой записи;
— амперсандный массив param: передается по ссылке; операции записи изменяют исходный массив.
Помните : PHP выполняет копирование значения в тот момент, когда вы пишете в неамперсандный массив param. Вот что означает копирование при записи. Я бы с радостью показал вам исходник этого поведения на C, но там все очень страшно. Лучше используйте xdebug_debug_zval().
Ответ
Зависит от ситуации.
Длинная версия
Всякий раз, когда люди говорят о ссылках (или указателях, если на то пошло), они обычно попадают в «магию» (только посмотрите на эту тему!).
Как вы увидите, вся эта штука с « по значению/по ссылке » очень сильно связана с тем, что именно вы делаете с этим массивом в области видимости вашего метода/функции: читаете его или изменяете .
Что говорится в руководстве PHP?
По умолчанию аргументы функции передаются по значению (так что если значение аргумента внутри функции изменено, оно не будет изменено вне функции). Чтобы функция могла изменять свои аргументы, они должны передаваться по ссылке.
Чтобы аргумент функции всегда передавался по ссылке, добавьте амперсанд (&) к имени аргумента в определении функции. Насколько я могу судить, когда серьезные программисты говорят о ссылках, они обычно говорят об изменении значения этой ссылки. И это именно то, о чем говорится в руководстве: если вы хотите ИЗМЕНИТЬ значение в функции, считайте, что PHP делает « передачу по значению » .
Однако есть еще один случай, о котором они не упоминают: что если я ничего не меняю , только читаю?
Что если вы передаете массив методу, который явно не помечает ссылку, и мы не изменяем этот массив в области видимости функции? Например:
function readAndDoStuffWithAnArray($array)
return $array[0] + $array[1] + $array[2];
>
$x = array(1, 2, 3);
echo readAndDoStuffWithAnArray($x);
Что на самом деле делает PHP? («с точки зрения памяти»)
Те же программисты, когда становятся еще более серьезными, говорят об « оптимизации памяти » в отношении ссылок. Так же поступает и PHP. Потому что PHP — динамический, слабо типизированный язык, использующий копирование при записи и подсчет ссылок, вот почему. Было бы расточительным передавать огромные массивы различным функциям, а PHP создавать их копии (в конце концов, именно это и делает « передача по значению » ):
// заполнение массива с 10000 элементами int 1
// допустим, это займет 3 мб вашей оперативной памяти
$x = array_fill(0, 10000, 1);
// Передача по значению, верно? ПРАВИЛЬНО?
function readArray($arr) < //
echo count($arr); // просто прочитаем массив
>
readArray($x);
Теперь, если бы это действительно было передачей по значению, мы бы потеряли 3 Мб ОЗУ, потому что есть две копии этого массива, верно?
Неверно. До тех пор, пока мы не изменим переменную $arr, это ссылка, с точки зрения памяти. Вы просто не видите ее. Вот почему PHP упоминает пользовательские ссылки, когда говорит о &$someVar, чтобы отличить внутренние и явные переменные (с амперсандом).
Факты
Итак, когда массив передается в качестве аргумента методу или функции, передается ли он по ссылке?
Я знаю три случая:
a) метод/функция только считывает аргумент массива ;
b) метод/функция изменяет аргумент массива ;
c) аргумент массива метода/функции явно помечен как ссылка (амперсандом).
Во-первых, давайте посмотрим, сколько памяти на самом деле занимает этот массив:
$start_memory = memory_get_usage();
$x = array_fill(0, 10000, 1);
echo memory_get_usage() — $start_memory; // 1331840
a) метод/функция читает только аргумент массива
Теперь сделаем функцию, которая читает только указанный массив в качестве аргумента, и посмотрим, сколько памяти занимает логика чтения:
function printUsedMemory($arr)
$start_memory = memory_get_usage();
count($arr); // чтение
$x = $arr[0]; // чтение (+второстепенная операция)
$arr[0] — $arr[1]; // чтение
echo memory_get_usage() — $start_memory; // посмотрим, сколько памяти используется во время чтения
>
$x = array_fill(0, 10000, 1); // 1331840 байт
printUsedMemory($x);
У меня 80. Это та часть, которую руководство PHP опускает. Если бы параметр $arr действительно передавался по значению, вы бы увидели что-то похожее на 1331840 байт. Кажется, что $arr ведет себя как ссылка, не так ли? Потому что это и есть ссылка — внутренняя.
б) метод/функция изменяет аргумент массива
Теперь давайте запишем в этот параметр, вместо того чтобы читать из него:
function printUsedMemory($arr)
$start_memory = memory_get_usage();
$arr[0] = 1; // WRITE!
echo memory_get_usage() — $start_memory; // посмотрим, сколько памяти используется во время чтения
>
$x = array_fill(0, 10000, 1);
printUsedMemory($x);
Опять же, для меня это довольно близко к 1331840. Так что в этом случае массив действительно копируется в $arr.
c) аргумент массива метода/функции явно помечен как ссылка (амперсандом)
Теперь посмотрим, сколько памяти занимает операция записи в явную ссылку — обратите внимание на амперсанд в сигнатуре функции:
function printUsedMemory(&$arr)
// явный, пользовательский, передаваемый по ссылке
$start_memory = memory_get_usage();
$arr[0] = 1; // WRITE!
echo memory_get_usage() — $start_memory; // посмотрим, сколько памяти используется во время чтения
>
$x = array_fill(0, 10000, 1);
printUsedMemory($x);
Таким образом, это съедает примерно столько же памяти, сколько чтение из параметра без амперсанда.
Ответ 4
- Примитивы передаются по значению. В отличие от Java, строка является примитивом в PHP .
- Массивы примитивов передаются по значению .
- Объекты передаются по ссылке .
- Массивы объектов передаются по значению, но каждый объект передается по ссылке.
Ответ 5
Когда массив передается методу или функции в PHP, он передается по значению, если вы явно не передаете его по ссылке, как, например, в этом случае:
function test(&$array)
$array[‘new’] = ‘hey’;
>
$a = $array(1,2,3);
// prints [0=>1,1=>2,2=>3]
var_dump($a);
test($a);
// prints [0=>1,1=>2,2=>3,’new’=>’hey’]
var_dump($a);
Во втором вопросе $b — это не ссылка на $a, а копия $a. Как и в первом примере, вы можете сослаться на $a, сделав следующее:
$a = array(1,2,3);
$b = &$a;
// prints [0=>1,1=>2,2=>3]
var_dump($b);
$b[‘new’] = ‘hey’;
// prints [0=>1,1=>2,2=>3,’new’=>’hey’]
var_dump($a);
Ответ 6
Чтобы расширить один из ответов : также подмассивы многомерных массивов передаются по значению, если только они не передаются явно по ссылке.
$foo = array( array(1,2,3), 22, 33);
function hello($fooarg)
$fooarg[0][0] = 99;
>
function world(&$fooarg)
$fooarg[0][0] = 66;
>
hello($foo);
var_dump($foo); // (исходный массив не изменен) массив передан по значению
world($foo);
var_dump($foo); // (исходный массив изменен) массив передан по ссылке
В результате:
array(3)
[0] => array(3)
[0] => int(1)
[1] => int(2)
[2] => int(3)
>
[1] => int(22)
[2] => int(33)
>
array(3)
[0] => array(3)
[0] => int(66)
[1] => int(2)
[2] => int(3)
>
[1] => int(22)
[2] => int(33)
>
Ответ 7
Попробуйте этот код:
$date = new DateTime();
$arr = [‘date’ => $date];
echo $date->format(‘Ymd’) . ‘
‘;
mytest($arr);
echo $date->format(‘Ymd’) . ‘
‘;
function mytest($params = [])
if (isset($params[‘date’]))
$params[‘date’]->add(new DateInterval(‘P1D’));
Обратите внимание, что нет амперсанда для параметра $params, и все равно он изменяет значение $arr[‘date’]. Это не совсем соответствует всем другим объяснениям здесь и тому, что я думал до сих пор. Если я клонирую объект $params[‘date’], вторая выводимая дата остается неизменной. Если я просто установлю ее в строку, это также не повлияет на вывод.
Мы будем очень благодарны
если под понравившемся материалом Вы нажмёте одну из кнопок социальных сетей и поделитесь с друзьями.
Передать массив в функцию
Передать массив параметров в функцию
Доброго времени суток Столкнулся с такой проблемой Есть Функция: $new_image =.
Как передать переменную (массив) в функцию?
У меня с этим PHP уже реально крыша отъезжает. Я-то привык, что во всех известных мне языках.
Передать массив d JS-функцию
Здравствуйте. Есть два массива $A и $B. Нужно что бы при клике на элемент массива А, выводился.
4885 / 3887 / 1611
Регистрация: 24.04.2014
Сообщений: 11,384
arrayFunc($arr);
Заблокирован

Сообщение было отмечено Памирыч как решение
Решение
Позволю себе несколько развернуть ответ, а то я когда сам учил это дело, не сразу догнал из за одинаковых имён.
1 2 3 4 5 6
function arrayFunc($arr) { print_r($arr); } $ljuboj_massiv = array(1 => 'one', 2 => 'two'); arrayFunc($ljuboj_massiv);
669 / 640 / 335
Регистрация: 26.04.2014
Сообщений: 2,122
Может быть лучше переменную назвать не $ljuboj_massiv, а, например $any_array или $another_array?
А то как-то не смотрится, там one, to, а здесь русский транслит. Тогда уж odin, dva.
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
Помогаю со студенческими работами здесь
Передать переменные в функцию
Здравствуйте. Есть сценарий: function template($tpl, $template) .
Передать параметр во вложенную функцию
как из объекта, можно передать параметр в вложенную функцию? public function fn1()< function.
Передать переменную из php в функцию js
Прошу помочь, кто разбирается. Суть есть переменная $Pobn которая получается так:$Pobn =.
передать выбранный option в функцию
привет! имеется 3 select’a,второй получает контент ответом на пост запрос исходя из первого,третий.
