In today's section, we will get more practice with PHP file i/o and write own own trivia web service. We will also practice making calls as a client to our web service using JS and AJAX.
Having written both the server-side and client-side programs for this website, this section will wrap up the course module on PHP web services!
First, we're going to review some PHP code quality guidelines for this course using an example of "poorly-implemented PHP code". The code is "externally correct", but has a variety of quality and documentation issues - many of these are common deductions in the PHP HW assignments.
You can find the source PHP code here. How many issues can you identify and explain as poor code quality?
trivia.php
Now that we've reviewed some common PHP code quality issues, let's write a PHP web service! To get started:
trivia.php
(remember to set
error_reporting(E_ALL)
at the top!).
trivia
folder (recall the glob
and scandir
functions for accessing files in directories). You may
also find array_rand
useful, as it selects a random index of a passed-in array. Also recall
file_get_contents
for getting the contents of a file as a string.
mode=categories
Modify the trivia.php
web service to take a required GET parameter called mode
.
When the user passes in a mode
value of categories
,
the web service should output a plain text list of all of the subdirectory names in the
trivia/
folder.
astronomy
biology
chemistry
computerscience
culture
history
internet
pokemon
random
mode=category
)
Next, add a check such that if mode
is passed as category
,
an optional name
parameter can be passed to choose the category
name
to return the contents of a random file for that specific category instead of a random category.
If the name
parameter is not passed, your web service should continue
to choose a random category as before.
If the mode
query parameter is missing or does not have a value of either categories
or
category
print out a 400 error message,
"Error: Please provide a mode of categories or category".
Otherwise, if the mode
query parameter is passed with a value of
category
and the optional query parameter name
is passed a
value that does not correspond to a category directory in the trivia
directory, print out a 400 error message,
"Error: Unknown category name
).
In this part of the exercise, we will practice outputting our data in a more
useful JSON format. Recall that JSON is much easier for clients to process
than plain text. First, we'll focus on changing our response when for
mode=category
.
Any valid response for this mode should output the random question and answer in the JSON format displayed below (example for request to trivia.php?mode=category&name=pokemon):
{
"question" : "What Pokemon comes first in the Pokedex?",
"answer" : "Bulbasaur"
}
Next, update your code for handing mode=categories
to now output JSON data in the format
below:
{
"categories" : [
{ "astronomy" : 2},
{ "biology" : 4},
{ "computerscience" : 10},
{ "culture" : 5},
{ "history" : 8},
{ "internet" : 9},
{ "pokemon" : 8}
{ "random" : 3}
]
}
The keys (categories) are the names of the folders in trivia
directory.
The values are the number of files in each category folder.
trivia.js
)
Next, we'll use a starting trivia.js
that has functions provided to
switch between different views and display questions/answers for trivia. However,
this file is missing... trivia. Let's use our new trivia web service for it to fetch
trivia from!
Note: For now, ignore the "Add Trivia" button. In Exercise 5/6, you can handle POST requests to finish the "Add Trivia" feature for more practice with POST!
In this part, we'll
focus just on using our GET parameters for the "List Categories" feature. Download
the starter HTML/CSS/JS here and make sure these are located in the same directory
as your trivia
directory and trivia.php
file.
The provided trivia.html
(styled with trivia.css
) has
three main sections: #category-view
, #question-area
, and
#new-trivia-view
.
When the page is initally loaded, a call is made to fetchCategories
. Finish
this function skeleton found in trivia.js
to fetch from your
trivia.php
to get the JSON response of all categories available
(mode=categories
). Use the provided populateCategories
function upon a successful response in this fetch request.
Next, when a user clicks the "New Question" button, a call to showTrivia
is
made from toggleQA
. Finish this showTrivia
function to make a request to
trivia.php
every time it is called. Your trivia.php
should send back data for a trivia tidbit if implemented correctly in Exercise 3. Upon success, you can use
the provided displayQuestion
function to show the new question data.
Now, we'll get some more practice handlng a POST request from our PHP service. Recall that while GET requests are often used to "get" information from a web service, POST requests are often supported by web services to take a request from a client and update some information on the server (e.g. adding to .txt files).
We'll add support to our trivia.php
web service to allow a client to add a
new question/answer entry to an existing category!
Add a check to your PHP such that if no GET parameter of mode
is passed,
three required POST parameters are checked:
category
- name of category to add new q/a entry toquestion
- new question to add for categoryanswer
- answer text for new questionIf any of these parameters are missing or the passed category does not correspond to a category folder, output a helpful 400 error message of your choice. Otherwise, write the necessary code to create a new text file (following naming conventions of the others) with the following format:
Q: <new-question>
A: <new-answer>
Upon success, your web service should print the following plaintext response:
New entry added for <category> category!
Now that you've implemented POST request handling in your PHP, add features to make a
POST request in trivia.js
when a the "Submit Entry!" button is clicked in
the "Add Trivia" view. Make sure to display a helpful message in the
#response
paragraph if missing question text in
the textarea and a corresponding answer in the answer input box.