Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG]: Phalcon\Config::merge change in 4.x #14705

Closed
dmarkic opened this issue Jan 13, 2020 · 8 comments · Fixed by #15723
Closed

[BUG]: Phalcon\Config::merge change in 4.x #14705

dmarkic opened this issue Jan 13, 2020 · 8 comments · Fixed by #15723
Assignees
Labels
5.0 The issues we want to solve in the 5.0 release breaks bc Functionality that breaks Backwards Compatibility bug A bug report discussion Request for comments and discussion

Comments

@dmarkic
Copy link

dmarkic commented Jan 13, 2020

Phalcon\Config::merge() now works, in some parts, for integer keys as PHP's array_merge. Integer keys do not get overwritten, but integer keys also do not get reindexed/renumbered.
The behavior is even stranger when we already have some numeric key inside, before merge, as keys get appended/incremented. Some examples below:

Script to reproduce:

$cfg = new \Phalcon\Config(['test' => 123, 'empty' => [], 'nonEmpty' => [5 => 'test']]);

echo " - original -\n";
print_r($cfg->toArray());

$emptyMerge = new \Phalcon\Config([3 => 'toEmpty']);
$nonEmptyMerge = new \Phalcon\Config([3 => 'toNonEmpty']);

$cfg->empty->merge($emptyMerge);
$cfg->nonEmpty->merge($nonEmptyMerge);

echo " - after merge -\n";
print_r($cfg->toArray());

Output (as expected) on Phalcon 3.x:

 - original -
Array
(
    [test] => 123
    [empty] => Array
        (
        )

    [nonEmpty] => Array
        (
            [5] => test
        )

)
 - after merge -
Array
(
    [test] => 123
    [empty] => Array
        (
            [3] => toEmpty
        )

    [nonEmpty] => Array
        (
            [5] => test
            [3] => toNonEmpty
        )

)

Everything is OK. empty has received 3 => toEmpty and nonEmpty has received 3 => toNonEmpty.

Output on Phalcon 4.x is completely different:

 - original -
Array
(
    [test] => 123
    [empty] => Array
        (
        )

    [nonEmpty] => Array
        (
            [5] => test
        )

)
 - after merge -
Array
(
    [test] => 123
    [empty] => Array
        (
            [0] => toEmpty
        )

    [nonEmpty] => Array
        (
            [5] => test
            [6] => toNonEmpty
        )

)

Here we see that empty receives key [0]. And nonEmpty gets appended to next key.

Expected behavior
I think Phalcon 3.x is the expected behavior, since this is configuration and keys may be important. Maybe add argument to Config::merge to overwrite or reindex keys on merge?

I didn't tested it, but simply removing elseif in https://github.com/phalcon/cphalcon/blob/master/phalcon/Config.zep#L191 would probably return to 3.x behavior.

If you'd like to move back to 3.x behavior I can try and change Config.zep and make PR.

Details

  • Phalcon version: 3.4.5 and 4.0.0
  • PHP Version: PHP 7.3.11-1~deb10u1
  • Operating System: Linux Debian
  • Installation type: installing via package manager
@dmarkic dmarkic added bug A bug report status: unverified Unverified labels Jan 13, 2020
@ruudboon ruudboon added the 4.0.3 label Jan 15, 2020
@ruudboon ruudboon self-assigned this Jan 25, 2020
@ruudboon ruudboon removed the status: unverified Unverified label Jan 25, 2020
@ruudboon ruudboon mentioned this issue Jan 25, 2020
5 tasks
@ruudboon ruudboon added 4.0.4 and removed 4.0.3 labels Jan 25, 2020
@ruudboon
Copy link
Member

ruudboon commented Feb 8, 2020

I think this issue needs some discussion. Personally I would like to align with how PHP is handeling this. Values in the input arrays with numeric keys will be renumbered with incrementing keys starting from zero in the result array.

http://sandbox.onlinephpfunctions.com/code/e79296edb95931346f14fb2155ae70965d586516

Array
(
    [test] => 123
    [empty] => Array
        (
            [0] => toEmpty
        )

    [nonEmpty] => Array
        (
            [0] => test
            [1] => toNonEmpty
        )

)

https://www.php.net/manual/en/function.array-merge.php
@niden @Jeckerson who do you guys think?

@ruudboon ruudboon added the discussion Request for comments and discussion label Feb 8, 2020
@Jeckerson Jeckerson added 4.0.5 and removed 4.0.4 labels Feb 15, 2020
@Jeckerson
Copy link
Member

I think current condition need to be here, to make sure that key is not overridden:

} elseif typeof key === "int" {

If in 4.0 approach was shifted to make same approach as PHP function array_merge(), even not intentionally, I prefer to stick with PHP's approach.

But, we need to update the docs with such examples as above.

@niden
Copy link
Member

niden commented Feb 20, 2020

I agree with @Jeckerson - the closer we are to PHP's native methods the better it is. It makes it easier for developers to use it. I would venture to say even that merge should be a clone of array_merge or array_replace

@niden niden added 4.0.6 and removed 4.0.5 labels Mar 8, 2020
@gpkappos
Copy link

gpkappos commented Apr 8, 2020

But this is about config so numeric keys might need to remain as they are.

For example in PDO, the constructor options are key value pairs like
[ PDO::ATTR_PERSISTENT => true ]
where PDO::ATTR_PERSISTENT is an integer.
Also PDO options is something that is expected to be kept in a config object.

@niden niden added 4.1.0 and removed 4.0.6 labels May 18, 2020
@gpkappos
Copy link

gpkappos commented Dec 7, 2020

Hello,
is there a decision on the behaviour of config merge?

@Jeckerson Jeckerson added 4.1.1 The issues we want to solve in the 4.1.1 release and removed 4.1.0 labels Dec 14, 2020
@Jeckerson
Copy link
Member

@gpkappos This behavior will be fixed in next release or some.

@Jeckerson Jeckerson added 5.0 The issues we want to solve in the 5.0 release breaks bc Functionality that breaks Backwards Compatibility and removed 4.1.1 The issues we want to solve in the 4.1.1 release labels Mar 26, 2021
@niden
Copy link
Member

niden commented Oct 23, 2021

Resolved in #15723

@niden niden closed this as completed Oct 23, 2021
@lcdennison
Copy link

@niden I believe the numerical-index merging is still a problem. Consider this test case, running on 5.0.0-beta1:

$array1 = ['first'];
$array2 = ['second', 'third'];

print_r((new Phalcon\Config\Config())
	->merge($array1)
	->merge($array2)
	->toArray()
);

gives:

Array
(
    [0] => second
    [1] => third
)

Even when I nested these arrays within a string-indexed child array, I got the same result for the merged element. Elements are always overwritten by their numerical indexes.

Based on the comments above, I thought the intention was to make the result like array_merge(), which applied to the same $array1 and $array2 above gives:

Array
(
    [0] => first
    [1] => second
    [2] => third
)

Did I just misunderstand the intended result from this fix, or is there still something to be adjusted here?

@niden niden moved this to Released in Phalcon v5 Aug 25, 2022
@niden niden added this to Phalcon v5 Aug 25, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
5.0 The issues we want to solve in the 5.0 release breaks bc Functionality that breaks Backwards Compatibility bug A bug report discussion Request for comments and discussion
Projects
Archived in project
Development

Successfully merging a pull request may close this issue.

6 participants