Jump to content

Looking for best practice regarding paths in include/require


martin05rc

Recommended Posts

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

 

 

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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

 

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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

 

 

 

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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

 

 

 

 

 

Link to comment
Share on other sites

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

 

 

 

 

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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

 

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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

 

Link to comment
Share on other sites

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

 

 

Link to comment
Share on other sites

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

 

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.