PHP Conference Japan 2024

array_walk

(PHP 4,PHP 5,PHP 7,PHP 8)

array_walk將使用者提供的函式應用到陣列的每個成員

描述

array_walk(array|object &$array, callable $callback, mixed $arg = null): true

將使用者定義的 callback 函式應用於 array 陣列的每個元素。

array_walk() 不受 array 的內部陣列指標影響。array_walk() 將會走訪整個陣列,而不管指標位置。

參數

array

輸入陣列。

callback

通常,callback 接受兩個參數。第一個參數是 array 參數的值,第二個參數是鍵/索引。

注意:

如果 callback 需要處理陣列的實際值,請將 callback 的第一個參數指定為參考。然後,對這些元素所做的任何更改都會在原始陣列本身中進行。

注意:

許多內部函式(例如 strtolower())如果傳入的參數超出預期數量,將會拋出警告,並且不能直接作為 callback 使用。

只能變更 array 的值;它的結構不能改變,也就是說,程式設計師不能新增、取消設置或重新排序元素。如果回呼不遵守此要求,則此函式的行為是未定義且無法預測的。

arg

如果提供了可選的 arg 參數,它將作為第三個參數傳遞給 callback

回傳值

總是回傳 true

錯誤/例外

從 PHP 7.1.0 開始,如果 callback 函式需要超過 2 個參數(陣列成員的值和鍵),或者如果也傳遞了 arg,則需要超過 3 個參數,將會拋出 ArgumentCountError。以前,在這種情況下,每次 array_walk() 呼叫 callback 時都會產生 E_WARNING 級別的錯誤。

更新日誌

版本 描述
8.2.0 回傳類型現在是 true;之前是 bool
8.0.0 如果 callback 期望第二個或第三個參數以參考方式傳遞,此函式現在會發出 E_WARNING

範例

範例 #1 array_walk() 範例

<?php
$fruits
= array("d" => "lemon", "a" => "orange", "b" => "banana", "c" => "apple");

function
test_alter(&$item1, $key, $prefix)
{
$item1 = "$prefix: $item1";
}

function
test_print($item2, $key)
{
echo
"$key. $item2\n";
}

echo
"Before ...:\n";
array_walk($fruits, 'test_print');

array_walk($fruits, 'test_alter', 'fruit');
echo
"... and after:\n";

array_walk($fruits, 'test_print');
?>

上面的範例會輸出

Before ...:
d. lemon
a. orange
b. banana
c. apple
... and after:
d. fruit: lemon
a. fruit: orange
b. fruit: banana
c. fruit: apple

範例 #2 使用匿名函式的 array_walk() 範例

<?php
$elements
= ['a', 'b', 'c'];

array_walk($elements, function ($value, $key) {
echo
"{$key} => {$value}\n";
});

?>

上面的範例會輸出

0 => a
1 => b
2 => c

參見

新增註解

使用者貢獻的註解 35 則註解

bisqwit at iki dot fi
20 年前
值得注意的是,array_walk 無法用於更改陣列中的鍵。
函式可以定義為 (&$value, $key) 而不是 (&$value, &$key)。
即使 PHP 沒有抱怨/警告,它也不會修改鍵。
ezhacher at gmail dot com
10 年前
在類別內部呼叫 array Walk

如果類別是靜態的
array_walk($array, array('self', 'walkFunction'));
或者
array_walk($array, array('className', 'walkFunction'));

否則
array_walk($array, array($this, 'walkFunction'));
01001coder at gmail dot com
6 年前
我注意到

當使用 array_walk() 時,即使有

declare(strict_types=1),PHP 還是會忽略參數類型。

請看以下程式碼範例...

<?php
declare(strict_types=1);

$fruits = array("butter" => 5.3, "meat" => 7, "banana" => 3);

function
test_print(int $item2, $key) {
echo
"$key: $item2<br />\n";
}

array_walk($fruits, 'test_print');

?>

輸出為

butter: 5
meat: 7
banana: 3

而期望的輸出是

Fatal error: Uncaught TypeError: Argument 1 passed to test_print() must be of the type integer

因為 "butter" => 5.3 是浮點數

