martin05rc Posted June 9, 2010 Share Posted June 9, 2010 What's the best practice in coding paths throughout a site so you don't get bit if the directory structure changes at a later time? For example: public-html forms myform.php common header.php index.php To refer to "header.php" from "myform.php" I have two choices: require_once('../common/header.php"); or require_once($_SERVER['DOCUMENT_ROOT'] . '/common/header.php'); (is there a third choice?) The problem with the first choice is that it breaks if I move "myform.php" to another location in the hierarchy. The second form works fine but is verbose and unnecessary for files located at the document root. However, if you were to have a file at document root and then decide to move it to, say, the "common" directory, you'd need the extra code to make sure that things don't break. Is there a way to set a global variable that would lookup and store the document root once and have to used --perhaps by default-- by all scripts for a particular domain? How would this work for virtual hosting, where you'd have multiple domains out of one machine? Again, looking for best practices. Feel free to suggest an entirely different approach. Thanks, -Martin Quote Link to comment https://forums.phpfreaks.com/topic/204329-looking-for-best-practice-regarding-paths-in-includerequire/ Share on other sites More sharing options...
Psycho Posted June 9, 2010 Share Posted June 9, 2010 I will use a variation on the last code example you provided. I will have a config.php or similar page that is utilized on any pages. This will include things such as database connection info and paths (of course this is not located in a web accessible folder). In that file I will create variables for the different folders I use. These may be internal paths (i.e. for the server to access, such as includes) or they may be external paths such as to use for image links that the user will access. This allows me to easily change the directory structure without recoding all the pages. Also, the paths are never relative. Here is a good article which speaks to file structure with respect to security and implements a manner to create those path variables. http://www.phpguru.org/static/ApplicationStructure Quote Link to comment https://forums.phpfreaks.com/topic/204329-looking-for-best-practice-regarding-paths-in-includerequire/#findComment-1070115 Share on other sites More sharing options...
martin05rc Posted June 9, 2010 Author Share Posted June 9, 2010 Interesting. Thank you. Do you have examples of config.php and template.php that I may have a look at? This question is outside the scope of this list: How do you deal with the sort of directory structure you are suggesting with a tool like Dreamweaver? It seems that it isn't happy with anything that falls outside of the www root directory. Thanks, -Martin Quote Link to comment https://forums.phpfreaks.com/topic/204329-looking-for-best-practice-regarding-paths-in-includerequire/#findComment-1070122 Share on other sites More sharing options...
Psycho Posted June 9, 2010 Share Posted June 9, 2010 Here is one example. In this project all pages will include the index.php file at the web root of the site. All that file basically does is set the root path and includes a file (main.php) which is not in a web accessible location. here is part of that file: $_PATHS['root'] = dirname(dirname(__FILE__)) . DIRECTORY_SEPARATOR; //... include ($_PATHS['root'].'main.php'); Then in the main.php file I will set all the other paths as follows: $_PATHS['includes'] = $_PATHS['root'] . 'includes' . DIRECTORY_SEPARATOR; $_PATHS['modules'] = $_PATHS['root'] . 'modules' . DIRECTORY_SEPARATOR; $_PATHS['classes'] = $_PATHS['root'] . 'classes' . DIRECTORY_SEPARATOR; $_PATHS['templates'] = $_PATHS['root'] . 'templates' . DIRECTORY_SEPARATOR; As for how you do this with DreamWeaver, I have not a clue. Quote Link to comment https://forums.phpfreaks.com/topic/204329-looking-for-best-practice-regarding-paths-in-includerequire/#findComment-1070125 Share on other sites More sharing options...
martin05rc Posted June 9, 2010 Author Share Posted June 9, 2010 To make sure I got the intent. In your example every file in the site would have at the top: require_once($_SERVER['DOCUMENT_ROOT']."/index.php"); Thanks, -Martin Quote Link to comment https://forums.phpfreaks.com/topic/204329-looking-for-best-practice-regarding-paths-in-includerequire/#findComment-1070137 Share on other sites More sharing options...
trq Posted June 9, 2010 Share Posted June 9, 2010 You would be much better of looking into set_include_path then putting all your libraries within your include path. Quote Link to comment https://forums.phpfreaks.com/topic/204329-looking-for-best-practice-regarding-paths-in-includerequire/#findComment-1070142 Share on other sites More sharing options...
martin05rc Posted June 10, 2010 Author Share Posted June 10, 2010 You would be much better of looking into set_include_path then putting all your libraries within your include path. I tried this: <?php set_include_path($_SERVER['DOCUMENT_ROOT']); ?> ... <?php require_once("/common/nav.php"); ?> before I had to use either of these two forms: <?php require_once("../common/nav.php"); ?> or <?php require_once($_SERVER['DOCUMENT_ROOT'] . "/common/nav.php"); ?> This solution works well for my original example. Seems simple enough to add to every file. Any issues I should be aware of? To boot, it solves a problem that Dreamweaver CS4 has with regards to resolving any includes that have anything other than an explicit path string in them. Thanks, -Martin Quote Link to comment https://forums.phpfreaks.com/topic/204329-looking-for-best-practice-regarding-paths-in-includerequire/#findComment-1070152 Share on other sites More sharing options...
trq Posted June 10, 2010 Share Posted June 10, 2010 You need to be careful when setting your include path that you don't wipe out what was originally in there. This may prevent you from using things like pear. So, instead of.... <?php set_include_path($_SERVER['DOCUMENT_ROOT']); ?> You might want..... <?php set_include_path(get_include_path() . PATH_SEPARATOR . $_SERVER['DOCUMENT_ROOT']); ?> I would also be more inclined to actually put the common directory on my path if that's where all your common functionality lives. Quote Link to comment https://forums.phpfreaks.com/topic/204329-looking-for-best-practice-regarding-paths-in-includerequire/#findComment-1070157 Share on other sites More sharing options...
martin05rc Posted June 10, 2010 Author Share Posted June 10, 2010 You need to be careful when setting your include path that you don't wipe out what was originally in there. This may prevent you from using things like pear. <snip> I would also be more inclined to actually put the common directory on my path if that's where all your common functionality lives. Thanks for the tip. Very important. I guess this takes me back to site structure, which really wasn't the topic of this thread...but it happens. In my case right now "common" just has "header.php" and "nav.php". I don't have much else in there. I also have a "forms" directory for, well, forms and form validation code. Is it better practice to lump it all into one directory these days? I also like the idea of having php scripts outside of the public html path as a security measure. I'll need to look into how to best implement this. Thanks again, -Martin Quote Link to comment https://forums.phpfreaks.com/topic/204329-looking-for-best-practice-regarding-paths-in-includerequire/#findComment-1070160 Share on other sites More sharing options...
martin05rc Posted June 10, 2010 Author Share Posted June 10, 2010 I would also be more inclined to actually put the common directory on my path if that's where all your common functionality lives. The other point I should make is that I think I prefer to be able to type in includes where I know that "/" means www root. By adding an include path to the public html directory this is accomplished and the world makes sense (OK, at least to me). Having said that...How is this affected by virtual hosting, if at all? Should I be concerned about the include path for site B being affected by the redefined include path for site A? Maybe I need to RTFM on "set_include_path", which I'll do right now! Thanks, -Martin Quote Link to comment https://forums.phpfreaks.com/topic/204329-looking-for-best-practice-regarding-paths-in-includerequire/#findComment-1070163 Share on other sites More sharing options...
trq Posted June 10, 2010 Share Posted June 10, 2010 I work with allot of oop code and I have my own framework of sorts (we'll call it foo), so things may be a little different, but you should be able to apply similar practices. If this is the structure your hosting has given you (again, I use my own servers so this is just a guess at an example.... [pre] /home/yourusername /htdocs [/pre] I would make my own libs directory and place it on the include path. [pre] /home/yourusername /htdocs /libs [/pre] I would then place my framework within libs.... [pre] /home/yourusername /htdocs /libs /Foo /Config /Controller [/pre] Then, within my php scripts I can easily include the classes I won't by simply using.... <?php include 'Foo/Controller/Front.php'; ?> This (pseudo) namespaces all my own libs into the Foo directory and is exactly how Pear works. Of course this ends up getting taken further by using an autoloader so I don't really have to include anything at all. Given the above structure, using the Pear/Zend naming convention and using this simple autoloader.... function __autoload($class) { require_once str_replace('_', '/', $class) . '.php'; } I can now just instantiate classes without even needing to include them. eg; $fc = new Foo_Controller_Front; This might be getting a bit too far ahead of your needs but I'm just giving you an example of what can be done. Quote Link to comment https://forums.phpfreaks.com/topic/204329-looking-for-best-practice-regarding-paths-in-includerequire/#findComment-1070175 Share on other sites More sharing options...
martin05rc Posted June 10, 2010 Author Share Posted June 10, 2010 This might be getting a bit too far ahead of your needs but I'm just giving you an example of what can be done. No, it's great. I'm coming from C/C++ development (both embedded and desktop applications) into web development and need to get a few good shoves in the right direction. One of my primary concerns is that of ensuring that I have a good, clean and scalable site structure. Can you recommend any books or web articles that might cover more advanced PHP topics like these? Going back to my basic question of the document root path, the issue I ran into using the above technique is that it doesn't seem to work with embedded PHP snippets: <?php set_include_path(get_include_path() . PATH_SEPARATOR . $_SERVER['DOCUMENT_ROOT']); ?> ...some HTML... <?php require_once('/common/header.php'; ?> ...more HTML... <?php require_once('/common/nav.php'; ?> Both "require_once" statements fail because it can't find the file. Is there a way to deal with this other than trying to merge it all into one <?php ... ?> block? Thanks, -Martin Quote Link to comment https://forums.phpfreaks.com/topic/204329-looking-for-best-practice-regarding-paths-in-includerequire/#findComment-1070241 Share on other sites More sharing options...
trq Posted June 10, 2010 Share Posted June 10, 2010 If the common directory is within your document root you need to remove the slash on the front of it. As for books or articles, I'm really not sure. The way I described above is pretty much how most of the big frameworks do it. Quote Link to comment https://forums.phpfreaks.com/topic/204329-looking-for-best-practice-regarding-paths-in-includerequire/#findComment-1070262 Share on other sites More sharing options...
martin05rc Posted June 10, 2010 Author Share Posted June 10, 2010 If the common directory is within your document root you need to remove the slash on the front of it. Right, I understand that. The problem is that not all files are at document root. My original intent here was to have a way to have the same code for any and all pages --regardless of location in the directory tree-- to include such things as headers, footers, navigation, etc. My index.php is mostly HTML with three <?php ... ?> include blocks. Maybe I need to find a way to have it be all php so that I can use set_include_path() to then be able to refer to included files with respect to the document root rather than whatever the current directory might happen to be. Does anyone use chdir() for these kinds of things? -Martin Quote Link to comment https://forums.phpfreaks.com/topic/204329-looking-for-best-practice-regarding-paths-in-includerequire/#findComment-1070516 Share on other sites More sharing options...
trq Posted June 11, 2010 Share Posted June 11, 2010 then be able to refer to included files with respect to the document root rather than whatever the current directory might happen to be. That is exactly what your current setup should do. Quote Link to comment https://forums.phpfreaks.com/topic/204329-looking-for-best-practice-regarding-paths-in-includerequire/#findComment-1070592 Share on other sites More sharing options...
martin05rc Posted June 11, 2010 Author Share Posted June 11, 2010 then be able to refer to included files with respect to the document root rather than whatever the current directory might happen to be. That is exactly what your current setup should do. To be clear, this: <?php set_include_path(get_include_path() . PATH_SEPARATOR . $_SERVER['DOCUMENT_ROOT']); ?> ...some HTML... <?php require_once('/common/header.php'; ?> ...more HTML... <?php require_once('/common/nav.php'; ?> ...doesn't work. Are you saying that it should? -Martin Quote Link to comment https://forums.phpfreaks.com/topic/204329-looking-for-best-practice-regarding-paths-in-includerequire/#findComment-1070605 Share on other sites More sharing options...
trq Posted June 11, 2010 Share Posted June 11, 2010 As I said, you need to remove the front slash. Quote Link to comment https://forums.phpfreaks.com/topic/204329-looking-for-best-practice-regarding-paths-in-includerequire/#findComment-1070628 Share on other sites More sharing options...
martin05rc Posted June 11, 2010 Author Share Posted June 11, 2010 As I said, you need to remove the front slash. My apologies. I wasn't paying attention. I kept thinking of the concatenated path and include needing to form a legal path to the file, which would require a slash. Of course, that's not how the mechanism work. Problem solved and lesson learned. Thank you, -Martin Quote Link to comment https://forums.phpfreaks.com/topic/204329-looking-for-best-practice-regarding-paths-in-includerequire/#findComment-1070670 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.