I wrote a small PHP application that I’d like to distribute. I’m looking for best practices so that it can be installed on most webhosts with minimal hassle.
Briefly: It’s simple tool that lets people download files once they login with a password.
So my questions are:
1) How should I handle configuration values? I’m not using a database, so a configuration file seems appropriate. I know that other php apps (e.g. WordPress) use defines, but they are global and there is potential that the names will conflict. (Global variables also have the same problem, obviously.) I looked at the “ini” file mechanism built into PHP. It only allows comments at the top – so you can’t annotate each setting easily – and you can’t validate syntax with “php -f”. Other options?
2) How to handle templating? The application needs to pump out a form. Possibly with an error message. (e.g. “Sorry, wrong password.”) I’ve have a class variable with the HTML form, but also allow an external template file to be used instead (specified in the config). I do some trivial search and replace – e.g. %SCRIPT% to the name of the script, %STATUS% to hold the error message. This feels a bit like reinventing the wheel, but including a templating system like Smarty is overkill. (Plus they may already have a templating system.) Other options?
3) i18n – There are only 3 message strings, and gettext doesn’t seem to be universally installed. Is it such a bad idea just to make these three strings parameters in the config file?
4) How to best integrate with other frameworks? My app is a single class. So, I thought I could just include a php script that showed how the class was called. It would be a starting point for people who had to integrate it into another framework, but also be fine as-is for those not interested in customizing. Reasonable?
5) GET/POST parameters – Is it bad form for a class to be looking at $_GET and $_POST? Should all values be passed into my class during construction?
You can use a php file like this:
<?php return array( 'option1' => 'foobar', 'option2' => 123, //and so on... ); ?>
And in the main class just use:
$config = (array) include 'path/to/config/file';
And if you plan to mostly distribute your class as a component in other applications, then simply put config array/object as a parameter in your class’ constructor and leave the details to the user.
For such simple application the method your described should be enough. Remember that one can always extend your class and overload your outputting method with his own.
As mentioned before, for 3 variables anything more than storing them as config is just overkill.
Comment each public method (or even better also protected and private ones) with explanations what do they do and what parameters are needed. If you combine that with an example, it should be enough for most users.
GET vs POST
Your class uses passwords and you even think of sending them via GET? 😉
Think of browser history, referer headers etc – your users’ passwords would be visible there.
Can config be local to class instances? Or could you create a little class that you could create an instance of to query for config values? Also prepending any global vars with you application’s name should go some way to stop clashes.
If your templating is really simple, just write a short templater. It’ll be easier than trying to fend off problems people get with any 3rd party templater. It might also simplify licensing issues. If you start worrying about what they already have, you’ll never release anything. There are too many combinations.
For 3 strings? Yeah do those the same way you’re handling config.
Good comments throughout with an intro explaining how you use the class.
I don’t think so. If it bothers you, you could use default arguments to use given arguments first, then search for GET/POST values if none are provided (though that might be a security risk)
There are other things to take into consideration. Lots of people are on shared hosts and as a result, don’t have control over their php.ini or their php version. You need to make sure you’re only using features that are as commonplace as possible.
One example is that shorttags aren’t enabled on some hosts (you have to use
<?php ... ?> and
<?php echo "..."?> instead of
<? ... ?> or
<?= "..." ?>) which can be a royal PITA.
In addition to Krzysztof’s good advice:
- If you use functions that can be disabled, use
function_exists()to ensure they’re available.
@missing_function()makes PHP die silently without any error logged.
- You can’t rely on things that can be disabled/changed via
ini_get()to adapt to different settings.
magic_quotesare enabled, strip slashes only on from your copy of input – don’t modify global arrays! Security of some lame code may rely on these slashes being present.
- Expect that users will mindlessly copy&paste code from your documentation/website.