我問了一些人,他們說「這是因為從內部程式碼呼叫的回呼函式總是使用弱型別」。但我嘗試做了一些測試,當使用 call_user_func() 時,這種行為並不是問題。
ludvig dot ericson at gmail dot com
19 年前
為了回應 'ibolmo',這是 string_walk 的擴展版本,允許傳遞使用者資料 (如 array_walk) 並讓函式以與 array_walk 相同的方式編輯字串。不過請注意,現在您必須傳遞變數,因為 PHP 無法通過參考傳遞字串字面值 (邏輯上)。

<?php
function string_walk(&$string, $funcname, $userdata = null) {
for(
$i = 0; $i < strlen($string); $i++) {
# 注意:PHP 的解引用很糟糕,我們必須這樣做。
$hack = $string{$i};
call_user_func($funcname, &$hack, $i, $userdata);
$string{$i} = $hack;
}
}

function
yourFunc($value, $position) {
echo
$value . ' ';
}

function
yourOtherFunc(&$value, $position) {
$value = str_rot13($value);
}

# 注意:我們現在需要這個醜陋的 $x = hack。
string_walk($x = 'interesting', 'yourFunc');
// 輸出:i n t e r e s t i n g

string_walk($x = 'interesting', 'yourOtherFunc');
echo
$x;
// 輸出:vagrerfgvat
?>

另請注意,直接在 $x 上呼叫 str_rot13() 會快得多 ;-) 這只是一個範例。
Maxim
13 年前
請注意,將 array_walk 與 intval 搭配使用是不適當的。
網路上有很多範例建議使用以下程式碼來安全地逸出 $_POST 整數陣列
<?php
array_walk
($_POST['something'],'intval'); // 在 PHP 5.3.3 中不起作用
?>
它在 _某些_ 較舊的 PHP 版本 (5.2) 中有效,但不符合規範。由於 intval() 不會修改它的參數,而是傳回修改後的結果,因此上面的程式碼對陣列沒有影響,並會在您的網站中留下安全漏洞。

您可以改用以下程式碼
<?php
$_POST
['something'] = array_map(intval,$_POST['something']);
?>
chaley at brtransport dot com
10 年前
大約 3 年前有一個關於將此用於修剪的註解。array_map() 可能更適合此用途。我還沒有檢查時間/資源影響

$result = array_map("trim", $array);
erelsgl at gmail dot com
15 年前
如果您想從回呼函式中取消設定元素,也許您真正需要的是 array_filter。
rustamabd at gmail dot com
14 年前
別忘了 array_map() 函式,它可能更容易使用!

以下是如何將陣列中的所有元素轉為小寫

<?php
$arr
= array_map('strtolower', $arr);
?>
fantomx1 at gmail dot com
8 年前
由於 array_walk 無法像之前提到的那樣修改/變更/重新索引鍵,我提供這個小小的包裝函式,它使用閉包和 "use" 關鍵字來實現傳遞陣列引用和索引。

function indexArrayByElement($array, $element)
{
$arrayReindexed = [];
array_walk(
$array,
function ($item, $key) use (&$arrayReindexed, $element) {
$arrayReindexed[$item[$element]] = $item;
}
);
return $arrayReindexed;
}
alex_stanhope at hotmail dot com
13 年前
我想走訪一個陣列並將其反向對應到第二個陣列。我決定使用 array_walk,因為它應該比 reset、next 迴圈或 foreach(x as &$y) 迴圈更快。

<?php
$output
= array();
array_walk($input, 'gmapmark_reverse', $output);

function
gmapmark_reverse(&$item, $index, &$target) {
$target[$item['form_key']] = $index;
}
?>

在我的偵錯器中,我可以看到 $target 會逐步更新,但是當 array_walk 返回時,$output 是空的。但是,如果我使用(已棄用的)傳址呼叫

<?php
array_walk
($input, 'gmapmark_reverse', &$output);
?>

$output 會正確傳回。不幸的是,沒有簡單的方法可以抑制警告

<?php
@array_walk($input, 'gmapmark_reverse', &$output);
?>

不會讓它們靜音。我已經設計了一個使用靜態陣列的解決方法

<?php
$reverse
= array();
array_walk($input, 'gmapmark_reverse');
// 最後一次呼叫函式以取得目標陣列,因為參數不起作用
$reverse = gmapmark_reverse($reverse);

