Application StructureAn error commonly made with applications and websites is made right at the very start - when laying out the structure of your application. It can make the difference between coding being a joy, and a chore. Not only this, but it can also help to make your app/website more secure, by preventing you having to remember important tasks like authentication. So onward... First of all. Let me tell you this. You are not special. You are the all singing all dancing crap of the world. Not everyone thinks like you. Not everyone will understand your directory names. I tell you, it's infuriating seeing directories with three letter names which contain absolutely nothing related to what you were expecting. For example, a "lib" directory which doesn't contain "lib"raries, or a "bin" directory which doesn't contain "bin"aries. Be verbose! It doesn't hurt. Trust me. So with supersized directory names firmly in mind (and citizens of the US of A, I'm afraid there's no fries with that), I present to you, the directory structure that I have, over the past three or four years, evolved to be using. Go ahead, click the pluses - they work... OverviewThe structure is laid out so that all major directories are at the same level, in the main application directory (in this case "www.example.com"). This structure suits both applications and websites equally well, since as we'll see paths and DocumentRoots can easily be customised. Normally though, the DocumentRoot would be the htdocs directory (so called as that's the name that the Apache webserver uses by default). So here's a break down of each directory... cronHolds all scripts that are run via cron, for example daily/hourly maintenance. Shouldn't be any reason why you have your maintenance scripts in another language either. Code reuse. Hoo-ya. htdocsAs noted, the DocumentRoot. Holds all the "front end" scripts - the files whose names you tap daintily into your browsers address bar. Anything to be accessible by the user. Things like CSS files, images and Jabbascript files should of course be put away neatly in their own directories. We'll get to the config.php file later. includesThe real meat of the site. All your application/site specific libraries go here. Classes, functions, you name it. Again, feel at liberty to further organise into subdirectories, in particular foreign code (eg. the jpgraph library). Again, the files shown here (prepend.php and template.php), we'll come to later. logsI don't always employ this one, but it's handy at times. Quite obviously, it's for your log files. pearNow this will probably be quite contentious. Simply put, the whole idea of a central PEAR installation gives me the willies. One upgrade can break multiple apps/websites? No thanks. Having to check every app/website when you do get around to upgrading? Double plus bad. So in each of my apps/websites there is a pear directory, in which lives a replica of the PEAR directory structure and all the PEAR code that I use. Heck if you really wanted to, you could even change the options in the installer and use the installer to manage this particular directory. That's far too much work for me though, so I use good old fashioned cut 'n' paste code reuse. Not only this, but if you're using source control, then all the PEAR code can more easily be incorporated into your repository. scriptsThis one is for shell scripts that support the app/site. Things like upload/release scripts, database import/export etc. templatesAnd finally, the templates directory. And don't be under any illusion, we aren't talking "template engine" templates. Well, I'm not. You can if you must. So there you have the directory structure. Very simple, very easy to understand, in particular if you're picking up maintenance of an app/site. This isn't all there is to it though. There's also how you structure your files. This is where you make your app easier and quicker to write, and more secure. index.php | +- config.php | | | +- Path & environment setup | +- Common libraries | +- prepend.php | ... Logic goes here | | +- template.php This here thing on the right, is how a files require()s are laid out. Starting at the top, working your way down:
So that's it. A simple yet elegant way to layout your application/website which can save you time and mullah. Notes
Link to meIf you use any of the code on this site (and if you don't I guess) or it makes your life easier, I'd appreciate a link - http://www.phpguru.org. Thanks.
Author: Helgi
Posted: 14th March 2005 14:42 Well I my self find it better to have prepend and config together in one file, because to me it's all just config stuff :-)
QuoteAlso you're only using none windows separators in the include_path (not like that's bad in anyway ;)) but I think windows has ; not : IMHO people that use the system PEAR folder for any application are stupid, because of the things you mentioned, having ya own PEAR dir is veerrrry important (= Wished more people would realize that.
Author: Arnaud
Posted: 14th March 2005 17:37 Helgi: which is why PEAR needs to improve to prevent system-wide breakdowns when you upgrade :)
Quoteps: it won't improve magically, we need to do it :)
Author: Richard Heyes
Posted: 14th March 2005 17:51 Alan Knowles:
Quote> using prepend is evil! If you're referring to the auto_prepend setting, then sure, it's nasty, which is why all the file inclusion should be done with require(). The file is only named prepend.php becuase, well, it's at the beginning. :) > another problem you have in using templates in > a third directory is that previewing the page, > without the server is difficult. you can end up > mundging paths really badly just to see get an > idea of what it will look like.. images/css > etc. Eeesh! Never develop without a webserver! :-)
Author: dravine
Posted: 14th March 2005 21:01 Developing web apps without a web server is just idiocy. How hard is it to install apache and php on your machine and develop locally? I've been doing it for years personally. People sometimes ask me why my laptop has a full suite of server apps on it, but when a server crashes or a network goes down, my productivity doesn't suffer.
QuoteGranted I'm not doing any of this on windows, and it may be a bit more difficult to get postgres etc. up and running on windows, but the benifits far outweigh the downsides. If you need MS office that bad, buy vmware and have at it. I still don't understand the folks who comment that the script doesn't use windows paths. Big deal! I've yet to see anyone using PHP on windows in a production environment. So why would you want the development environment to be grossly different from the production one?
Author: Bert Van den Brande
Posted: 15th March 2005 10:02 dravine:
Quote> So why > would you want the development environment to > be grossly different from the production one? Because not everyone has the luxury and/or knowledge to work with something else than windows as the development environment ...
Author: Greg Strockbine
Posted: 24th March 2005 06:45 A separate copy of PEAR for each website?
Quoteoh dude, I wish I hadn't stumbled across your site. This is scaring me into not using php. greg strockbine
Author: Richard Heyes
Posted: 24th March 2005 10:20 Greg Strockbine:
Quote> A separate copy of PEAR for each website? > oh dude, I wish I hadn't stumbled across > your site. This is scaring me into not using > php. From the feedback I've been getting this appears to be what the vast majority of people do. Consider the need for one version of a class for one app, and another version for another app, both on the same server. Not good.
Author: Mike
Posted: 27th March 2005 18:22 interessting article!
QuoteI like the: dirname(dirname(__FILE__)) . "/";
Author: Pies
Posted: 18th April 2005 02:46 While I agree that there's a great need to systematize the directory structure on your projects, I don't really like the one shown in the article. I wouldn't even know where to put the business logics in.
QuoteMy own structure (based on Ruby on Rails): /app /controllers /models /views /layouts default.thtml /config database.php routes.php /docs /libs /logs /public /css /img dispatch.php /scripts This one is actually from an MVC framework I develop. The /app directory holds all application's business logics (controllers), data structures (models) and templates (views). In /config you keep, well, configuration -- in my case it's database config and URL structure. /docs and /logs are obvious and optional. /libs keeps all the universal libraries, such as PEAR and PECL (if I used them). /public is for files that are directly accessible to the visitors with a minor exception for dispatch.php, which is a script that includes some libraries and runs the query. /scripts contains all the utility scripts, both cron and interactive. Of course, what is the most comfortable direstory structure depends a lot on what kind of website are you developing, and depends even more on what you're used to. I like mine :)
Author: Pies
Posted: 18th April 2005 02:48 Eh, the structure once again:
Quote/app ___/controllers ___/models ___/views ______/layouts _________default.thtml /config ___database.php ___routes.php /docs /libs /logs /public ___/css ___/img ___dispatch.php /scripts And see http://sputnik.pl/cake/ for information about Cake, the framework I use.
Author: Crache
Posted: 22nd April 2005 03:03 One thing that I don't like about the way you guys are laying out the directory structures is you seem to want to conquer the site. Though in defense of the article I think it was written with a general situation in mind.
QuoteI don't like shoving various parts of a project into lots of different directory scopes just because of some minor security benefits provided by default server configuration. I like to keep a project as isolated, simplified, flexible and compatible as possible within reasonable means. The purpose of your article was I'm sure intended to benefit those who might not otherwise put forth the due diligence in deciding how they should best organize things. If someone isn't putting effort into how their projects are organized, they are dangerous to themselves and others. :) Especially when it comes to databases, where articulated architecture can mean the difference between a 1 week job and a 3 month job. It's excellent for people to consider the file organization of a project in direct relation to how you maintain the overall idea in your mind. "Trash in, Trash out." Here's how i normally structure a typical project (and this means it might not apply to everyone's specialized project types): ------------------------------------------ /htdocs/index.php (could also be in /htdocs/<project>/) /htdocs/img/ (images relevant to site) /htdocs/<project>/inc/config/inc_db.php /htdocs/<project>/inc/config/inc_settings.php /htdocs/<project>/inc/ (code relevant to all) /htdocs/<project>/inc/inc_auth.php /htdocs/<project>/inc/inc_html.php /htdocs/<project>/inc/site/ (code relevant to site) /htdocs/<project>/inc/site/html/css/ /htdocs/<project>/inc/site/html/js/ /htdocs/<project>/inc/site/html/<template>/css/ /htdocs/<project>/inc/site/html/<template>/js/ /htdocs/<project>/inc/backend/ (code relevant to backend) /htdocs/<project>/inc/backend/cron/ /htdocs/<project>/inc/backend/img/ (could also be /htdocs/img/backend/) /htdocs/<project>/inc/backend/html/css/ /htdocs/<project>/inc/backend/html/js/ /htdocs/<project>/inc/backend/html/<template>/css/ /htdocs/<project>/inc/backend/html/<template>/js/ /htdocs/<project>/logs/ /htdocs/<project>/resources/docs/ /htdocs/<project>/resources/utils/ (misc dev/management scripts that weren't worth building into the admin interface) ------------------------------------------ Of course that would look much cleaner in a dynamic tree format, but what the hey. Someone who'd never seen this particular <project> before could easily understand where all it's relevant files are and exactly how to find what they're looking for. In this particular directory layout you can tell that /site/ is intended for a public site and /backend/ would be for the administrator of the site to manage content, mail, whatever. Or /site/ could be non-existent and there would just be a backend private application. If the site is using SSL and the secure directory is not under /htdocs/, you might have the index.php under the live secure directory, but all the other aspects of the project that don't require encrypted transfer can stay under /htdocs/ so they don't take up unnecessary processor time. Also, there are some directories you may not want to be public, so instead of hiding behind /htdocs/ and throwing it out of the project directory scope, you might want to just use an .htaccess file. Another subject which I think would be a nice addition to your article would be file naming conventions, because they're just as important as the location of the files. In fact, with really good naming conventions, depending on the size of the project, you could do away with a lot of directories. -Crache
Author: Thilo Raufeisen
Posted: 30th April 2005 15:59 The most important thing: Never put files, which contains passwords/access data, in the webroot.
QuoteAlso: Put as less as possible in the webroot. A Databaseclass should not be accessible by a client. Also the Templatedirectory. There is no need to makes them world-wide readable. Donīt rely on the php-parser. Code between <?php and ?> is not secure because itīs possible, that php crashes. In this case, the client can download the PHP-File.
Author: Ray Cauchi
Posted: 9th June 2005 14:22 I am still trying to figure how the hell to develop a web app in PHP without a server?
Quotebaffled... As for directory structure, I must say I am guilty of the libs directory (guess it could be short for libidos - somewhere to store your libido when you have a client meeting perhaps? guess it depends on the client?) I can't really fathom why installing AMP on either L or W is such an issue - it ain't that hard! Nor can I fathom why a seperate installation of PEAR per app is swo difficult - it ain't ! though the idea of centralisation is utopia, actually doing it and making it work is much harder than downloading PEAR and installing it (manually even) As for having different directories for everything, as humans we tend to put our undies in a separate drawer to our t-shirts (well, I do...) - its no different really. When I get dressed I usually wear both. I know where eahc is because i put them there. Isn't that part of getting dressed 101? Similarly, if I split my files into what I at least consider to be logical directories, and then either document that or make it so bleedingly obvious what each directory does, that if another developer needs to work on my code I can stand behind them with a paddle and justifiably hit them square across the head when they ask me whats in the PEAR directory, isn't that really just the same as putting your t-shirts in one drawer and your undies in another? I digress...back to work for fear of my Clients whacking ME across the head with that paddle...
Author: Eric
Posted: 10th June 2005 14:37 I would prefer the simple "all-purpose" structure from Richard to the more complex ones like Pie's or Crache's for a simple reason: It is so obvious than I seen at a glance where (almost) everything was supposed to be stored.
QuoteI agree that you should never store includes files, especialy ones with hardcoded passwords in htdocs but some hosting companies do not allow you to do that. Here is a few tips to make this as secure as possible when you have no other solution: - Always use ".php" as file extension instead of some ".inc" or other fancy stuffs. It does not matter for PHP to include any file with any extension, but it will prevent peoples to access the source by just typing the file URL in their browser (most HTTP servers will not recognize ".inc" extension and will process it as TEXT/PLAIN...). You may use something like ".inc.php" if you really want to. - Protect your include directory with a .htaccess (deny for all is OK since nobody is supposed to access the file with HTTP) - Never (I mean NEVER !) display error message with connection information (i.e. to NOT follow: print "Unable to connect DB using '$login' account with '$password' password";) You may think that the two first points are redundants, but it does not cost more, so use BOTH of them. I did not think anybody may be fool enough for doing what I describe in the third point until I actually seen it... (the guy posted a code sample on a forum with both the include line AND its web site URL (another thing NOT to do...)) About installing AMP on W, peoples with very few admin skills may use easyphp (www.easyphp.org). This thing will easily install Apache + PHP + MySQL + PhpMyAdmin in a few clicks with a nice GUI for starting/stopping servers. Last release (1.8) even work on a USB keys and be launched from any computer you plug it into. Just take care of cAsInG mismatch... Since windows has a no case-sensitive filesystem, it will work if you include "MyIncFile.php", even if the file name is "myINCfile.PHP". It will not on unix platform... Same thing occurs with MySQL table names since MySQL store tables as files. If you create table 'foo' and perform the request "SELECT * FROM `Foo`;", it will work on windows, not elsewhere... Eric
Author: pmcweb.at
Posted: 15th July 2005 11:50 Hint: to extend the code
Quoteini_set("include_path", "$_PATHS[includes]:$_PATHS[pear]:$_PATHS[templates]"); one has to determin the OS and set a semi-colon, if not linux. If using the PEAR, it is already done in the PEAR.php file. changing it to ini_set("include_path", $_PATHS[includes].PATH_SEPARATOR.$_PATHS[pear].PATH_SEPARATOR.$_PATHS[templates]); make it platform indepented.
Author: john
Posted: 29th July 2005 08:55 $dburl = file_get_contents("path/to/file/with/password");
QuoteThat call is fast. It keeps your password away from the visible parts of the site.
Author: Elantrix
Posted: 20th September 2005 11:03 The difference between windows and *nixes is not that big, the only time you really need to worry about this is when you are working with:
QuoteA) networking B) system calls As for the file structure. I do it like this Base dir: /www/vhosts/www.test.org/html/ index.php includes/ template/ template/xml/ public/images/ public/styles/ public/files/ pulic/scripts/ webcms/ (usually different for every website for security) var/ lang/ install/ (temp install dir)
Author: James
Posted: 31st October 2005 23:23 Here's mine. Everything is in the doc root on my development box at present, although I may move it around later.
Quotecache cache/mail cache/page cache/query cache/thumb chrome (CSS and layout images) class class/<classname> class/<classname>/class.<classname>.php (makes it easy for __autoload to find everything in PHP 5) class/<classname>/dialog.<dialogname>.php (template for popup dialog) class/<classname>/method.<methodname>.php (include template for methods that write HTML) client (JS and SWF files) data (mostly CSV files) include include/PEAR (only the PEAR files used in the app, not the whole PEAR archive) include/<packagename> servlet (specialized scripts that serve files from the database, RSS, photorolls, etc.)
Author: Krokodox
Posted: 9th November 2005 22:39 dravine:
Quote> I still don't understand the folks who comment > that the script doesn't use windows paths. Big > deal! I've yet to see anyone using PHP on > windows in a production environment. So why > would you want the development environment to > be grossly different from the production one? Wake up and smell the coffe! We are running a *LARGE* site on 20+ PHP / IIS6 / W2K3 servers with MySQL (also on W2k3!), albeit slimmed down W2K3 and IIS6 installations, with wonderful performance, stability and manageability. I would never dream of switching to Linux / Apache 1.x, not when IIS6 is excellent in multithreading, easy to configure, maintain and lock down to be PHP-only. Installation from bare-bones to up-and-running server takes less than an hour with preconfiguired LAN boot and setup scripts. Awake yet? ;-)
Author: Anurag
Posted: 15th December 2005 04:07 a bottom-up approach would suggest something like this
Quote[Basic Structure] /configuration.php -- contains gloal configuration /initialize.php -- initializes application according to environment /index.php -- document root /Frontend/ -- all frontend stuff including css,presentation pages, images, javascript etc., etc. /Backend/ -- all backend stuff including back-end scripting, business logic etc etc :)
Author: Anurag
Posted: 15th December 2005 04:27 you can extend the Frontend/ and Backend/ directories further, but for a simple web application even this structure would suffice.
Quoteconfiguration and initialization are two different things. you shouldnt combine them into the same step for portability reasons. /configuration.php simply holds application-wide configuration like database connection information, paths and so on. example define("ROOT", "/htdocs/"); define("HTTP_ROOT", "/"); define("DB_USERNAME", "..."); define("DB_PASSWORD", "..."); define("DB_DATABASE", "..."); define("DB_TYPE", "..."); // mysql/pgsql/oracle etc /initialization.php is used to initialize the application to conform to the current environment. example ini_set('include_path', ROOT); ini_set('error_reporting', E_ALL); ini_set('magic_quotes_runtime', false);
Author: Prashant
Posted: 16th February 2006 07:48 I have a small company and i just started working in php,mysql,apache. I like to make c/s arch. but i do't know how to do it will any on 1 help me pls. mail me in prashcom@gmail.com
QuoteI am using windows Xp and i m using phpdev5(compaq pack of php,mysql,apache).I need help from anyone
Author: Chris
Posted: 16th June 2008 19:10 I am curious how people display images within HTML code when it is a couple of folders down the chain?
Quote
Author: Richard Heyes
Posted: 16th June 2008 19:12 Chris:
Quote> I am curious how people display images within > HTML code when it is a couple of folders down > the chain? Just have a top level images folder and all of your image paths will start: /images/...
Author: Chris
Posted: 16th June 2008 23:04 What happens if you have a number of templates which automatically and dynamically change? Just multiple sub-folders within the main images folder?
Quote |

Comments
Posted: 14th March 2005 09:47
It has a tendancy to make code totally unreadably when you come back 6 months latter.. - Questions like 'where is this method/class defined/configured, I cant find it the include anywhere' come to mind.
I've seen code where it does all sorts of magic vodoo in prepend, let alone the portibility issues of setting up the code on another server...
another problem you have in using templates in a third directory is that previewing the page, without the server is difficult. you can end up mundging paths really badly just to see get an idea of what it will look like.. images/css etc.