file_put_contents()搞乱了更新的数组值

时间:2013-12-04 10:18:02

标签: php arrays

如果标题有点令人困惑,请道歉。

我的结果指出了发生了什么。


这个问题变得非常广泛,所以我在这里强调这两件事:

查看底部的更新,看似合理的原因。

整个文件:(参见第86行)http://codepad.org/oIXaZZaB


这是发生了什么:

我有这个数组,它按照语言代码保存计数整数。

$downloads = [
    'all' => [
        'nl-BE' => 0,
        'nl-NL' => 0,
        'fr-BE' => 0,
        'fr-FR' => 0,
        'de-DE' => 0,
        'it-IT' => 0,
        'en-UK' => 0,
        'en'    => 0
    ],
    'unique' => [
        'nl-BE' => 0,
        'nl-NL' => 0,
        'fr-BE' => 0,
        'fr-FR' => 0,
        'de-DE' => 0,
        'it-IT' => 0,
        'en-UK' => 0,
        'en'    => 0
    ]
];

$_GET['langCode']参数中检索到的密钥始终计算$downloads['all']中的相应密钥。

我还检查访问者是否是唯一的,并且之前已经使用了相同的$langCode。如果之前未使用相同的$langCode,则计数也会添加到$downloads['unique']中的相应键中。

这是通过以下代码完成的:

$uniqueVisitors = [
    '127.0.0.1' => [ 'en-UK' ]
];


if ($uniqueVisitors == null)
{
    $uniqueVisitors = [
        $ipNew => []
    ];
}



$countUnique = 1;


/*  Check Unique Visitors  */

if (isset($uniqueVisitors[$ipNew]))
{
    if (in_array($langCode, $uniqueVisitors[$ipNew]))
    {
        $countUnique = 0;
    }

    else $uniqueVisitors[$ipNew][] = $langCode;
}

else $uniqueVisitors[$ipNew] = [ $langCode ];



/*  Update Data  */

$downloads['all'][$langCode]++;

if ($countUnique)
{
    $downloads['unique'][$langCode]++;
}


/*  Save Data  */

file_put_contents('data/unique-visitors.json', json_encode($uniqueVisitors));
file_put_contents('data/downloads.json', json_encode($downloads));

现在奇怪的是,当我运行脚本时,有时会计算多个键,即使$langCode只包含一个键(例如'nl-NL'

使用'en-UK'时,'en'通常也会被计算在内。 'fr-FR''fr-BE'也是如此。 并'nl-NL''nl-BE'

当使用的langCode计数仍为0时,通常会发生这种情况 但它似乎也是以随机顺序发生的。

现在您可能认为这是由于 langCodes 使用 ,但我使用了零索引键以及,结果相同!

例如:

/*  Retrieved first from JSON file  */

$downloads = [
    'all' => [
        'nl-BE' => 0,
        'nl-NL' => 2,
        'fr-BE' => 1,
        'fr-FR' => 0,
        'de-DE' => 0,
        'it-IT' => 0,
        'en-UK' => 0,
        'en'    => 0
    ],
    'unique' => [
        'nl-BE' => 0,
        'nl-NL' => 1,
        'fr-BE' => 1,
        'fr-FR' => 0,
        'de-DE' => 0,
        'it-IT' => 0,
        'en-UK' => 0,
        'en'    => 0
    ]
];

$uniqueVisitors = [
    '127.0.0.1' => [ 'nl-NL', 'fr-BE' ]
];


/*  Result after running script with 'en-UK' langCode  */

$downloads = [
    'all' => [
        'nl-BE' => 0,
        'nl-NL' => 2,
        'fr-BE' => 1,
        'fr-FR' => 0,
        'de-DE' => 0,
        'it-IT' => 0,
        'en-UK' => 1,
        'en'    => 1   // Why is this one counted ?
    ],
    'unique' => [
        'nl-BE' => 0,
        'nl-NL' => 1,
        'fr-BE' => 1,
        'fr-FR' => 0,
        'de-DE' => 0,
        'it-IT' => 0,
        'en-UK' => 1,
        'en'    => 1   // Why is this one counted ?
    ]
];

$uniqueVisitors = [
    '127.0.0.1' => [ 'nl-NL', 'fr-BE', 'en', 'en-UK' ]  //  'en' stored as well ?
];

整个文件:(参见第86行)http://codepad.org/oIXaZZaB


更新

当我没有使用两个file_put_contents()函数将更新的数据保存回文件,并且只是进行一些测试和转储时,整个计数确实按预期工作!

所以看来这两个file_put_contents()函数,用于保存(正确)更新的数据,以某种方式干扰,并在执行时改变一些计数。

但是如何?!

有人对此意外行为有更好的了解吗?


更新2:

当我在我的json_encode()函数中遗漏file_put_contents()时,我会收到“数组到字符串转换”错误,两次用于保存我的计数数据{{1} }):