function
gmapmark_reverse(&$item, $index = 0) {
static
$target;
if (!
$target) {
$target = array();
}
if (isset(
$item['form_key'])) {
$target[$item['form_key']] = $index;
}
return(
$target);
}
?>
Andrzej Martynowicz at gmail dot com
19 年前
在回呼函式中永久修改第三個(可選)參數並通過引用傳遞,可能會非常有用。這會導致將修改後的參數傳遞給 array_walk() 的下一次迭代。下面的範例列舉了陣列中的項目

<?php
function enumerate( &$item1, $key, &$startNum ) {
$item1 = $startNum++ ." $item1";
}

$num = 1;

$fruits = array( "lemon", "orange", "banana", "apple");
array_walk($fruits, 'enumerate', $num );

print_r( $fruits );

echo
'$num is: '. $num ."\n";
?>

這會輸出

Array
(
[0] => 1 lemon
[1] => 2 orange
[2] => 3 banana
[3] => 4 apple
)
$num is: 1

請注意,在輸出的最後一行,在 array_walk() 之外,$num 參數的初始值為 1。這是因為 array_walk() 並非通過引用來取得第三個參數。那麼如果我們將引用作為可選參數傳遞會怎樣呢?

<?php
$num
= 1;

$fruits = array( "lemon", "orange", "banana", "apple");
array_walk($fruits, 'enumerate', &$num ); // 此處為引用

print_r( $fruits );

echo
'$num is: '. $num ."\n";
echo
"we've got ". ($num - 1) ." fruits in the basket!";
?>

這會輸出
Array
(
[0] => 1 lemon
[1] => 2 orange
[2] => 3 banana
[3] => 4 apple
)
$num is: 5
we've got 4 fruits in the basket!

現在 $num 已經更改,因此我們能夠計算項目數量(而無需不必要地呼叫 count())。

總之,將引用與 array_walk() 搭配使用可能是一個強大的工具,但應謹慎操作,因為在 array_walk() 之外修改第三個參數並不總是我們想要的。
taj at yahoo dot fr
5 年前
// 我們可以使用這個簡單的 FOREACH 迴圈來做到這一點

$fruits = array("d" => "lemon", "a" => "orange", "b" => "banana", "c" => "apple");

foreach($fruits as $cls => $vls)
{
$fruits[$cls] = "fruit: ".$vls;
}

結果

Array
(
[d] => fruit: lemon
[a] => fruit: orange
[b] => fruit: banana
[c] => fruit: apple
)
EllisGL
6 年前
對於那些認為不能使用 array_walk 來更改/取代鍵名的人,這裡有一個範例

<?php
function array_explore(array &$array, callable $callback)
{
array_walk($array, function(&$value, $key) use (&$array, $callback)
{
$callback($array, $key, $value);

if(
is_array($value))
{
array_explore($value, $callback);
}
});
}

/**
* 竊取自: https://stackoverflow.com/questions/13233405/change-key-in-associative-array-in-php
*/
function renameKey(array &$data, $oldKey, $newKey, $ignoreMissing = false, $replaceExisting = false)
{
if (!empty(
$data))
{
if (!
array_key_exists($oldKey, $data))
{
if (
$ignoreMissing)
{
return
FALSE;
}

throw new
\Exception('舊鍵不存在。');
}
else
{
if (
array_key_exists($newKey, $data))
{
if (
$replaceExisting)
{
unset(
$data[$newKey]);
}
else
{
throw new
\Exception('新鍵已存在。');
}
}

$keys = array_keys($data);

// EllisGL 的修復:https://php.dev.org.tw/manual/en/function.array-search.php#122377
$keys[array_search($oldKey, array_map('strval', $keys))] = $newKey;

$data = array_combine($keys, $data);

return
TRUE;
}
}

return
FALSE;
}

$array = [
"_10fish" => 'xyz',
"_11fish" => [
"_22" => "a", "b", "c"
],
"someFish" => [
'xyz',
'@attributes' => ['type' => 'cod']
]
];

array_explore($array, function(&$value, $key)
{
// 將鍵 '@attrutes' 替換為 '_attributes'
if('@attributes' === $key)
{
renameKey($value, $key, '_attributes');
}

});

