Allegro.cc - Online Community

Allegro.cc Forums » Off-Topic Ordeals » How to make clean PHP5 websites

This thread is locked; no one can reply to it. rss feed Print
 1   2 
How to make clean PHP5 websites
Simon Parzer
Member #3,330
March 2003
avatar

Quote:

That's exactly what it comes down to. It doesn't mater if you use PHP, ASP, RUBY, etc -- write clean code. Seperate your code into tiers of Application Framework, Business, Database Logic, Presentation and you'll be coding like a pro. Writing the code isn't the hard part, it's making it clean, maintainable, documented, and killing it's bugs that's the real hard part.

I've written a PHP website including a small CMS without seperating code and presentation. At all. ~3500 lines of code. It's the typical PHP site where the average PHP file consists of 50% code and 50% "echo" output commands. It has been running for more than a year now and I never had problems finding bugs or maintaining it.

Quote:

The problem I have is that I'm using a minimal Ubuntu set up within a virtual environment and I'm not too familiar with its workings since I run Gentoo as my primary distro (and I much prefer Gentoo to any other distribution that I've tried). The thing about Ubuntu(Debian) is that I can't seem to properly uninstall packages -- the configuration files seem to stay in the system. To make my installation 'organised' again is to start over.

Use aptitude.
apt-get remove --purge <package> to remove the config files.
aptitude purge <package> to do the same with aptitude.
Aptitude does what apt-get can't. It maintains constraints. So, if you install Package X which automatically installs Y and Z and then remove X three years later, aptitude will remove Y and Z, too.

Tobias Dammers
Member #2,604
August 2002
avatar

Quote:

$pageData = get_template("pages/thread.tpl", $posts);

One piece of advice: Use .php extension on all include files. This way, it is impossible to read the php code in them even if requested directly. Suppose an include file contains a database username and password; if the extension is .php, the server will happily execute it, setting two variables and outputting nothing - and the client reads an empty page. If the extension is something else, the server will treat it as plain text and send it through http as-is; the client can then read your database login.

A template system isn't that hard to do really. All you need is an index page that loads the content pages based on an input variable (either from $_GET or from $_REQUEST). Just don't forget to validate. It can be as easy as:

1<?php
2ob_start();
3@include('head.php');
4 
5function validate_page($page) {
6 // this should prevent cross-site scripting.
7 return './pages/'.basename($page);
8}
9 
10$page = validate_page($_GET['page']);
11if (!$page)
12 $page = './pages/home.php';
13 
14@include($page);
15@include('foot.php');
16ob_end_flush();
17?>

Then put the doctype, header, stylesheet reference and whatnot, into 'head.php', a closing </body></html> into 'foot.php', and make every link say something like '?page=foo.php'.

---
Me make music: Triofobie
---
"We need Tobias and his awesome trombone, too." - Johan Halmén

CGamesPlay
Member #2,559
July 2002
avatar

Quote:

One piece of advice: Use .php extension on all include files. This way, it is impossible to read the php code in them even if requested directly.

Better advice: don't put your code in the web root.

--
Tomasu: Every time you read this: hugging!

Ryan Patterson - <http://cgamesplay.com/>

Tobias Dammers
Member #2,604
August 2002
avatar

Even better: Make them .php AND put them somewhere that's not the web root. And protected through .htaccess.

---
Me make music: Triofobie
---
"We need Tobias and his awesome trombone, too." - Johan Halmén

CGamesPlay
Member #2,559
July 2002
avatar

From a security standpoint, you should get it out of your head that naming your file in a particular way somehow gives it more security. Just because one directory on the system is configured to execute files with a .php extension doesn't mean others are. Especially when those others lie outside of the web root: if someone manages to get access outside of that, they have bypassed Apache's configuration already.

In fact, once you leave the web root, I'd say the most likely path to hacking comes from the local machine: someone with access to the file system browsing around. In those cases, I'd wager that naming your files with .php would make them more likely to be found. If that scenario seems unlikely to you, then consider how unlikely the idea that a file outside of your web root is accessed in the first place.

As a side note, if it's outside the web root, protecting it through htaccess won't do any good, since it's outside the web root: Apache won't parse the file anyways (since Apache won't serve the file, though, it doesn't make a difference).

Now, since naming your templates with a .php extension gives them marginal security benefits if they're stored in the webroot, and doesn't cause any problems either way, why not do it anyways? For the same reason you use a for loop instead of a goto statement. Sure, both ways will work, but in the end one looks neater and tells you more information about what the construct does. Likewise, why not name all the image files on your server with a .img extension? Both ways will work, but in the end one gives you more information about what the files are.

--
Tomasu: Every time you read this: hugging!

Ryan Patterson - <http://cgamesplay.com/>

Archon
Member #4,195
January 2004
avatar

By "putting them outside the web root", you mean:

var/www/website/root
var/www/website/root/imgs
var/www/website/root/css
/var/www/website/code

Where the root directory is

/var/www/website/root/

?

CGamesPlay
Member #2,559
July 2002
avatar

Ideally, yeah. Then you simply have a single go.php file that you map your URLs to, and that file passes control to the application handlers which lie outside of your web root.

The simplest way to achieve this is using mod_rewrite. In this example I don't have the ability to change my web root, so I use mod_rewrite to mask it.

1wwwroot/
2 app/
3 code/
4 controllers/
5 page.php
6 models/
7 page.php
8 views/
9 layouts/
10 layout.html
11 pages/
12 about.html
13 webroot/
14 images/
15 logo.png
16 main.css
17 engine/
18 Cx.php

Then I use this mod_rewrite rule set:

RewriteEngine on
RewriteRule ^$ engine/Cx.php [L]
# Translate path into the webroot if not already done
RewriteRule !app/webroot/ - [C]
RewriteRule (.*) app/webroot/$1
# If file doesn't exist in webroot then use Cx
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* engine/Cx.php

The first rule sends the index page to my engine. The second and third rules translates paths into the app/webroot/ directory. The third rule checks if the given path (now translated into the webroot directory) exists. If it does not, it hands the URL to my engine.

Using this setup, I can place static objects into the webroot, and it will be clean of all code. Also, it is impossible* to access any of the code.

* In any security discussion, absolutes such as "impossible" are assuming normal operation of the software involved, i.e. that there are no exploits in mod_rewrite or apache.

--
Tomasu: Every time you read this: hugging!

Ryan Patterson - <http://cgamesplay.com/>

le_y_mistar
Member #8,251
January 2007
avatar

even better idea, chroot apache or run ALL other services in a VM, only have ssh and security related tools running on the host (i.e.: snort, tripwire, denyhosts...), anything else, VM...and do rsyncs, and apply CGP's method as well.

-----------------
I'm hell of an awesome guy :)

Michael Jensen
Member #2,870
October 2002
avatar

Quote:

I thought ASP.NET could use C# too...

of course it can, it can also use j#, or any other .NET language -- you can add your own languages of course (there are some wrappers that add LUA to .NET) -- and soon .NET will have ruby also ("IronRuby").

Quote:

Yeah, you think you have the timezones right, but if they change (like... this year), you have to update your code to cope. Not to mention you have to deal with time zones supporting and not supporting DST, as well as half hour time zones.

I don't really do anything with time zones, so I'm fuzzy here, but I remember getting an email from microsoft about their API operating differently now that the daylight savings times are different. So there is an API that handles time zones/daylight savings times that's built in -- I've just never used it -- or needed to.

CGamesPlay
Member #2,559
July 2002
avatar

Quote:

(there are some wrappers that add LUA to .NET)

"Compilers". They actually compile the language to CIL.

Quote:

So there is an API that handles time zones/daylight savings times that's built in -- I've just never used it -- or needed to.

Like I said, it works for local time and UTC. No others. And it doesn't know what time zone local time is, it relies on Windows' knowledge of it.

--
Tomasu: Every time you read this: hugging!

Ryan Patterson - <http://cgamesplay.com/>

 1   2 


Go to: