tags:

views:

550

answers:

4

I'm always interested in more efficient ways and learning new things. Right now, I am using the code <?php include('config.php'); ?> in each and every file. Depending on where the file is in my the folder structure, I would have <?php include('../config.php'); ?> or even <?php include('../../config.php'); ?>. How can I make it more efficient? Is there a way to just have it my config.php in root and make everything in root require config.php?

+8  A: 

Put the path containing config.php in your php include path and then you can simply do this:

include 'config.php';

or better yet:

require_once 'config.php';

require is preferred over include because it triggers an error instead of a warning when a file cannot be included for some reason (e.g. file not found, permissions error, etc.). The _once suffix is a good addition to make sure the same file isn't needlessly included multiple times.

Also, please note that you don't need the parenthesis around 'config.php' in your include call. include is not a function in php. It's a language construct. The parenthesis just serve as a needless grouping not unlike this example: $myVar = (2 + 2);.

Asaph
Special thanks for the note on parenthesis .
Doug
+2  A: 

You can make a base dir constant

define('BASE_DIR', realpath(__FILE__));

Put that in your index.php

Then you can do

include BASE_DIR . 'config.php';
alex
this is handy for many different uses too - it's always good to have some path constants defined once for your application.
nickf
I usually have a BASE_DIR and DOC_ROOT .. BASE_DIR for directories that PHP uses, and DOC_ROOT as a prefix for HTML relative paths etc
alex
+10  A: 

there is a way to include a file automatically (auto_prepend_file ini setting), however the biggest improvement you can make is to abandon the usage of multiple php files and use index.php as a single entry point for the whole website.

suppose you write a SO clone ;) with the pages "questions", "tags", "users", etc. On each page you need some generic php stuff (db, session) + common html elements (header, footer). A popular approach is to have a bunch of php files (questions.php, tags.php, users.php) each of them includes the common stuff. For example, users.php will look like this then

include 'db.php';
include 'session.php';
include 'html.header.php';
.....users-specific stuff 
include 'html.footer.php';

This is quite tedious (you have to repeat lots of code) and inflexible (think adding a sidebar to all pages on the site). My suggestion is to make includes "inside out" that is, have a "common stuff" file that includes page-specific code:

 # index.php
 db functions
 session functions
 html header

 $page = isset($_GET['page']) 
   ? preg_replace("/\W+/", "", $_GET['page'])
   : "home";
 include "$page.php";

 html footer

Thus you'll have a single entry point on the website - this is more flexible and better for debugging. The only drawback is that urls are less "nice" (user.php vs index.php?page=user), but this can be easily solved with mod_rewrite

stereofrog
care to elaborate? in what way is that an improvement? performance, maintainability, etc?
nickf
As long as there's some sort of templating going on (which there would have to be) I guess that works pretty well as a reframing of the problem.
Tchalvak
I like this answer the best. There are many ways to expedite this process such as using a framework to automate it for you. I can recommend some if you like.
Tres
@Trest Recommend away...
Doug
You'd probably be better off being pointed in the direction of a well established question on clean starting frameworks, since they'd give you a broader picture of the different options and how they rate against each other. One thing that I will say is: use templating, regardless of how you end up doing it, the separation of php logic from html logic will simplify your work 20 fold, as I eventually learned to my chagrin.
Tchalvak
http://stackoverflow.com/search?q=simple+php+frameworks There you go, pick a question or two with a lot of answers, and you'll get a good overview of the community preferred frameworks. *smiles*
Tchalvak
Your regex maybe could be /[a-z0-9-]+/i ? I often find for security it is better to whitelist then blacklist. That regex will take *slugs-like-this-too4*.
alex
I liked how you answered my next question with the mod_rewrite comment. SEO matters to me, so mod_rewrite is a definite.
Doug
@alex what's wrong with slugs-like-that-too4?
Doug
Finally got around to implementing this. Awesome!
Doug
A: 

Different options that can be combined:

  • Make path definitions in a resources file that won't be tracked in your source control. e.g. define('LIB_PATH', '/home/tchalvak/project/');

  • Specify an autoprepend file and set that up in the php.ini. e.g. including a global, used-everywhere list of scripts, which you can add to or subtract from on the fly.

  • Finally, a little bit of path-string-manipulation trickery that I found or came up with, I forget which:

    require_once(substr(__FILE__, 0, (strpos(__FILE__, 'lib/')))."resources.php"); // require a file in a specific relationship to another known file, regardless of the actual path involved, and without dealing with any defines.

Tchalvak
Plus putting a file directly into the php include path as Asaph says above. Strangely, I've never actually done it that way. I wonder if there is a disadvantage when sharing projects or something? Not sure.
Tchalvak