print_r($array);
?>
matthew at codenaked dot org
14 年前
使用 Lambda,您可以建立一個方便的 zip 函式,將陣列的鍵和值壓縮在一起。我擴展了它,允許您將「膠水」字串作為可選的使用者資料參數傳遞。以下範例用於壓縮電子郵件標頭陣列

<?php

/**
* 使用提供的膠合字串將陣列的鍵和值壓縮在一起
*
* 陣列的值會被新的計算值取代
*
* @param array $data
* @param string $glue
*/
function zip(&$data, $glue=': ')
{
if(!
is_array($data)) {
throw new
InvalidArgumentException('第一個參數必須是陣列');
}

array_walk($data, function(&$value, $key, $joinUsing) {
$value = $key . $joinUsing . $value;
},
$glue);
}

$myName = 'Matthew Purdon';
$myEmail = 'matthew@example.com';
$from = "$myName <$myEmail>";

$headers['From'] = $from;
$headers['Reply-To'] = $from;
$headers['Return-path'] = "<$myEmail>";
$headers['X-Mailer'] = "PHP" . phpversion() . "";
$headers['Content-Type'] = 'text/plain; charset="UTF-8"';

zip($headers);

$headers = implode("\n", $headers);
$headers .= "\n";

echo
$headers;

/*
From: Matthew Purdon <matthew@example.com>
Reply-To: Matthew Purdon <matthew@example.com>
Return-path: <matthew@example.com>
X-Mailer: PHP5.3.2
Content-Type: text/plain; charset="UTF-8"
*/
?>
brian at access9 dot net
11 年前
array_walk 不適用於 SplFixedArray 物件
<?php
$array
= new SplFixedArray(2);
$array[0] = 'test_1';
$array[1] = 'test_2';

array_walk($array, function(&$val){
$val .= '__';
return
$val;
});
foreach (
$array as $a) {
echo
"$a\n";
}
?>

結果是
test_1
test_2
zlobnygrif at gmail dot com
11 年前
一些速度測試

<?php
// 測試結果
$array1 = test('array_walk');
$array2 = test('array_walk_list_each');
$array3 = test('array_walk_foreach1');
$array4 = test('array_walk_foreach2');

// 檢查陣列是否相等
var_dump($array1 == $array2, $array1 == $array3, $array1 == $array4);

// 測試函式 1
function array_walk_list_each(&$array, $function, $userData = null) {
while ( list(
$key, $value) = each($array) )
$function($array[$key], $key, $userData);
}

// 測試函式 2
function array_walk_foreach1(&$array, $function, $userData = null) {
foreach (
$array as $key => &$value )
$function($value, $key, $userData);
}

// 測試函式 3
function array_walk_foreach2(&$array, $function, $userData = null) {
foreach (
$array as $key => $value )
$function($array[$key], $key, $userData);
}

function
some_function(&$value, $key, $userData) {
$value = "$key => $userData";
}

function
test($function, $count = 10000, $arrayElements = 1000) {
echo
$function, ' ... ';
$array = array_fill(0, $arrayElements, "一些文字值");

$timer = microtime(true);
for(
$i = 0; ++$i < $count; )
$function($array, 'some_function', '一些使用者資料');
printf("%.3f 秒\n", microtime(true) - $timer);

return
$array;
}
?>

輸出 (PHP 5.4.9-4ubuntu2.2 (cli) (建置於:2013 年 7 月 15 日 18:24:39))
=========================
array_walk ... 13.572 秒
array_walk_list_each ... 0.027 秒
array_walk_foreach1 ... 15.356 秒
array_walk_foreach2 ... 17.416 秒
bool(true)
bool(true)
bool(true)

輸出 (PHP 5.5.0 (cli) (建置於:2013 年 7 月 16 日 17:59:42) - 同一台伺服器)
=========================
array_walk ... 4.776 秒
array_walk_list_each ... 0.006 秒
array_walk_foreach1 ... 4.482 秒
array_walk_foreach2 ... 5.166 秒
bool(true)
bool(true)
bool(true)

PHP 5.5 的 array_walk 看起來還不錯,但 list each 越來越快...
fred
8 年前
更正 zlobnygrif 的速度測試。

<?php
// 測試結果
$array1 = test('array_walk');
$array2 = test('array_walk_list_each');
$array3 = test('array_walk_foreach1');
$array4 = test('array_walk_foreach2');

