A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://www.php.net/manual/en/function.array-walk.php below:

PHP: array_walk - Manual

array_walk

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

array_walkApply a user supplied function to every member of an array

Description

Applies the user-defined callback function to each element of the array array.

array_walk() is not affected by the internal array pointer of array. array_walk() will walk through the entire array regardless of pointer position.

Parameters
array

The input array.

callback

Typically, callback takes on two parameters. The array parameter's value being the first, and the key/index second.

Note:

If callback needs to be working with the actual values of the array, specify the first parameter of callback as a reference. Then, any changes made to those elements will be made in the original array itself.

Note:

Many internal functions (for example strtolower()) will throw a warning if more than the expected number of argument are passed in and are not usable directly as a callback.

Only the values of the array may potentially be changed; its structure cannot be altered, i.e., the programmer cannot add, unset or reorder elements. If the callback does not respect this requirement, the behavior of this function is undefined, and unpredictable.

arg

If the optional arg parameter is supplied, it will be passed as the third parameter to the callback.

Return Values

Always returns true.

Errors/Exceptions

As of PHP 7.1.0, an ArgumentCountError will be thrown if the callback function requires more than 2 parameters (the value and key of the array member), or more than 3 parameters if the arg is also passed. Previously, in this case an error of level E_WARNING would be generated each time array_walk() calls callback.

Changelog Version Description 8.2.0 The return type is true now; previously, it was bool. 8.0.0 If callback expects the second or third parameter to be passed by reference, this function will now emit an E_WARNING. Examples

Example #1 array_walk() example

<?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');
?>

The above example will output:

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

Example #2 array_walk() example using anonymous function

<?php
$elements
= ['a', 'b', 'c'];array_walk($elements, function ($value, $key) {
echo
"{$key} => {$value}\n";
});
?>

The above example will output:

See Also bisqwit at iki dot fi

20 years ago

It's worth nothing that array_walk can not be used to change keys in the array.
The function may be defined as (&$value, $key) but not (&$value, &$key).
Even though PHP does not complain/warn, it does not modify the key.

ezhacher at gmail dot com

10 years ago

Calling an array Walk inside a class

If the class is static:


array_walk($array, array('self', 'walkFunction'));
or
array_walk($array, array('className', 'walkFunction'));

Otherwise:


array_walk($array, array($this, 'walkFunction'));
01001coder at gmail dot com

7 years ago

I noticed that :

PHP ignored arguments type when using array_walk() even if there was

declare(strict_types=1) .

See this code as an example ...

<?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');?>


The output is :

butter: 5


meat: 7
banana: 3

whilst the expecting output is :

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

because "butter" => 5.3 is float

I asked someone about it and they said "this was caused by the fact that callbacks called from internal code will always use weak type". But I tried to do some tests and this behavior is not an issue when using call_user_func().

ludvig dot ericson at gmail dot com

19 years ago

In response to 'ibolmo', this is an extended version of string_walk, allowing to pass userdata (like array_walk) and to have the function edit the string in the same manner as array_walk allows, note now though that you have to pass a variable, since PHP cannot pass string literals by reference (logically).

<?php
function string_walk(&$string, $funcname, $userdata = null) {
for(
$i = 0; $i < strlen($string); $i++) {
$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);
}
string_walk($x = 'interesting', 'yourFunc');
string_walk($x = 'interesting', 'yourOtherFunc');
echo
$x;
?>


Also note that calling str_rot13() directly on $x would be much faster ;-) just a sample.
Maxim

14 years ago

Note that using array_walk with intval is inappropriate.
There are many examples on internet that suggest to use following code to safely escape $_POST arrays of integers:
<?php
array_walk
($_POST['something'],'intval'); ?>
It works in _some_ older PHP versions (5.2), but is against specifications. Since intval() does not modify it's arguments, but returns modified result, the code above has no effect on the array and will leave security hole in your website.

You can use following instead:


<?php
$_POST
['something'] = array_map(intval,$_POST['something']);
?>
chaley at brtransport dot com

11 years ago

There is a note about 3 years ago regarding using this for trimming. array_map() may be cleaner for this. I haven't checked the time/resource impact:

$result = array_map("trim", $array);

erelsgl at gmail dot com

16 years ago

If you want to unset elements from the callback function, maybe what you really need is array_filter.

rustamabd at gmail dot com

15 years ago

Don't forget about the array_map() function, it may be easier to use!

Here's how to lower-case all elements in an array:

<?php
$arr
= array_map('strtolower', $arr);
?>

fantomx1 at gmail dot com

8 years ago

Since array_walk cannot modify / change / reindex keys as already mentioned, i provide this small wrapping function which accomplishes passing array reference and index using closures , "use" keyword.

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 years ago

