Join 136,907 PHP Programmers for FREE! Get instant access to thousands of PHP experts, tutorials, code snippets, and more! There are 1,765 people online right now. Registration is fast and FREE... Join Now!
I'm learning PHP, and figured making a basic RPG with my friend (an artist of sorts) would be a decent enough, fun starting place. I'm also trying to optimize my database while I do it. Unfortunately my host does not allow persistent connections (their loss really )
The method I've been using is working fine so far, but figured I'd run it by some of the more experienced PHP'ers to make sure it's alright.
Basically, there are pages that the user never sees - such as the pages that process the battles (based off of input from a form), when a user discards an item, etc. Essentially, I thought I needed to update the database on every page, because if the user walks away / closes the browser (or really just ends the session), then I lose the data.
Then I got the idea that I don't need to connect, or do queries, on the pages that the user doesn't see. Since each page the user actually sees needs to connect to ensure they see the right data, I've been queueing up the requests using session variables, and then performing those queries on a page already connected, since according to my host, connecting to a db is 25 times more stressful than a query - so if I cut down on connections, then I'm saving usage.
Here's what I mean.
On a battle processing page, which the user doesn't see (they get redirected through PHP headers):
You won't see anything wrong with this now, but from a design standpoint this could spell trouble much later down the road. Why? Well you are shifting your workload from one page to another. This will lead to problems later on very popular main pages of the site, like the main index page of the game. You will find your main page executing the workload of battles from the battle page, adjusting inventory from an inventory page, adding health because they drank a potion on the item page etc. All these activities have nothing to do with presenting the relevant content on the main page they see.
This also becomes a logistical nightmare for any new programmers you have come on board. Because if I came on board and I noticed a bug in your battle sequence, I expect to go to a battle page and see where all the battle related functions, queries, procedures are. I don't want to hunt down which pages follow it to find the queries I am searching for. I don't want to see "Oh after they do the session adjustments, they redirect to the main page, I have to go there to find the queries".
In design terms this is called "tight coupling" where one page (your battle page) is tightly coupled to your main page to do its work. Without the main page the battle info won't get updated.
Lastly what if you run into pages that have multiple redirects to other pages? You may find yourself needing to replicate your queries across multiple pages because there are multiple redirects (paths they could take). For instance, if I do my battle and go to the battle page where it redirects me back to main because I won (and does the query to update battle info on the main page) fine, but if I lost maybe I go to another screen where I get a status report of what units I lost (and again would have to update my battle info there).
And contrary to what your host has told you, it is harder to create a connection than to run the query, it isn't that much more and doesn't degrade performance terribly. If you are interested in performance purposes, look into the singleton design pattern which will allow you to reuse connections that have been established already (if you are using other databases other than mysql) and mysql already does this.
But yeah, it will work, but it will be huge problems for you later.
This post has been edited by Martyr2: 28 Mar, 2008 - 08:35 AM
Thanks for your viewpoints. So basically, coupling is a bad programming practice.
However I think you are overestimating the coupling that I'm doing. Only pages that the user doesn't see are coupled to another page. So in your example where you drink a potion on the item page, that action is processed on a separate page, the queries are queued, and then the next page they see again - which would be the item page - processes that action.
In terms of the multiple redirects, I cannot see where that would be practical. What is going on is that information is added to a string stored in $event as the battle is processed, which is stored as a session variable, and displayed on the main page. So, regardless of it you won or lost, you would still be on the same page.
Yes, you want to strive for a loose coupling if possible, you want each page to be independent. This will allow you to take out pages later (or replace them) without it effecting other pages and how they work.
Whether it is a page they see or not, makes no difference. A coupled page is a coupled page. Coupling is going to hurt you as the programmer who has to go in and edit the pages that are coupled. Coupling hurts the designers and programmers, not the end users.
And I get what you are saying by queue the actions for a page that has a database connection. I am telling you that a page on items shouldn't be doing the work that your page that a user can't see should be doing. Establish the connection on the page they can't see, do the work relevant to that page. Queuing up requests for other pages to process doesn't do anything but force you as a programmer to keep track of whos tasks are done where instead of just going straight to the page designed for the work and doing the work there.
Like I said, database connections are not that harsh. ALLLLL the other websites in the world typically open a connection on the page, do the work, close it. And since most of these sites do it, the process of connecting to a database has been actually streamlined over time. It won't be as fast as a query ever just because it has to ask for resources, but backend databases like MySQL (Which I am sure you are using here) handles connections very well using things like pooling etc.
As for multiple redirects, you have them all the time. You go to different pages based on all sorts of criteria. Check a checkbox on a form and hit the button will take you to one page, leave it unchecked and hit the button will take you to another. If the checkbox reads "change character" obviously if you hit the button you might be taken to a character changing screen. If you don't change it, you go to main page.
I am not overestimating your coupling, I am just saying that is what you are doing from a design perspective when you do what you are doing. If it works for you, fine go ahead. Just trying to lend you the advice you asked for is all.
Queuing up requests for other pages to process doesn't do anything but force you as a programmer to keep track of whos tasks are done where instead of just going straight to the page designed for the work and doing the work there.
Well Said .
One of my previous projects was an RPG based php game; It started out nice because I was ambitious how to design its structure so I took it slow and make sure everything is clean, easily readable for future programmers and customizable. I got occupied with the logic of the game and let go of my programming thoeries and started messy coding in hopes of cleaning them one day. That day never came. I had sometime similar to you; redirects on pages and and I dont know about you but Database Calls in every page.
Once I introduced the backend coding to some php programmers, it was embarrassing I must say. There was a lot of useless junk as well as useless queries and calls. Its design was ruined because my objects would interfere with one another. Ofcourse I learned my lesson and have improved my abilities regarding coupling and data management.
There is a lot of thinking required for this sort of application programming, I hope you all the best and it is a thrilling experience .
I realize that this is extremely sloppy, and hard to read, even if I alone am working on it.
I am using MySQL, and all I've been trying to do is avoid connections. I'll take your word Martyr that it's not too stressful.
I've got some other program cleaning to do on the battle page (spent half an hour copying and pasting blocks of code - it wasn't until five seconds after I was done I thought of functions), so when I'll do both in one shot.