// 檢查陣列是否相等
var_dump($array1 == $array2, $array1 == $array3, $array1 == $array4);

// 測試函式 1
function array_walk_list_each(&$array, $function, $userData = null) {
/* 確保每次都遍歷陣列 */
reset($array);
while ( list(
$key, $value) = each($array) )
$function($array[$key], $key, $userData);
}

// 測試函式 2
function array_walk_foreach1(&$array, $function, $userData = null) {
foreach (
$array as $key => &$value )
$function($value, $key, $userData);
}

// 測試函式 3
function array_walk_foreach2(&$array, $function, $userData = null) {
foreach (
$array as $key => $value )
$function($array[$key], $key, $userData);
}

function
some_function(&$value, $key, $userData) {
$value = "$key => $userData";
}

function
test($function, $count = 10000, $arrayElements = 1000) {
echo
$function, ' ... ';
$array = array_fill(0, $arrayElements, "some text value");

$timer = microtime(true);
for(
$i = 0; ++$i < $count; )
/* 為每個 $i 變更資料 */
$function($array, 'some_function', 'some user data ' . $i);
printf("%.3f 秒\n", microtime(true) - $timer);

return
$array;
}
jab_creations_-at_-yahoo_-dot-_com
16 年前
很不幸地,我花了很多時間嘗試使用 array_walk 函式將函式的效果永久應用到陣列,但實際上我想要的是 array_map。這裡有一個非常簡單但有效的範例,提供給那些可能對這個函式感到過於沮喪的人...

<?php
$fruits
= array("Lemony & Fresh","Orange Twist","Apple Juice");

print_r($fruits);
echo
'<br />';

function
name_base($key)
{
$name2 = str_replace(" ", "_", $key);
$name3 = str_replace("&", "and", $name2);
$name4 = strtolower($name3);
echo
$name4.'<br />';
return
$name4;
}
echo
'<br />';

$test = array_map('name_base', $fruits);
$fruits_fixed = $test;
echo
'<br />';
print_r($fruits_fixed);
?>
http://alex.moutonking.com/wordpress
13 年前
為了完整起見,必須提及在 PHP 5.3 中使用此函式搭配閉包的可能性

<?php
$names
= array("D\'Artagnan", "Aramis", "Portos");
array_walk($names, function(&$n) {
$n = stripslashes($n);
});
?>

array_walk 的陷阱在於它不回傳陣列,而是透過引用修改陣列。
arekandrei at yandex dot ru
14 年前
您可以將 lambda 函式作為第二個參數使用

<?php
array_walk
($myArray, function(&$value, $key){
// 如果您想要變更陣列值,則 $value 前面的 "&" 是必要的。
});
?>

範例 (將正數值乘以二)

<?php
$myArray
= array(1, 2, 3, 4, 5);

array_walk($myArray, function(&$value, $index){
if (
$value > 0) $value *= 2;
});
?>
manuscle at gmail dot com
12 年前
搭配閉包的範例,檢查和刪除陣列中的值

<?php
$array
= array('foo' => 'bar', 'baz' => 'bat');

array_walk($array, function($val,$key) use(&$array){
if (
$val == 'bar') {
unset(
$array[$key]);
}
});

var_dump($array);
op_adept at yahoo dot co dot uk
14 年前
將陣列值加上鍵作為前綴,並以黏合字串的形式檢索,原始陣列保持不變。我使用此方法從陣列建立一些 SQL 查詢。

<?php

function array_implode_prefix($outer_glue, $arr, $inner_glue, $prefix=false){
array_walk( $arr , "prefix", array($inner_glue, $prefix) );
return
implode($outer_glue, $arr);
}

function
prefix(&$value, $key, array $additional){
$inner_glue = $additional[0];
$prefix = isset($additional[1])? $additional[1] : false;
if(
$prefix === false) $prefix = $key;

$value = $prefix.$inner_glue.$value;
}

//範例 1:
$order_by = array("3"=>"ASC", "2"=>"DESC", "7"=>"ASC");
echo
array_implode_prefix(",", $order_by, " ");
//輸出: 3 ASC,2 DESC,7 ASC

//範例 2:
$columns = array("product_id", "category_id", "name", "description");
$table = "product";

