英文:
jQuery AJAX call broken under PHP 8.X (PHP 8 Uncaught TypeError: array_key_exists() error)
问题
I will try to be as much explicative as possible.
我将尽量详细说明。
I have a PHP+jQuery application (some sort of a text game) where the system works reading and writing JSON files with AJAX all the time. Everything is absolutely perfect under PHP 7.4, however, when I upgrade to 8.0 or 8.1 (my hosting is forcing me) the AJAX breaks.
我有一个PHP+jQuery应用程序(一种文本游戏),系统通过AJAX一直在读写JSON文件。在PHP 7.4下一切都完美无缺,然而,当我升级到8.0或8.1时(我的主机强制我升级),AJAX就出现了问题。
Inspecting the JS console, right after the very first AJAX call, I get a ERROR 500. So, I assumed it was happening in the PHP side and I was right. I did take a look in the apache logs and found a PHP fatal error happening there — But note that under PHP7.4, there are no problems at all.
在第一个AJAX调用之后,我在JS控制台中检查到一个ERROR 500错误。所以,我认为这是在PHP端发生的,我是对的。我查看了Apache日志,发现那里发生了PHP致命错误,但请注意,在PHP7.4下,一切都没有问题。
The error in my Apache log:
我的Apache日志中的错误:
PHP Fatal error: Uncaught TypeError: array_key_exists(): Argument #2 ($array) must be of type array, stdClass given in /home/xxx/zzz.com/motor/FileDriver.php:36, referer: https://zzz.com/yyy/xxx/
And this is the PHP file where the error happens, line 36:
这是发生错误的PHP文件,第36行:
$n = func_num_args();
$g = func_get_args();
$data = json_decode(file_get_contents($g[0]));
if (!array_key_exists($g[1], $data))
$data->{$g[1]} = new StdClass();
if (($n == 4) && (!array_key_exists($g[2], $data->{$g[1]})))
$data->{$g[1]}->{$g[2]} = new StdClass();
if ($n == 3)
$data->{$g[1]} = $g[2];
else if ($n == 4)
$data->{$g[1]}->{$g[2]} = $g[3];
unlink($g[0]);
file_put_contents($g[0], json_encode($data, JSON_PRETTY_PRINT));
}```
**The error happens right here:**
**错误发生在这里:**
``` $data = json_decode(file_get_contents($g[0]));
// THE ERROR BELOW!
if (!array_key_exists($g[1], $data))
$data->{$g[1]} = new StdClass();```
<details>
<summary>英文:</summary>
I will try to be as much explicative as possible.
I have a PHP+jQuery application (some sort of a text game) where the system works reading and writing JSON files with AJAX all the time. Everything is absolutely **perfect under PHP 7.4**, however, when I **upgrade to 8.0 or 8.1** (my hosting is forcing me) the AJAX breaks.
Inspecting the JS console, right after the very first AJAX call, I get a ERROR 500. So, I assumed it was happening in the PHP side and **I was right**. I did take a look in the apache logs and found a PHP fatal error happening there — But note that under PHP7.4, there are no problems at all.
**The error in my Apache log:**
PHP Fatal error: Uncaught TypeError: array_key_exists():
Argument #2 ($array) must be of type array,
stdClass given in /home/xxx/zzz.com/motor/FileDriver.php:36,
referer: https://zzz.com/yyy/xxx/
**And this is the PHP file where the error happens, line 36:**
function save() {
$n = func_num_args();
$g = func_get_args();
$data = json_decode(file_get_contents($g[0]));
if (!array_key_exists($g[1], $data))
$data->{$g[1]} = new StdClass();
if (($n == 4) && (!array_key_exists($g[2], $data->{$g[1]})))
$data->{$g[1]}->{$g[2]} = new StdClass();
if ($n == 3)
$data->{$g[1]} = $g[2];
else if ($n == 4)
$data->{$g[1]}->{$g[2]} = $g[3];
unlink($g[0]);
file_put_contents($g[0], json_encode($data, JSON_PRETTY_PRINT));
}
**The error happens right here:**
$data = json_decode(file_get_contents($g[0]));
// THE ERROR BELOW!
if (!array_key_exists($g[1], $data))
$data->{$g[1]} = new StdClass();
I tried to add the **$assoc** parameter to PHP **json_decode() function**, but it did not help. I really have no idea how to solve that, other than downgrading to PHP 7.4... however, can't do it anymore.
EDITED: Removed irrelevant code, image and information.
EDITED2: Adjusted the title to a more explicative sentence.
</details>
# 答案1
**得分**: 3
The AJAX call hasn't failed. The error message clearly points at PHP, so all this JavaScript is irrelevant.
Looking at the error message and the PHP code you have posted the variable `$data` is an object.
The documentation for `array_key_exists()` says this:
> For backward compatibility reasons, array_key_exists() will also
> return true if key is a property defined within an object given as
> array. This behaviour is deprecated as of PHP 7.4.0, and removed as of
> PHP 8.0.0.
>
> To check whether a property exists in an object, property_exists()
> should be used.
You should update line 36 to this:
if (!property_exists($data,$g[1]))
<details>
<summary>英文:</summary>
The AJAX call hasn't failed. The error message clearly points at PHP, so all this JavaScript is irrelevant.
Looking at the error message and the PHP code you have posted the variable `$data` is an object.
The documentation for `array_key_exists()` says this:
> For backward compatibility reasons, array_key_exists() will also
> return true if key is a property defined within an object given as
> array. This behaviour is deprecated as of PHP 7.4.0, and removed as of
> PHP 8.0.0.
>
> To check whether a property exists in an object, property_exists()
> should be used.
You should update line 36 to this:
if (!property_exists($data,$g[1]))
Note that the order of parameters is reversed from `array_key_exists()`
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论