-
Course Code
Subscribe to download the code!
Subscribe to download the code!
-
This Video
Subscribe to download the video!
Subscribe to download the video!
-
Course Script
Subscribe to download the script!
Subscribe to download the script!
Saving Pets
Scroll down to the script below, click on any sentence (including terminal blocks) to jump to that spot in the video!
Keep on Learning!
If you liked what you've learned so far, dive in! Subscribe to get access to this tutorial plus video, code and script downloads.
Saving Pets¶
Ok, let’s talk about saving pets. No, not like rescuing them, though that’s really cool too. I’m talking about being able to submit our new pet form and saving that pet information somewhere so that it shows up on our site. I want to make our pet list truly dynamic!
We haven’t talked about databases yet, and we’re not using one. But actually, the pet data our site needs is being stored in a simple pets.json file. And this file is something we can read from and even update. And hey, that’s basically all a database really does. So if we can figure out how to update the pets.json file each time we submit this form, we’re in business!
First, we can re-use our get_pets function to get an array of all of the existing pets from the file. Let’s add this right at the bottom of our form processing code:
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
// ...
$pets = get_pets();
var_dump($name, $breed, $weight, $bio);die;
}
Next, create an associative array that represents the new pet that’s being added. Make sure the keys you’re using match the existing pets from the file. We don’t have age or image fields yet, so just set those to be blank:
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
// ...
$pets = get_pets();
$newPet = array(
'name' => $name,
'breed' => $breed,
'weight' => $weight,
'bio' => $bio,
'image' => '',
'age' => '',
);
var_dump($name, $breed, $weight, $bio);die;
}
Ok! Now just add that new pet to the $pets array:
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
// ...
$pets = get_pets();
$newPet = array(
'name' => $name,
'breed' => $breed,
'weight' => $weight,
'bio' => $bio,
'image' => '',
'age' => '',
);
$pets[] = $newPet;
var_dump($name, $breed, $weight, $bio);die;
}
Remember that the empty square brackets tells PHP we want to add something to the $pets array, but we don’t care what the items key is. It’ll choose a unique number for us.
Saving the Pets to pets.json¶
Now, $pets has all the existing little fur balls, and our new one. It basically represents what we want to save to pets.json.
Let’s do it! First, turn $pets back into JSON with PHP’s json_encode function. To actually save the file, use another PHP function: file_put_contents:
// ...
$pets[] = $newPet;
$json = json_encode($pets);
file_put_contents('data/pets.json', $json);
This is basically what the get_pets function does, only in reverse! json_encode turns the array into a string, and then we save it back to the file.
Let’s try it! Fill out the form and submit. An error!
Call to undefined function get_pets()
Ah, woops! That function lives in the functions.php file. If we want to use it, we need to require that file:
<?php
require 'lib/functions.php';
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
// ...
}
Ok, refresh and re-post the form. Hmm, it looks like it did nothing. But that’s not true! We submitted the form, our code detected this was a POST request, we saved the new stuff to pets.json, and then the page continued rendering the blank form. There weren’t any fireworks, but I think this worked!
Go to the homepage to find out for sure! We didn’t give it an image, but there’s our pet. We don’t even have a database, and we already have a dynamic app.
Readable JSON!¶
If you look at pets.json, it got flattened onto one line. That’s ok! Spaces and new lines aren’t important in JSON, and PHP saved without any extra whitespace. Again, that’s fine really.
But since I did like my file better when it was readable, give json_encode a second argument of JSON_PRETTY_PRINT:
$json = json_encode($pets, JSON_PRETTY_PRINT);
Fill out our form again. Hey, now pets.json looks awesome again. We are really good at training this digital pet :) JSON_PRETTY_PRINT is called a constant, which is kind of like a variable, exept that it’s magically available everywhere, doesn’t have a $, and its value can’t change. You won’t use them often, so don’t worry about them too much.
26 Comments
Hi Again,
I fixed by disabling selinux:)
thank you
Hey Mahmut,
I'm glad to hear you found the solution yourself, well done! And thanks for sharing it with others :)
Cheers!
Hi there!
I can't seem to progress the challenge, even if I copy paste the provided solution. I assume it's broken, can you fix this?
Hey @Deniz
Can you point me to the challenge you're having troubles? I just tried out the challenges of this episode and I was able to solve them (The only gotcha is to fullfil the form in the Browser tab, and click on "Add toy")
Cheers!
Hey MolloKhan !
It just works now for some reason- thanks for checking!
Good to know! It may have been a short outage :)
Hello,
Copy all from "Show answer" and paste in the my 'new_toy.php' but all the time i have error
"Bummer! Not quite right, try again!
I don't see Bacon Bone in toys.json - double-check that you're keeping the original pets, not replacing them entirely."
Ok nevermind, I add __DIR__ . '/../toys.json' click check and then change it to toys.json and its work.
I've been following along with Chapter 4 by loading the project in codeanywhere and editing the pets_new.php. Everything has worked fine up until this point until I try to submit the form and I get this warning "Warning: file_put_contents(data/pets.json): failed to open stream: Permission denied in /home/cabox/workspace/pets_new.php on line 44" at the top of the page. Any assistance in getting this to work would be much appreciated!
Hey Daniel R.
You have to give at least read permissions to such user/group on that folder/file so your code can access to it
Cheers!
Hello!
First of all, thank you for the quality of this course! :)
I discovered a bug on the first challenge, when I filled out the form and send it, I had an error but I still validated the challenge :p
I think you check only a var_dump message on the content of the web page even if it does not match with the expected answer.
My error : i forgot the quotation marks on the first parameter of the file_get_contents php function.
Hope this helps you!
Hey Yassin,
First of all, thank you for your kind words and reporting this issue. I just double checked it and, unfortunately, I wasn't able to reproduce it. If I missed quotes for the 1st argument of file_get_contents(), i.e. call "file_put_contents(toys.json, $json);" - I would have an error and the system does not consider my answer as correct. But there's some tricky part - if you answered the challenge correctly before - then the "Fluffy Pig Stuffed Animal" IS already in the list because we store it into the file, and on the 2nd go when you send form with "file_put_contents(toys.json, $json);" it will show an error in the browser but consider the answer as correct. Anyway, I think it's OK because we handle it right on the first go and just because we don't want to complicate our grading system. Yes, sometimes you can bypass the grading system and mark challenges as correct but you need to know how the grading works for current challenge, so it's up to you :) We don't want to give you a super secure system where you 100% could not cheat, we just want to help you to catch stupid misprints and push you to the right direction ;)
But sometimes our challenges may have some bugs, so if you find a weird behavior - please, leave a comment again!
Cheers!
<?php
php tag
require DIR.'/lib/functions.php';
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$name =$_POST['name'];
$description = $_POST['description'];
$toys = get_great_pet_toys();
$new_toy = ['name'=>$_POST['name'], 'description'=>$_POST['description']];
$toys[] = $new_toy;
file_put_contents(__DIR__.'/../toys.json',json_encode($toys));
$json = json_decode(file_get_contents(__DIR__.'/../toys.json'),true);
var_dump($json);
}
$json = json_decode(file_get_contents(DIR.'/../toys.json'),true);
var_dump($json);
?>
<form action="/new_toy.php" method="POST">
<input type="text" name="name" />
<textarea name="description"></textarea>
<button type="submit">Add toy</button>
</form>
This code produces error like this:I don't see a new toy with name Fluffy Pig Stuffed Animal in toys.json. Are you adding it to the toys array before calling json_encode() and saving the file?
But on the browser window var_dump output shows the presence of 'Fluffy Pig Stuffed Animal' in the $json array decoded from the 'toys.json' file.
What could be the reason?
(On top of my code I've written php tag but it is not getting printed on the comment.)
Hey Tariq,
Are you talking about a challenge? If so, what challenge exactly? Could you link to it? Also, did you compare your code with the challenge answer? Also, I'd recommend you to try to execute your answer again on the new fresh challenge instance so that our system boots it from scratch.
Cheers!
Challenge 4.1(new_toy.php)
Hey Tariq,
Now I see... We're sorry to confuse you, but the problem is that you store the file in the parent directory, i.e. "__DIR__.'/../toys.json'", but we're expecting the file in the *current* directory instead, so basically "file_get_contents(__DIR__.'/toys.json')" or just "file_get_contents('toys.json')" should both work.
That's because of some limitation on our side to make think not too complex. And it looks like you're the first who tried a different from the current path :)
Cheers!
Thanks a lot...it worked !!! :-)
Hey Tariq,
Great! Thank you for replying back and confirming this works for you now!
Cheers!
Hello
Copy all from "Show answer" and paste in the my 'new_toy.php' but take mistake
Bummer! Not quite right, try again!
You should send a POST request: use the form in Browser to add a new toy with specific name.
What wong?
Hey Nina,
This challenge is pretty tricky ;) Pressing "Check" button sin't enough here, you need to send a really POST request, it means you need to fill in input fields with proper values on the "Browser" tab and press "Add toy" - this way a real POST request will be sent :)
Cheers!
Hi, even when I post use the code from the Answer section, it does not work. I keep getting "Fatal error: Call to undefined function get_great_pet_toys() in /var/www/code/new_toy.php on line 8. Looks like there is some problem with the path to the file with the function. Please help.
Hey Christoph Potzinger!
Oh no! Hmm. So I just tried the first challenge myself on this chapter (this one - just to make sure we're talking about the right one! https://knpuniversity.com/s... and I did *not* get the undefined function error. Do you have the "require" line on top? You mentioned you used the Answer code, so you should - but that require line should bring in lib/functions.php... which should bring in that function. Do you see any other errors? For example, if you *do* have the require line, do you see any error about "lib/functions.php" not existing?
Cheers!
Hi, thanks for your fast reply. I fixed it by completely reloading the page and pasting in the answer code. My problem might have been caused by the fact that I had a few errors before trying the answer code. It looks that my errors messed up the challenge validation. I could now pass the challenge. So all fixed! Thanks for your quick reaction - this is a Sunday, wow!
Awesome! And you might be right - the challenges are the wild west - we really let you do whatever you want in your code :). You could even delete (via PHP) the functions.php file... and yep, then you'd really be in trouble. Whatever the reason, happy it worked out for you!
Cheers!
"Houston: no signs of life"
Start the conversation!
Hi,
I have a problem about
file_put_contents()
function. When I use below PHP code, I can see withvar_dump
(json) thatnewPet
elements inserted pets array. However,file_put_contents()
is not updating data/json file.I am using centos and I gave chmod 777 permission to pets.json file.
Do you have any comment about this? thank you