echo
array_implode_prefix(", ", $columns, ".", $table);
//輸出: product.product_id, product.category_id, product.name, product.description

//範例 3 (函式 prefix) 本身不會單獨使用
$pre= "vacation";
$value = "lalaland";
prefix($value, $pre, array("."));
echo
$value;

//輸出: vacation.lalaland

?>
theking2(at)king.ma
11 個月前
此函式可用於將一個陣列中的值加到另一個陣列

<?php
echo '<pre>';
// 範例程式碼
$a = [ 1, 2, 3, 4, 5, 6];
$c = [10,20,30,40,50,60];

array_walk($a,
function(&
$item, $key, $y) { $item += $y[$key];},
$c
);

print_r($a);

// 結果

Array
(
[
0] => 11
[1] => 22
[2] => 33
[3] => 44
[4] => 55
[5] => 66
)
@jfredys
13 年前
我正在尋找修剪陣列中所有元素的方法,我發現這是最簡單的解決方案

<?php
array_walk
($ids, create_function('&$val', '$val = trim($val);'));
?>
christopher at crmldnrs dot com
2 年前
public function big_endian_array_walk(array $array, $callback) {
end($array);
for($i=sizeof($array);$i>0;$i--) {
$key = key($array);
$value = array_pop($array);
if(preg_match('/^[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*$/', $value)) {
call_user_func_array($callback, [$value, $key]);
}
}
}

我只是想從結尾走到開頭。
christopher at crmldnrs dot com
2 年前
public function big_endian_array_walk(array $array, $callback) {
end($array);
for($i=sizeof($array);$i>0;$i--) {
$key = key($array);
$value = array_pop($array);
if(preg_match('/^[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*$/', $value)) {
call_user_func_array($callback, [$value, $key]);
}
}
}
vrrivaro at YESIUSEGMAIL dot gmail dot SO dot com
7 年前
如果透過網頁瀏覽器檢視,範例的輸出才是正確的。但是,如果您將其傳遞到 PHP-CLI,您將會看到額外的 HTML 換行符號。
diyism
16 年前
當我在 php5.2.5 中透過參照傳遞第三個參數時,
發生了這個:Warning: Call-time pass-by-reference has been deprecated - argument passed by value...(警告:呼叫時傳址已棄用 - 參數以值傳遞...)

並且根據 http://bugs.php.net/bug.php?id=19699,在 php.ini 中將 allow_call_time_pass_reference 設定為 true 無效,因此為了解決這個問題

<?php
array_walk
($arrChnOut, create_function('&$v, $k, $arr_rtn', 'if ($k{0}!="_") {$arr_rtn[0]["_".$v[\'ID\']]=$v; unset($arr_rtn[0][$k]);}'), array(&$arrChnOut));
?>
gold[at]evolved.net.nz
11 年前
對於所有試圖將 trim() 硬塞到 array_walk() 中,並且發現這些技巧可以解決 array_walk() 將 2 個參數傳遞給回呼的問題的人們...

請查看 array_map()。

https://php.dev.org.tw/array_map

它各種方面的強大。

在此記錄。我也是這些人之一,在 15 年的 php 開發經驗之後,我很高興地說我還在學習。:) 我自己才剛發現 array_map()...
espertalhao04 at hotmail dot com
11 年前
這是一個簡單但易於使用的此函式實作。
「原始」函式的問題是您無法取消設定值。
使用我的函式,您可以!

<?php
function array_walk_protected(&$a,$s,$p=null)
{
if(!
function_exists($s)||!is_array($a))
{
return
false;
}

foreach(
$a as $k=>$v)
{
if(
call_user_func_array($s,array(&$a[$k],$k,$p))===false)
{
unset(
$a[$k]);
}
}
}

function
get_name(&$e,$i,$p)
{
echo
"$i: $e<br>";
return
false;
}

$m=array('d'=>'33','Y'=>55);

array_walk_protected($m,'get_name');

var_dump($m); //傳回 array(0) { }
?>

我稱它為 array_walk_protected 是因為它可以防止使用原始函式取消設定值時發生意外行為。

要刪除元素,只需傳回 false!
不需要其他任何東西!
在您建立的函式下取消設定 $e,將保持陣列與原樣相同,沒有任何變更!

順便說一下,如果 $a 不是陣列或 $s 不是字串,則函式會傳回 false!