I wanted to walk an array and reverse map it into a second array. I decided to use array_walk because it should be faster than a reset,next loop or foreach(x as &$y) loop.

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

function

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


In my debugger I can see that $target is progressively updated, but when array_walk returns, $output is empty. If however I use a (deprecated) call-by-reference:

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


$output is returned correctly. Unfortunately there's not an easy way to suppress the warnings:

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


doesn't silence them. I've designed a workaround using a static array:

<?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 years ago

It can be very useful to pass the third (optional) parameter by reference while modifying it permanently in callback function. This will cause passing modified parameter to next iteration of array_walk(). The exaple below enumerates items in the array:

<?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";
?>


This outputs:

Array


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

Notice at the last line of output that outside of array_walk() the $num parameter has initial value of 1. This is because array_walk() does not take the third parameter by reference.. so what if we pass the reference as the optional parameter..

<?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!";
?>


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

Now $num has changed so we are able to count the items (without calling count() unnecessarily).

As a conclusion, using references with array_walk() can be powerful toy but this should be done carefully since modifying third parameter outside the array_walk() is not always what we want.

taj at yahoo dot fr

6 years ago

// We can make that with this simple FOREACH loop :

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

foreach($fruits as $cls => $vls)


{
$fruits[$cls] = "fruit: ".$vls;
}

Results:

Array


(
[d] => fruit: lemon
[a] => fruit: orange
[b] => fruit: banana
[c] => fruit: apple
)
EllisGL

6 years ago

For those that think they can't use array_walk to change / replace a key name, here you go:

<?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);
}
});
}
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('Old key does not exist.');
}
else
{
if (
array_key_exists($newKey, $data))
{
if (
$replaceExisting)
{
unset(
$data[$newKey]);
}
else
{
throw new
\Exception('New key already exist.');
}
}
$keys = array_keys($data);$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)
{
if('@attributes' === $key)
{
renameKey($value, $key, '_attributes');
}

});

print_r($array);
?>

zlobnygrif at gmail dot com

11 years ago

Some speed tests

<?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);function array_walk_list_each(&$array, $function, $userData = null) {
while ( list(
$key, $value) = each($array) )
$function($array[$key], $key, $userData);
}
function array_walk_foreach1(&$array, $function, $userData = null) {
foreach (
$array as $key => &$value )
$function($value, $key, $userData);
}
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; )
$function($array, 'some_function', 'some user data');
printf("%.3f sec\n", microtime(true) - $timer);

return

$array;
}
?>


Output (PHP 5.4.9-4ubuntu2.2 (cli) (built: Jul 15 2013 18:24:39))
=========================
array_walk ... 13.572 sec
array_walk_list_each ... 0.027 sec
array_walk_foreach1 ... 15.356 sec
array_walk_foreach2 ... 17.416 sec
bool(true)
bool(true)
bool(true)

Output (PHP 5.5.0 (cli) (built: Jul 16 2013 17:59:42) - same server)


=========================
array_walk ... 4.776 sec
array_walk_list_each ... 0.006 sec
array_walk_foreach1 ... 4.482 sec
array_walk_foreach2 ... 5.166 sec
bool(true)
bool(true)
bool(true)

PHP 5.5 array_walk looks pretty good but list each is more and more quickly...

matthew at codenaked dot org

14 years ago

Using lambdas you can create a handy zip function to zip together the keys and values of an array. I extended it to allow you to pass in the "glue" string as the optional userdata parameter. The following example is used to zip an array of email headers:

<?php function zip(&$data, $glue=': ')
{
if(!
is_array($data)) {
throw new
InvalidArgumentException('First parameter must be an array');
}
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; ?>

brian at access9 dot net

12 years ago

array_walk does not work on SplFixedArray objects:
<?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";
}
?>

result is:
test_1
test_2
jab_creations_-at_-yahoo_-dot-_com

16 years ago

Unfortunately I spent a lot of time trying to permanently apply the effects of a function to an array using the array_walk function when instead array_map was what I wanted. Here is a very simple though effective example for those who may be getting overly frustrated with this function...

<?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);
?>

arekandrei at yandex dot ru

15 years ago

You can use lambda function as a second parameter:

<?php
array_walk
($myArray, function(&$value, $key){
});
?>


Example (multiply positive values by two):

<?php
$myArray
= array(1, 2, 3, 4, 5);array_walk($myArray, function(&$value, $index){
if (
$value > 0) $value *= 2;
});
?>

http://alex.moutonking.com/wordpress

14 years ago

For completeness one has to mention the possibility of using this function with PHP 5.3 closures:

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


The trap with array_walk being it doesn't return the array, instead it's modified by reference.
manuscle at gmail dot com

13 years ago

example with closures, checking and deleting value in array:

