mirror of
https://github.com/yiisoft/yii2.git
synced 2025-11-01 03:26:36 +08:00
Fix #19914: Fixed ArrayHelper::keyExists() and ::remove() functions when the key is a float and the value is null
This commit is contained in:
@ -16,6 +16,7 @@ Yii Framework 2 Change Log
|
||||
- Enh #19884: Added support Enums in Query Builder (sk1t0n)
|
||||
- Bug #19908: Fix associative array cell content rendering in Table widget (rhertogh)
|
||||
- Bug #19906: Fixed multiline strings in the `\yii\console\widgets\Table` widget (rhertogh)
|
||||
- Bug #19914: Fixed `ArrayHelper::keyExists()` and `::remove()` functions when the key is a float and the value is `null` (rhertogh)
|
||||
- Enh #19920: Broadened the accepted type of `Cookie::$expire` from `int` to `int|string|\DateTimeInterface|null` (rhertogh)
|
||||
|
||||
|
||||
|
||||
@ -282,7 +282,7 @@ abstract class BaseActiveRecord extends Model implements ActiveRecordInterface
|
||||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
if (isset($this->_attributes[$name]) || array_key_exists($name, $this->_attributes)) {
|
||||
if (array_key_exists($name, $this->_attributes)) {
|
||||
return $this->_attributes[$name];
|
||||
}
|
||||
|
||||
@ -290,7 +290,7 @@ abstract class BaseActiveRecord extends Model implements ActiveRecordInterface
|
||||
return null;
|
||||
}
|
||||
|
||||
if (isset($this->_related[$name]) || array_key_exists($name, $this->_related)) {
|
||||
if (array_key_exists($name, $this->_related)) {
|
||||
return $this->_related[$name];
|
||||
}
|
||||
$value = parent::__get($name);
|
||||
|
||||
@ -327,7 +327,12 @@ class BaseArrayHelper
|
||||
*/
|
||||
public static function remove(&$array, $key, $default = null)
|
||||
{
|
||||
if (is_array($array) && (isset($array[$key]) || array_key_exists($key, $array))) {
|
||||
// ToDo: This check can be removed when the minimum PHP version is >= 8.1 (Yii2.2)
|
||||
if (is_float($key)) {
|
||||
$key = (int)$key;
|
||||
}
|
||||
|
||||
if (is_array($array) && array_key_exists($key, $array)) {
|
||||
$value = $array[$key];
|
||||
unset($array[$key]);
|
||||
|
||||
@ -608,17 +613,20 @@ class BaseArrayHelper
|
||||
* Checks if the given array contains the specified key.
|
||||
* This method enhances the `array_key_exists()` function by supporting case-insensitive
|
||||
* key comparison.
|
||||
* @param string $key the key to check
|
||||
* @param string|int $key the key to check
|
||||
* @param array|ArrayAccess $array the array with keys to check
|
||||
* @param bool $caseSensitive whether the key comparison should be case-sensitive
|
||||
* @return bool whether the array contains the specified key
|
||||
*/
|
||||
public static function keyExists($key, $array, $caseSensitive = true)
|
||||
{
|
||||
// ToDo: This check can be removed when the minimum PHP version is >= 8.1 (Yii2.2)
|
||||
if (is_float($key)) {
|
||||
$key = (int)$key;
|
||||
}
|
||||
|
||||
if ($caseSensitive) {
|
||||
// Function `isset` checks key faster but skips `null`, `array_key_exists` handles this case
|
||||
// https://www.php.net/manual/en/function.array-key-exists.php#107786
|
||||
if (is_array($array) && (isset($array[$key]) || array_key_exists($key, $array))) {
|
||||
if (is_array($array) && array_key_exists($key, $array)) {
|
||||
return true;
|
||||
}
|
||||
// Cannot use `array_has_key` on Objects for PHP 7.4+, therefore we need to check using [[ArrayAccess::offsetExists()]]
|
||||
|
||||
@ -135,6 +135,29 @@ class ArrayHelperTest extends TestCase
|
||||
$this->assertEquals('defaultValue', $default);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function testRemoveWithFloat()
|
||||
{
|
||||
if (version_compare(PHP_VERSION, '8.1.0', '>=')) {
|
||||
$this->markTestSkipped('Using floats as array key is deprecated.');
|
||||
}
|
||||
|
||||
$array = ['name' => 'b', 'age' => 3, 1.1 => null];
|
||||
|
||||
$name = ArrayHelper::remove($array, 'name');
|
||||
$this->assertEquals($name, 'b');
|
||||
$this->assertEquals($array, ['age' => 3, 1.1 => null]);
|
||||
|
||||
$floatVal = ArrayHelper::remove($array, 1.1);
|
||||
$this->assertNull($floatVal);
|
||||
$this->assertEquals($array, ['age' => 3]);
|
||||
|
||||
$default = ArrayHelper::remove($array, 'nonExisting', 'defaultValue');
|
||||
$this->assertEquals('defaultValue', $default);
|
||||
}
|
||||
|
||||
public function testRemoveValueMultiple()
|
||||
{
|
||||
$array = [
|
||||
@ -506,14 +529,21 @@ class ArrayHelperTest extends TestCase
|
||||
/**
|
||||
* @see https://github.com/yiisoft/yii2/pull/11549
|
||||
*/
|
||||
public function test()
|
||||
public function testGetValueWithFloatKeys()
|
||||
{
|
||||
if (version_compare(PHP_VERSION, '8.1.0', '>=')) {
|
||||
$this->markTestSkipped('Using floats as array key is deprecated.');
|
||||
}
|
||||
|
||||
$array = [];
|
||||
$array[1.0] = 'some value';
|
||||
|
||||
$result = ArrayHelper::getValue($array, 1.0);
|
||||
$array[1.1] = 'some value';
|
||||
$array[2.1] = null;
|
||||
|
||||
$result = ArrayHelper::getValue($array, 1.2);
|
||||
$this->assertEquals('some value', $result);
|
||||
|
||||
$result = ArrayHelper::getValue($array, 2.2);
|
||||
$this->assertNull($result);
|
||||
}
|
||||
|
||||
public function testIndex()
|
||||
@ -712,6 +742,7 @@ class ArrayHelperTest extends TestCase
|
||||
'a' => 1,
|
||||
'B' => 2,
|
||||
];
|
||||
|
||||
$this->assertTrue(ArrayHelper::keyExists('a', $array));
|
||||
$this->assertFalse(ArrayHelper::keyExists('b', $array));
|
||||
$this->assertTrue(ArrayHelper::keyExists('B', $array));
|
||||
@ -723,6 +754,27 @@ class ArrayHelperTest extends TestCase
|
||||
$this->assertFalse(ArrayHelper::keyExists('c', $array, false));
|
||||
}
|
||||
|
||||
public function testKeyExistsWithFloat()
|
||||
{
|
||||
if (version_compare(PHP_VERSION, '8.1.0', '>=')) {
|
||||
$this->markTestSkipped('Using floats as array key is deprecated.');
|
||||
}
|
||||
|
||||
$array = [
|
||||
1 => 3,
|
||||
2.2 => 4, // Note: Floats are cast to ints, which means that the fractional part will be truncated.
|
||||
3.3 => null,
|
||||
];
|
||||
|
||||
$this->assertTrue(ArrayHelper::keyExists(1, $array));
|
||||
$this->assertTrue(ArrayHelper::keyExists(1.1, $array));
|
||||
$this->assertTrue(ArrayHelper::keyExists(2, $array));
|
||||
$this->assertTrue(ArrayHelper::keyExists('2', $array));
|
||||
$this->assertTrue(ArrayHelper::keyExists(2.2, $array));
|
||||
$this->assertTrue(ArrayHelper::keyExists(3, $array));
|
||||
$this->assertTrue(ArrayHelper::keyExists(3.3, $array));
|
||||
}
|
||||
|
||||
public function testKeyExistsArrayAccess()
|
||||
{
|
||||
$array = new TraversableArrayAccessibleObject([
|
||||
|
||||
Reference in New Issue
Block a user