限制:它只能執行使用者定義的函式。
希望你會喜歡它!
mystral77 at gmail dot com
4 年前
您好,

如果您想將兩個陣列中具有相同鍵的值相加

<?php
function add(&$item,$key,$search) {
$item += (is_array($search))?((isset($search[$key]))?$search[$key]:0):0;
}

$a = ["orange" => 2, "banana" => 3, "apple" => 1];
$b = ["orange" => 1, "apple" => 4];

array_walk($c,"add",$b);

echo
"<pre>".print_r($c,true)."</pre>";
?>

這將會輸出

"orange" => 3,
"banana" => 3,
"apple" => 5
jerk at yoosic dot de
17 年前
如果你想修改多維陣列的每個值,請使用這裡使用的這個函式

<?php

$array
= array (1=>1, 2=> 2, 3 => array(1=>11, 2=>12, 3=>13));
$text = "test";

function
modarr(&$array, $text) {
foreach (
$array as $key => $arr) {
if(
is_array($arr)) $res[$key] = modarr(&$arr,$text);
// 此處為修改函式
else $res[$key] = $arr.$text;
}
return
$res;
}

$erg = modarr($array, $text);

print_r($erg);

?>

結果會是:

<?php
Array ( [1] => 1test [2] => 2test [3] => Array ( [1] => 11test [2] => 12test [3] => 13test ) )
?>
el_porno at web dot de
19 年前
您想去除使用者在表單欄位中加入的空白嗎...?
只需使用...

class SomeVeryImportantClass
{
...
public function mungeFormData(&$data)
{
array_walk($data, array($this, 'munge'));
}

private function munge(&$value, &$key)
{
if(is_array($value))
{
$this->mungeFormData($value);
}
else
{
$value = trim($value);
}
}
...
}

所以...
$obj = new SomeVeryImportantClass;
$obj->mungeFormData($_POST);
___
eNc
emre
3 年前
如果使用函式內全域的暫時返回陣列,則可以使用 array_walk 變更鍵或值。例如

$array = ['a'=>10, 'b'=>20];
$sequence = array ();

$newArray = array_values(array_walk($array, 'fn'));

function fn(&$val,$key){

global $sequence;

$sequence [] = $val;

}

無需擔心子陣列內部指標的位置。您現在已經重新回到以 0 為起始索引的新陣列,而不是字串鍵陣列。
peterzuzek AT gmail DOT com
16 年前
我使用此函式時遇到一些問題 - 它不想要應用 PHP 定義的函式。所以我決定自己寫一個 - 就是這個。我必須使用一些泛型程式設計技巧,沒有真正檢查速度(我認為它可能很慢)... 我相信它可能會更好,但我不知道如何 - 嗯,我猜支援多個陣列和遞迴會很好。那麼?

原型
bool arrayWalk(array &$arry, callback $callback, mixed $params=false)

<?php

function arrayWalk(&$arry, $callback, $params=false) {
$P=array(""); // 參數
$a=""; // 引數字串 :)

if($params !== false) { // 加入參數
if(is_array($params)) { // 多個額外參數
foreach($params as $par)
{
$P[]=$par; }
}
else
// 只有一個額外參數
{ $P[]=$params; }
}

for(
// 建立引數字串
$i=0; isset($P[$i]); ++$i
)
{
$a.='$'.chr($i + 97).', '; } // 隨機引數名稱

$a=substr($a, 0, -2); // 去除最後的逗號和兩個空格

$func=create_function($a, 'return '.$callback.'('.$a.');'); // 通用函式

if(is_callable($func)) {
for(
// 迴圈遍歷陣列
$i=0; isset($arry[$i]); ++$i
) {
$P[0]=$arry[$i]; // 第一個元素必須是第一個引數 - 陣列值
$arry[$i] = call_user_func_array($func, $P); // 指派由通用函式獲得的新值
}
}
else
{ return
false; } // 失敗 - 函式不可呼叫

return true; // 成功!
} // arrayWalk()

?>

我目前注意到一個大問題 - 例如,如果你想在陣列上使用 str_replace,你會失敗 - 僅僅因為 str_replace 的引數順序,其中修改的字串是第三個引數,而不是 arrayWalk 要求的第一個引數。

所以,還有一些工作要做...
To Top