<?php
$array
= array('foo' => 'bar', 'baz' => 'bat');array_walk($array, function($val,$key) use(&$array){
if (
$val == 'bar') {
unset(
$array[$key]);
}
});
var_dump($array);

fred

9 years ago

Correction for the speed test from 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);function array_walk_list_each(&$array, $function, $userData = null) {
reset($array);
while ( list(
$key, $value) = each($array) )
$function($array[$key], $key, $userData);
}
function array_walk_foreach1(&$array, $function, $userData = null) {
foreach (
$array as $key => &$value )
$function($value, $key, $userData);
}
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; )
$function($array, 'some_function', 'some user data ' . $i);
printf("%.3f sec\n", microtime(true) - $timer);

return

$array;
}

op_adept at yahoo dot co dot uk

14 years ago

Prefix array values with keys and retrieve as a glued string, the original array remains unchanged. I used this to create some SQL queries from arrays.

<?phpfunction 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;
}
$order_by = array("3"=>"ASC", "2"=>"DESC", "7"=>"ASC");
echo
array_implode_prefix(",", $order_by, " ");
$columns = array("product_id", "category_id", "name", "description");
$table = "product";

echo

array_implode_prefix(", ", $columns, ".", $table);
$pre= "vacation";
$value = "lalaland";
prefix($value, $pre, array("."));
echo
$value;?>

theking2(at)king.ma

1 year ago

This function can be used to add the values in one array to another:

<?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

14 years ago

I was looking for trimming all the elements in an array, I found this as the simplest solution:

<?php
array_walk
($ids, create_function('&$val', '$val = trim($val);'));
?>

christopher at crmldnrs dot com

3 years ago

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]);
}
}
}

I just wanted to walk from the end to the beginning.

christopher at crmldnrs dot com

3 years ago

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]);
}
}
}

diyism

16 years ago

When i pass the third parameter by reference in php5.2.5,
happened this: Warning: Call-time pass-by-reference has been deprecated - argument passed by value...

And to set allow_call_time_pass_reference to true in php.ini won't work, according to http://bugs.php.net/bug.php?id=19699 thus to work around:

<?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

12 years ago

For all those people trying to shoe-horn trim() into array_walk() and have found all these tricks to work around the issue with array_walk() passing 2 parameters to the callback...

Check out array_map().

http://php.net/array_map

It's all sorts of win.

For the record. I'm one of these people and after 15 years of php development I'm pleased to say that there's still things I'm learning. :) I just found out about array_map() myself...

espertalhao04 at hotmail dot com

12 years ago

here is a simple and yet easy to use implementation of this function.
the 'original' function has the problem that you can't unset a value.
with my function, YOU CAN!

<?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); ?>


i called it array_walk_protected because it is protected against the unexpected behavior of unsetting the value with the original function.

to delete an element, simply return false!!!


nothing else is needed!
unsetting $e, under your created function, will keep the same array as-is, with no changes!

by the way, the function returns false if $a is not array or $s is not a string!

limitations: it only can run user defined functions.


i hope you like it!
emre

4 years ago

You can change the key or value with array_walk if you use the temporal returned array in global inside the function. For example:

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


$sequence = array ();

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

function fn(&$val,$key){

global $sequence;

$sequence [] = $val;

}

No need to concern about the place of the internal pointer for the baby array. You have now rewinded, 0 based new array, string key one instead.

mystral77 at gmail dot com

5 years ago

Hello,

If you want to add values with same key from two arrays :

<?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>";
?>


This will output:

"orange" => 3,


"banana" => 3,
"apple" => 5
jerk at yoosic dot de

18 years ago

if you want to modify every value of an multidimensional array use this function used here:

<?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); ?>


result will be_

<?php
Array ( [1] => 1test [2] => 2test [3] => Array ( [1] => 11test [2] => 12test [3] => 13test ) )
?>

peterzuzek AT gmail DOT com

16 years ago

I had some problems using this function - it didn't want to apply PHP-defined functions. So I decided to write my own - here it is. I had to use some generic-programming skills, didn't really checked the speed (I think it could be slow)... I believe it could be much better, but I don't know, how - well, I guess multiple array support and recursion would be nice. So?

Prototype:


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

<?phpfunction 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; } ?>


One big problem I've noticed so far - for example, if you wanted to use str_replace on the array, you'd fail - simply because of the arguement order of str_replace, where the string modified is the third arguement, not the first as arrayWalk requires.

So, still some work left...

el_porno at web dot de

20 years ago

You want to get rid of the whitespaces users add in your form fields...?
Simply use...:

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);
}
}
...
}

so...


$obj = new SomeVeryImportantClass;
$obj->mungeFormData($_POST);
___
eNc

RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4