file_put_contents( "notes.txt", $note );, and it works perfectly the first time. The second time a different visitor submits a note, the entire file only contains the second note. The first visitor's note is gone completely, even though nothing deleted it directly. Why would saving a second piece of information erase the first?file_put_contents(), called with no extra flag, replaces the entire file's previous contents every single time it runs, by default, rather than adding new content onto what is already there. The second call does not delete the file as a separate step. It simply replaces everything the file held, because that is this function's default behavior, unless the FILE_APPEND flag is passed as a third argument, or the existing contents are read and combined first.file_get_contents() reads an entire file's contents into a single string in one call. file_put_contents() writes a string out to a file in one call, creating the file if it does not already exist.json_encode() turns a PHP array into one text string that can be saved, and json_decode() turns that same string back into a PHP array later.file_get_contents() and file_put_contents() can fail, returning false instead of stopping the script outright, most often because the file or folder does not have the right permissions for the server to read or write.file_get_contents( $file ) reads the entire current contents of notes.json into one string. If the file does not exist yet at all, this specific call produces a warning and returns false instead of stopping the program outright.json_decode( $existing_data, true ) turns that one long string back into a real PHP array. The second argument, true, is what makes the result an array instead of an object, which matters for whether $notes[] = ... works at all on the next line.?? [] right after json_decode(...) supplies an empty array specifically for the very first save, when the file does not exist yet and $existing_data came back false, which json_decode() would otherwise turn into null rather than a usable array.$notes[] = $_POST["note"] ?? ""; adds exactly one new note onto the array already read from the file, in memory, before anything is written back out. Nothing is saved to disk yet at this exact point.json_encode( $notes ) converts the entire, now-updated array back into one single string, and file_put_contents() writes that whole string out, replacing the file's previous contents entirely with a new, complete version that already includes every old note plus the new one.file_put_contents( $file, $new_text ) with no third argument removes everything the file held before and replaces it entirely with $new_text. Saving a second, unrelated note this way, without reading the file first, would leave exactly one note in the file, the most recent one, with the first one gone.file_get_contents() on a file that has never been created returns false, with a warning, rather than stopping the script. The ?? [] in this code specifically exists to turn that false, by way of json_decode() producing null, into a normal, empty array, so the very first save still works correctly.json_decode( $string, true ) produces an array, but json_decode( $string ) with no second argument produces an object instead, where $notes[] = ... would fail outright. Mixing these two forms across different parts of the same program is a common, easy-to-miss source of a fatal error.file_put_contents() returns false, and produces a warning, rather than stopping the program outright, when the server process does not have permission to write to the given folder. A save that silently does nothing, with the page still loading normally, is a common sign of exactly this kind of permissions problem rather than a mistake in the PHP code itself.file_get_contents() or file_put_contents() actually returns, since both can fail and return false instead of stopping the script. Third, does json_decode() get called with the right second argument to match how the rest of the code expects to use the result, as an array or an object.file_put_contents( $file, json_encode( $notes ) ); to file_put_contents( $file, $_POST["note"] ?? "" ); instead, to recreate the overwrite problem from the why cards on purpose, then undo the change.json_decode() without its second argument anywhere in this code, and read the resulting error when $notes[] = ... runs immediately afterward.Welcome back to Jit4All