Saturday, December 14, 2024

Generate HTML files with PHP to Reduce the Server Load

Share

PIM Team Case Study

How you can have a site with tons of visitors without to crash the server?

Problem

PIM Team Bulgaria had the task to create a quiz site able to hold an extreme server load.

The site is currently installed as beta version at www.quizzy.net.

Goals

– Create a user friendly quiz editor

– Create static URLs for the quizes

– Users were able to put the quizes on their site. However this shouldnt cause big server load.

Solution

Creating database structure and the basic program logic was a game play for the experienced developers in PIM.

However we had to decide the best way to reduce the server load. After investigating together with the help of the customer we found the best solution – the quiz forms were going to be hardcoded.

Methodology

We don’t need anything special except PHP and MySQL to achieve this task. Having the right permissions to write in the server folders its all about generating strings and saving HTML files.

Implementation

As this article is not aboput creating a quiz site, we’ll point our attention only to these features which required reducing of the server load.

A quiz editor for creating and editing quizes

While the creating of quizes isnt likely to be done by all the users of the site all the time, we wouldnt need to worry about the server load. Not that we can hardcode this editor in HTML ever!

The editor allows usres to create questions with various number and type of answers on each quiz.

Each quiz also had various number of results which were generated depending of user’s answres.

Here we saw what we could use to reduce the server load:

Quizes themself

What is one quiz in the terms of a website? Its just a HTML form. However our users are creating the quizes so nobody could know what forms will they create. The ordinary solution is to read the database with questions, select possible answers and display them to the users.

But all of this is database queries. We can’t select questions and answers at once with JOIN, because both need to be ordered in the same way the user has put them in the editor.

This means at least one query for each question. Imagine a quiz with 30 questions taken from 100 users at the same time. This is 3000 queries at least. We don’t wan’t to do this.

So we were going to create pure HTML forms from the quizes at the time of creating. We also needed to update the quizes when users update them. So we add a button ‘activate’ for ‘sending’ the quiz online. Hitting this button actually takes the questions and answers from the database and creates HTML form. Below is a piece of code showing how easy this is:


//generate HTML for the quiz page

$html="
<head><title>Quizzy.net - Quizzes and Personality
Tests</title>\n
<link rel=stylesheet
href=".SITE_URL."templates/styles.css></head>\n
<table align=center width=600>\n
<tr><td class=heading>$quiz[title] By <a target=_blank
style='color:white;'
href=".SITE_URL."user.php?id=$user->id>$user->username</a></td></tr>\n
<tr><td><i>".nl2br($quiz[description])."</i><br><br></td></tr>
<form method=post action=".SITE_URL."result.php>\n
<input type=hidden name=id value=$quiz[id]>\n";

foreach($questions as $question)
{
$html.="<tr><td><b>".nl2br($question[question])."</b><br><br>";

foreach($question[choices] as $choice)
{
if($question[qtype]=='single')
{
$html.="<input class=radio type=radio
name=question".$question[id]." value=".$choice[id].">
$choice[answer]<br>\n";
}
else
{
$html.="<input class=radio type=checkbox
name=question".$question[id]."[] value=".$choice[id].">
$choice[answer]<br>\n";
}
}

$html.="<br><br></td></tr>";
}

$html.="<tr><td><input type=submit name=ok value=Go
class=button></td></tr></table>\n
</form><br>";

Now we have to save this as HTML file:


//generate file name
$qfname=str_replace(" ","-",$quiz[title]);
$qfname=str_replace("?","",$qfname);

//open file
$fp=fopen("quiz/$user->username/$qfname.html","wb");
fwrite($fp,$html);
fclose($fp);

And thats it? No. Quizes are not the only thing which could be optimized. What else?

Quiz Results

After the user take a quiz we have to calculate their results. Obviously this can’t be done without a script.

When calculate we had to show the right record (result) from the database as created by the user.

We had to select the result by id, to select the quiz and its detail, to check if the result has image associated and if so to show it. Do we need these calculations? Not really. And thats not all. The customer wanted to allow the quiz creators to have their result displayed on their websites or whereever they want.

Imagine some user having a website with 100 000 visits per day and every visit to get the info from quizzy server.

5 users like that and it could crash. We already had the solution – to create HTML files for each the result and put the same HTML in a textarea (yes, in the created HTML!) for the users to copy and put on their sites. Here is a piece of code to see how easy this is:


//save results
$q="SELECT * FROM $T_RESULTS
WHERE poll=$quiz[id]";
$results=$DB->aq($q);

foreach($results as $result)
{

$head="<head><title>Quizzy.net - Quizzes and Personality
Tests</title></head>";

$tryit="<tr><th align=center><a target=_blank
href=\"".QUIZ_PATH.$user->username."/".$qfname."\">$quiz[title]</a>
By <a target=_blank
href=\"".SITE_URL."user.php?id=$user->id\">$user->username</a></th></tr>";

$begin.="<table style='border:1px solid
black;font-family:verdana,hebar,arial;font-size:12px;' align=center
width=600>\n";

$anotherquiz="<p align=center
style='font-size:10px;font-family:verdana,hebar,arial;'>
Another <a href=".SITE_URL.">Quizzy</a> Quiz!</p>";

$html="<tr><td align=center><h2
style='color:orange;'>$result[value]</h2></td></tr>\n";

if($result[image])
{
//select image
$q="SELECT * FROM $T_IMAGES
WHERE id=$result[image]";
$image=$DB->sq($q);

$html.="<tr><td align=center><br>
<img src='".IMAGES_PATH."$image[file]'>
</td></tr>\n";
}

$html.="<tr><td
align=center>".nl2br($result[description])."</td></tr>\n";
/* ........ */
}

Save this string in a file, update the quiz database so the calculator script know which HTML to show and all is done.

Results

While quizzy.net site is still in beta testing, the results are already there. Excellent quiz site working really fast.

Static HTML pages allowing ALL the quizes and their results to be indexed by the search engines.

A site able to hold hundred thousands of users in a shared webhost. And it works fast!

Conclusions

– Dynamicly create static HTML files with PHP to reduce the server loads

– Allow users to use the generated HTMLs for their own

– Improve search engine optimisation with the static files

– Allow hundred thousands of users to visit your site without database server crash

Bobby Handzhiev is a senior developer in PIM Team Bulgaria

http://pimteam.net

admin@pimteam.net

Table of contents

Read more

Local News