Примечание: это кажется довольно длинным, вот краткое объяснение для людей, которые не хотят (или не должны) видеть все мои длинные объяснения ниже. Извините, если я поместил здесь слишком много материала, но я подумал, что лучше давать слишком много информации, а не слишком мало.
Короче, у меня есть массив JS, полный объектов. Эти объекты имеют массивы как некоторые из их свойств. Эти массивы представляют собой объекты, внутри которых есть массивы, внутри которых есть объекты. Всего 5 уровней вложенности. JavaScript 'JSON .parse / stringify отлично работает на них, но когда я начал заставлять эту программу работать на сервере, я использовал JavaScript' * JSON .stringify для отправки некоторых данных и php ' s json_decode, чтобы прочитать это. php манипулирует данными, используя их для редактирования большого объекта (хранится в формате JSON в текстовом файле на сервере). Небольшие функции, такие как addMessage и createRoom, работают, но когда я пытаюсь отправить 3-уровневый объект, он не работает. Я думаю, что проблема может быть связана с попыткой загрузить строковый объект, так как другие мои php сценарии получают параметры и затем создают объекты как stdClass из них.
Длинная скучная версия:
Этот вопрос, кажется, задается в разных вариантах в других местах, но я не могу найти ответ, который мне подходит. По сути, я занимаюсь разработкой интерактивной программы интерактивной доски. Он использует JS в качестве основного языка и PHP для выполнения всей работы по записи файлов. Я храню свои данные в файле .txt, используя json_encode. Для чтения данных из файла my JS вызывает my php, который декодирует файл, получает соответствующие данные, кодирует их и отображает их. Все данные создаются JS и ориентированы на редактирование JS - все они построены из JS классов. До сих пор моя программа работала нормально, объединение / создание досок и функция чата были относительно простыми. Когда я попытался реализовать синхронизацию доски между компьютерами, я обнаружил, что когда я отправлял новые данные доски до php и пытался поместить их в файл, json_encode не удался. Я получаю эту ошибку из журнала Apache: PHP Recoverable fatal error: Object of class stdClass could not be converted to string
.
Вместо того, чтобы останавливать программу, она запускается и повреждает файл данных (вероятно, необходимо выполнить некоторые проверки там) и убивает всю программу. Вот как работают мои структуры данных (в JS, как это было бы, если бы я жестко запрограммировал их):
[ /* list of room objects */
{ /* a room object */
name: 'example',
id: 'numbers',
whiteboardData: [
{ /* a shape object */
color: [r, g, b],
pointList: [
{ /* a vector object*/
x: 100,
y: 100,
}
/* heaps of other vector objects */
]
}
], /* end of whiteboardData */
chatMessages: [
{ /* a message object */
sender: 'username',
content: 'hi'
}
/* heaps of other message objects */
]
}
/* heaps of other room objects */
]
Как я уже сказал, он отлично работал с 3-уровневым вложением сообщения, но 5-уровневое вложение координат точки не работает. Я не могу упростить хранение данных программы, не переписав большую ее часть. Мой php в псевдокоде (потому что код немного трудно понять, не читая мою документацию):
receive id of the room that the whiteboard belongs to
receive whiteboard data as object
receive username of who made the edit (not used yet)
get contents of data file on server
do checks
decode data file and turn into object (roomData)
get the room as an object (actually a link to the room object in roomData)
decode the data that got sent up and turn into object
swap out the whiteboardData of the room object with the new data made in the line above
turn the main object (roomData) into a string (this is the one that keeps failing)
put the resulting string into the file
Мой php:
<?php
const roomDataFileUrl = "../!roomdata.txt";
$roomId = $_POST["roomId"];
$whiteboardDataStr = $_POST["whiteboardData"];
$editMadeBy = $_POST["editMadeBy"]; // unused as of now, may be used later on
// read data from file
$roomDataStr = file_get_contents(roomDataFileUrl);
if (strlen($roomDataStr) <= 0) {
echo "||nonExistentRoom";
}
// do check for null
if ($roomDataStr !== null) {
// if data file is empty, then just make empty array for data instead of reading file
if (strlen($roomDataStr) <= 0) {
$roomData = [];
}
else { // otherwise parse data
$roomData = json_decode($roomDataStr);
}
$room = getRoom($roomData, $roomId);
// check if room exists
if ($room !== null) {
// parse the whiteboard data and then put it in the room
// this will kill the program is there's a problem with the whiteboard data, so no checks needed
$whiteboardData = json_decode($whiteboardDataStr);
$room->whiteboardData = $whiteboardData;
// THIS LINE IS THE ONE THAT KEEPS FAILING
$roomDataStr = json_encode($roomData);
// put in file
if (strlen($roomDataStr) > 0) {
file_put_contents(roomDataFileUrl, $roomData);
}
else {
echo "**unknownServerError";
}
}
else {
echo "||nonExistentRoom";
}
}
else {
echo "**roomFileEmpty";
}
function getRoom($roomData, $roomId) {
$room = null;
for ($i = 0; $i < count($roomData); $i ++) {
$currentRoom = $roomData[$i];
if ($currentRoom->id === $roomId) {
$room = $currentRoom;
break;
}
}
return $room;
}
?>
Мой JS ( два метода из класса вырезаны и отредактированы, потому что большинство из них не нужно)
drawWhiteboardData(serverResponse) {
// I've removed about 20 lines of error processing here
var whiteboardDataStr = response;
var whiteboardData = JSON.parse(whiteboardDataStr);
this.whiteboardPtr.shapeList = whiteboardData;
}
sendWhiteboardData() {
var localWhiteboardData = this.whiteboardPtr.shapeList;
// this stringify works fine - I've checked the output manually
var localWhiteboardDataStr = JSON.stringify(localWhiteboardData);
// serverCommsManager.sendWhiteboardData just turns the data into a post request and sends it to my php file using the keys that can be seen at the top of the php file
this.serverCommsManagerPtr.sendWhiteboardData(
localWhiteboardDataStr, this.successfulEditProtocol.bind(this));
this.lastWhiteboardUpload = localWhiteboardDataStr;
}