mirror of
https://github.com/yiisoft/yii2.git
synced 2025-08-14 22:30:27 +08:00
Fixes #11275: Added possibility of unset or force replace former value in ArrayHelper::merge()
This commit is contained in:

committed by
Alexander Makarov

parent
0ac161b69d
commit
993f2aef28
@ -303,21 +303,68 @@ Encoding will use application charset and could be changed via third argument.
|
|||||||
|
|
||||||
## Merging Arrays <span id="merging-arrays"></span>
|
## Merging Arrays <span id="merging-arrays"></span>
|
||||||
|
|
||||||
|
You can use [[yii\helpers\ArrayHelper::merge()|ArrayHelper::merge()]] to merge two or more arrays into one recursively.
|
||||||
|
If each array has an element with the same string key value, the latter will overwrite the former
|
||||||
|
(different from [array_merge_recursive()](http://php.net/manual/en/function.array-merge-recursive.php)).
|
||||||
|
Recursive merging will be conducted if both arrays have an element of array type and are having the same key.
|
||||||
|
For integer-keyed elements, the elements from the latter array will be appended to the former array.
|
||||||
|
You can use [[yii\helpers\UnsetArrayValue]] object to unset value from previous array or
|
||||||
|
[[yii\helpers\ReplaceArrayValue]] to force replace former value instead of recursive merging.
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
```php
|
```php
|
||||||
/**
|
$array1 = [
|
||||||
* Merges two or more arrays into one recursively.
|
'name' => 'Yii',
|
||||||
* If each array has an element with the same string key value, the latter
|
'version' => '1.1',
|
||||||
* will overwrite the former (different from array_merge_recursive).
|
'ids' => [
|
||||||
* Recursive merging will be conducted if both arrays have an element of array
|
1,
|
||||||
* type and are having the same key.
|
],
|
||||||
* For integer-keyed elements, the elements from the latter array will
|
'validDomains' => [
|
||||||
* be appended to the former array.
|
'example.com',
|
||||||
* @param array $a array to be merged to
|
'www.example.com',
|
||||||
* @param array $b array to be merged from. You can specify additional
|
],
|
||||||
* arrays via third argument, fourth argument etc.
|
'emails' => [
|
||||||
* @return array the merged array (the original arrays are not changed.)
|
'admin' => 'admin@example.com',
|
||||||
*/
|
'dev' => 'dev@example.com',
|
||||||
public static function merge($a, $b)
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
$array2 = [
|
||||||
|
'version' => '2.0',
|
||||||
|
'ids' => [
|
||||||
|
2,
|
||||||
|
],
|
||||||
|
'validDomains' => new \yii\helpers\ReplaceArrayValue([
|
||||||
|
'yiiframework.com',
|
||||||
|
'www.yiiframework.com',
|
||||||
|
]),
|
||||||
|
'emails' => [
|
||||||
|
'dev' => new \yii\helpers\UnsetArrayValue(),
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
$result = ArrayHelper::merge($array1, $array2);
|
||||||
|
```
|
||||||
|
|
||||||
|
The result will be:
|
||||||
|
|
||||||
|
```php
|
||||||
|
[
|
||||||
|
'name' => 'Yii',
|
||||||
|
'version' => '2.0',
|
||||||
|
'ids' => [
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
],
|
||||||
|
'validDomains' => [
|
||||||
|
'yiiframework.com',
|
||||||
|
'www.yiiframework.com',
|
||||||
|
],
|
||||||
|
'emails' => [
|
||||||
|
'admin' => 'admin@example.com',
|
||||||
|
],
|
||||||
|
]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@ Yii Framework 2 Change Log
|
|||||||
- Bug #11912: Fixed PostgreSQL Schema to support negative default values for integer/float/decimal columns (nsknewbie)
|
- Bug #11912: Fixed PostgreSQL Schema to support negative default values for integer/float/decimal columns (nsknewbie)
|
||||||
- Bug #11947: Fixed `gridData` initialization in `yii.gridView.js` (pavlm)
|
- Bug #11947: Fixed `gridData` initialization in `yii.gridView.js` (pavlm)
|
||||||
- Bug #11949: Fixed `ActiveField::end` generates close tag when it's `option['tag']` is null (egorio)
|
- Bug #11949: Fixed `ActiveField::end` generates close tag when it's `option['tag']` is null (egorio)
|
||||||
|
- Enh #11275: Added possibility of unset or force replace former value in `ArrayHelper::merge()` (mdmunir, rob006)
|
||||||
- Enh #11950: Improve BaseArrayHelper::keyExists speed (egorio)
|
- Enh #11950: Improve BaseArrayHelper::keyExists speed (egorio)
|
||||||
- Bug #11726: `DbSession` was echoing database errors in production mode (samdark, pastuhov, deadkrolik)
|
- Bug #11726: `DbSession` was echoing database errors in production mode (samdark, pastuhov, deadkrolik)
|
||||||
- Bug #12030: Fixed `yii\base\Model::offsetExists()` throws an exception on un-existing field (klimov-paul)
|
- Bug #12030: Fixed `yii\base\Model::offsetExists()` throws an exception on un-existing field (klimov-paul)
|
||||||
|
@ -107,6 +107,8 @@ class BaseArrayHelper
|
|||||||
* type and are having the same key.
|
* type and are having the same key.
|
||||||
* For integer-keyed elements, the elements from the latter array will
|
* For integer-keyed elements, the elements from the latter array will
|
||||||
* be appended to the former array.
|
* be appended to the former array.
|
||||||
|
* You can use [[UnsetArrayValue]] object to unset value from previous array or
|
||||||
|
* [[ReplaceArrayValue]] to force replace former value instead of recursive merging.
|
||||||
* @param array $a array to be merged to
|
* @param array $a array to be merged to
|
||||||
* @param array $b array to be merged from. You can specify additional
|
* @param array $b array to be merged from. You can specify additional
|
||||||
* arrays via third argument, fourth argument etc.
|
* arrays via third argument, fourth argument etc.
|
||||||
@ -119,7 +121,11 @@ class BaseArrayHelper
|
|||||||
while (!empty($args)) {
|
while (!empty($args)) {
|
||||||
$next = array_shift($args);
|
$next = array_shift($args);
|
||||||
foreach ($next as $k => $v) {
|
foreach ($next as $k => $v) {
|
||||||
if (is_int($k)) {
|
if ($v instanceof UnsetArrayValue) {
|
||||||
|
unset($res[$k]);
|
||||||
|
} elseif ($v instanceof ReplaceArrayValue) {
|
||||||
|
$res[$k] = $v->value;
|
||||||
|
} elseif (is_int($k)) {
|
||||||
if (isset($res[$k])) {
|
if (isset($res[$k])) {
|
||||||
$res[] = $v;
|
$res[] = $v;
|
||||||
} else {
|
} else {
|
||||||
|
73
framework/helpers/ReplaceArrayValue.php
Normal file
73
framework/helpers/ReplaceArrayValue.php
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link http://www.yiiframework.com/
|
||||||
|
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||||
|
* @license http://www.yiiframework.com/license/
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace yii\helpers;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Object that represents the replacement of array value while performing [[ArrayHelper::merge()]].
|
||||||
|
*
|
||||||
|
* Usage example:
|
||||||
|
*
|
||||||
|
* ```php
|
||||||
|
* $array1 = [
|
||||||
|
* 'ids' => [
|
||||||
|
* 1,
|
||||||
|
* ],
|
||||||
|
* 'validDomains' => [
|
||||||
|
* 'example.com',
|
||||||
|
* 'www.example.com',
|
||||||
|
* ],
|
||||||
|
* ];
|
||||||
|
*
|
||||||
|
* $array2 = [
|
||||||
|
* 'ids' => [
|
||||||
|
* 2,
|
||||||
|
* ],
|
||||||
|
* 'validDomains' => new \yii\helpers\ReplaceArrayValue([
|
||||||
|
* 'yiiframework.com',
|
||||||
|
* 'www.yiiframework.com',
|
||||||
|
* ]),
|
||||||
|
* ];
|
||||||
|
*
|
||||||
|
* $result = \yii\helpers\ArrayHelper::merge($array1, $array2);
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* The result will be
|
||||||
|
*
|
||||||
|
* ```php
|
||||||
|
* [
|
||||||
|
* 'ids' => [
|
||||||
|
* 1,
|
||||||
|
* 2,
|
||||||
|
* ],
|
||||||
|
* 'validDomains' => [
|
||||||
|
* 'yiiframework.com',
|
||||||
|
* 'www.yiiframework.com',
|
||||||
|
* ],
|
||||||
|
* ]
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* @author Robert Korulczyk <robert@korulczyk.pl>
|
||||||
|
* @since 2.0.10
|
||||||
|
*/
|
||||||
|
class ReplaceArrayValue
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var mixed value used as replacement.
|
||||||
|
*/
|
||||||
|
public $value;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
* @param mixed $value value used as replacement.
|
||||||
|
*/
|
||||||
|
public function __construct($value)
|
||||||
|
{
|
||||||
|
$this->value = $value;
|
||||||
|
}
|
||||||
|
}
|
53
framework/helpers/UnsetArrayValue.php
Normal file
53
framework/helpers/UnsetArrayValue.php
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link http://www.yiiframework.com/
|
||||||
|
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||||
|
* @license http://www.yiiframework.com/license/
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace yii\helpers;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Object that represents the removal of array value while performing [[ArrayHelper::merge()]].
|
||||||
|
*
|
||||||
|
* Usage example:
|
||||||
|
*
|
||||||
|
* ```php
|
||||||
|
* $array1 = [
|
||||||
|
* 'ids' => [
|
||||||
|
* 1,
|
||||||
|
* ],
|
||||||
|
* 'validDomains' => [
|
||||||
|
* 'example.com',
|
||||||
|
* 'www.example.com',
|
||||||
|
* ],
|
||||||
|
* ];
|
||||||
|
*
|
||||||
|
* $array2 = [
|
||||||
|
* 'ids' => [
|
||||||
|
* 2,
|
||||||
|
* ],
|
||||||
|
* 'validDomains' => new \yii\helpers\UnsetArrayValue(),
|
||||||
|
* ];
|
||||||
|
*
|
||||||
|
* $result = \yii\helpers\ArrayHelper::merge($array1, $array2);
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* The result will be
|
||||||
|
*
|
||||||
|
* ```php
|
||||||
|
* [
|
||||||
|
* 'ids' => [
|
||||||
|
* 1,
|
||||||
|
* 2,
|
||||||
|
* ],
|
||||||
|
* ]
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* @author Robert Korulczyk <robert@korulczyk.pl>
|
||||||
|
* @since 2.0.10
|
||||||
|
*/
|
||||||
|
class UnsetArrayValue
|
||||||
|
{
|
||||||
|
}
|
@ -307,6 +307,79 @@ class ArrayHelperTest extends TestCase
|
|||||||
$this->assertEquals($expected, $result);
|
$this->assertEquals($expected, $result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testMergeWithUnset()
|
||||||
|
{
|
||||||
|
$a = [
|
||||||
|
'name' => 'Yii',
|
||||||
|
'version' => '1.0',
|
||||||
|
'options' => [
|
||||||
|
'namespace' => false,
|
||||||
|
'unittest' => false,
|
||||||
|
],
|
||||||
|
'features' => [
|
||||||
|
'mvc',
|
||||||
|
],
|
||||||
|
];
|
||||||
|
$b = [
|
||||||
|
'version' => '1.1',
|
||||||
|
'options' => new \yii\helpers\UnsetArrayValue(),
|
||||||
|
'features' => [
|
||||||
|
'gii',
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
$result = ArrayHelper::merge($a, $b);
|
||||||
|
$expected = [
|
||||||
|
'name' => 'Yii',
|
||||||
|
'version' => '1.1',
|
||||||
|
'features' => [
|
||||||
|
'mvc',
|
||||||
|
'gii',
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
$this->assertEquals($expected, $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testMergeWithReplace()
|
||||||
|
{
|
||||||
|
$a = [
|
||||||
|
'name' => 'Yii',
|
||||||
|
'version' => '1.0',
|
||||||
|
'options' => [
|
||||||
|
'namespace' => false,
|
||||||
|
'unittest' => false,
|
||||||
|
],
|
||||||
|
'features' => [
|
||||||
|
'mvc',
|
||||||
|
],
|
||||||
|
];
|
||||||
|
$b = [
|
||||||
|
'version' => '1.1',
|
||||||
|
'options' => [
|
||||||
|
'unittest' => true,
|
||||||
|
],
|
||||||
|
'features' => new \yii\helpers\ReplaceArrayValue([
|
||||||
|
'gii',
|
||||||
|
]),
|
||||||
|
];
|
||||||
|
|
||||||
|
$result = ArrayHelper::merge($a, $b);
|
||||||
|
$expected = [
|
||||||
|
'name' => 'Yii',
|
||||||
|
'version' => '1.1',
|
||||||
|
'options' => [
|
||||||
|
'namespace' => false,
|
||||||
|
'unittest' => true,
|
||||||
|
],
|
||||||
|
'features' => [
|
||||||
|
'gii',
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
$this->assertEquals($expected, $result);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see https://github.com/yiisoft/yii2/pull/11549
|
* @see https://github.com/yiisoft/yii2/pull/11549
|
||||||
*/
|
*/
|
||||||
|
Reference in New Issue
Block a user