$downloads

Notice: Array to string conversion in /Applications/MAMP/htdocs/project/downloads/downloads.php on line 89

Notice: Array to string conversion in /Applications/MAMP/htdocs/project/downloads/downloads.php on line 90

Notice: Array to string conversion in /Applications/MAMP/htdocs/project/downloads/downloads.php on line 90

那为什么那个被执行两次?那里甚至没有一个循环。


更新3:

我的JSON编码file_put_contents('data/unique-visitors.json', json_encode($uniqueVisitors)); file_put_contents('data/downloads.json', json_encode($downloads)); // This one is called twice! 数据正确显示更新后的值。

但是,只要我使用$downloads来存储更新的file_put_contents()数据,就会更新值。即使我在使用$downloads之前/之后转储我的更新数据,它也会显示混乱。

初始file_put_contents数组:

$downloads

使用$downloads = [ 'all' => [ 'nl-BE' => 0, 'nl-NL' => 0, 'fr-BE' => 0, 'fr-FR' => 0, 'de-DE' => 0, 'it-IT' => 0, 'en-UK' => 0, 'en' => 0 ], 'unique' => [ 'nl-BE' => 0, 'nl-NL' => 0, 'fr-BE' => 0, 'fr-FR' => 0, 'de-DE' => 0, 'it-IT' => 0, 'en-UK' => 0, 'en' => 0 ] ]; 更新了值:

$_GET['langCode'] = 'nl-BE'

当我尝试使用$downloads = [ 'all' => [ 'nl-BE' => 1, 'nl-NL' => 0, 'fr-BE' => 0, 'fr-FR' => 0, 'de-DE' => 0, 'it-IT' => 0, 'en-UK' => 0, 'en' => 0 ], 'unique' => [ 'nl-BE' => 1, 'nl-NL' => 0, 'fr-BE' => 0, 'fr-FR' => 0, 'de-DE' => 0, 'it-IT' => 0, 'en-UK' => 0, 'en' => 0 ] ]; 存储更新的数组时:

file_put_contents()

奇怪的是,当我使用$downloads = [ 'all' => [ 'nl-BE' => 2, // Why this increment? 'nl-NL' => 0, 'fr-BE' => 0, 'fr-FR' => 0, 'de-DE' => 0, 'it-IT' => 0, 'en-UK' => 0, 'en' => 0 ], 'unique' => [ 'nl-BE' => 1, 'nl-NL' => 0, 'fr-BE' => 0, 'fr-FR' => 0, 'de-DE' => 0, 'it-IT' => 0, 'en-UK' => 0, 'en' => 0 ] ]; 时,更新的file_put_contents显示错误更新,在同一个脚本运行时转移($downloads之前和之后)。我甚至不必使用file_put_contents来检索错误保存的数据。


更新4 :(原因)

Safari 7正在导致此错误。

Firefox和Chrome都完美地运行此脚本。

我可以在哪里举报?


htaccess的:

如果没有htaccess文件,仍然会发生同样的错误。

file_get_contents

2 个答案:

答案 0 :(得分:1)

我也无法重现你的错误。在我看来,你的脚本被调用两次(参见'all'中的项目增加但不是'unique'。

file_put_contents()没有问题。您可以通过在脚本中添加以下内容来验证这一点:

<?php

mail('you@domain.tld', 'script executed at '.time(), '');

// your code ...

我建议您复制脚本,删除所有HTML代码,然后在具有虚拟数据的终端中执行

php yourscript.php

这是我的代码:http://codepad.org/XhS6uEz1

你会发现它的行为正确。

此外,你可以禁用一些php module that could be responsible for such bugs,但我认为这不是问题。

答案 1 :(得分:0)

查看服务器访问日志,看看是否可以确定第二次调用脚本的来源。我已经安装了插件这样的东西,调试器或插件检查你的页面加载速度可以再次调用页面。