Includes in libraries

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Tim Tyler

    Includes in libraries

    A fairly simple question:

    I have a library A which depends on library B and C.

    Currently I have:

    <?php
    include("A.inc. php");
    include("B.inc. php");
    include("C.inc. php");
    ?>

    ....in my HTML.

    This needs changing to:

    <?php
    include("../A.inc.php");
    include("../B.inc.php");
    include("../C.inc.php");
    ?>

    ....if I call it from deeper in the directory tree.

    I don't want lots of includes in my HTML. I want to write:

    <?php
    include("A.inc. php");
    ?>

    ....and to have the other includes in the "A.inc.php" file.

    However if I put:

    include("B.inc. php");
    include("C.inc. php");

    ....in the library, it doesn't fild the files when included using:

    <?php
    include("../A.inc.php");
    ?>

    ....in an HTML file some distance from the root.

    I don't want to wire absolute paths in.

    I *could* pass the "../" in as a method parameter - but that
    seems like a total mess.

    What is the best way to resolve this issue?
    --
    __________
    |im |yler http://timtyler.org/ tim@tt1lock.org Remove lock to reply.
  • Kevin Thorpe

    #2
    Re: Includes in libraries

    Tim Tyler wrote:[color=blue]
    > A fairly simple question:
    >
    > I have a library A which depends on library B and C.
    >
    > Currently I have:
    >
    > <?php
    > include("A.inc. php");
    > include("B.inc. php");
    > include("C.inc. php");
    > ?>
    >
    > ...in my HTML.
    >
    > This needs changing to:
    >
    > <?php
    > include("../A.inc.php");
    > include("../B.inc.php");
    > include("../C.inc.php");
    > ?>
    >
    > ...if I call it from deeper in the directory tree.
    >
    > I don't want lots of includes in my HTML. I want to write:
    >
    > <?php
    > include("A.inc. php");
    > ?>
    >
    > ...and to have the other includes in the "A.inc.php" file.
    >
    > However if I put:
    >
    > include("B.inc. php");
    > include("C.inc. php");
    >
    > ...in the library, it doesn't fild the files when included using:
    >
    > <?php
    > include("../A.inc.php");
    > ?>
    >
    > ...in an HTML file some distance from the root.
    >
    > I don't want to wire absolute paths in.
    >
    > I *could* pass the "../" in as a method parameter - but that
    > seems like a total mess.
    >
    > What is the best way to resolve this issue?[/color]

    Best idea is to put all your libraries in a single directory and add it
    to include_path in php.ini.

    Failing that you could look at the constant _FILE_ which, in A.inc will
    point to the full path of A.inc (I think).

    Comment

    • Tim Tyler

      #3
      Re: Includes in libraries

      Tim Tyler <tim@tt1lock.or g> wrote or quoted:

      [snip]
      [color=blue]
      > However if I put:
      >
      > include("B.inc. php");
      > include("C.inc. php");
      >
      > ...in the library, it doesn't fi[n]d the files when included using:
      >
      > <?php
      > include("../A.inc.php");
      > ?>
      >
      > ...in an HTML file some distance from the root.
      >
      > I don't want to wire absolute paths in.
      >
      > I *could* pass the "../" in as a method parameter - but that
      > seems like a total mess.
      >
      > What is the best way to resolve this issue?[/color]

      Prepending $DOCUMENT_ROOT seems like a possible resolution.

      It's not an ideal solution - since it too hinders portability,
      by wiring in an path with an absoulte element.

      i.e. if I ever want to move the library files relative to the
      webserver's document root, then they would need rewriting.
      --
      __________
      |im |yler http://timtyler.org/ tim@tt1lock.org Remove lock to reply.

      Comment

      • Tim Tyler

        #4
        Re: Includes in libraries

        Kevin Thorpe <kevin@pricetra k.com> wrote or quoted:
        [color=blue]
        > Best idea is to put all your libraries in a single directory and add it
        > to include_path in php.ini.[/color]

        Noooooooooooooo ooooooooooooo! ;-)
        [color=blue]
        > Failing that you could look at the constant _FILE_ which, in A.inc will
        > point to the full path of A.inc (I think).[/color]

        If so, that sounds like it will sort out the problem.

        There's still the expense of writing a routine to strip off the leaf -
        and including the body of this function in every library file that wants
        to include other library files - of course.

        However this is likely to be low maintenance code - and I don't mind
        duplicating it all over the place - if that's /really/ what it takes.
        --
        __________
        |im |yler http://timtyler.org/ tim@tt1lock.org Remove lock to reply.

        Comment

        • Tim Tyler

          #5
          Re: Includes in libraries

          Tim Tyler <tim@tt1lock.or g> wrote or quoted:[color=blue]
          > Kevin Thorpe <kevin@pricetra k.com> wrote or quoted:[/color]
          [color=blue][color=green]
          >> Failing that you could look at the constant _FILE_ which, in A.inc will
          >> point to the full path of A.inc (I think).[/color]
          >
          > If so, that sounds like it will sort out the problem.[/color]

          Hah!

          ``If you use a relative path for include or include_one, the path is
          relative to the running script, ie. the script that started all the
          includes. There’s no easy way to include files relative to the current
          file. This is a real hassle if you’ve got a library file that links to a
          whole lot of other files. You can use absolute paths (with
          $DOCUMENT_ROOT) but this is (obviously) less flexible.

          I’ve finally figured out a solution, using _FILE_, realpath, and basedir:

          include_once(re alpath(dirname( __FILE__) . "../relative/path/to/file"))''

          - http://www.ineffable.co.nz/archives/cat_php.html

          So I reckon something like:

          function include_once_re lative($path) {
          include_once(re alpath(dirname( __FILE__)."../".$path));
          }

          ....should patch things up - until the PHP designers fix up the problem.
          --
          __________
          |im |yler http://timtyler.org/ tim@tt1lock.org Remove lock to reply.

          Comment

          • Johan Holst Nielsen

            #6
            Re: Includes in libraries

            Tim Tyler wrote:
            [color=blue]
            > A fairly simple question:[/color]

            Well, another way (than the other answers) are to add another include
            directory by ini_set() and the "include_pa th" option.

            Regards,
            Johan

            Comment

            • Tim Tyler

              #7
              Re: Includes in libraries

              I, Tim Tyler <tim@tt1lock.or g> wrote or quoted:
              [color=blue]
              > ``If you use a relative path for include or include_one, the path is
              > relative to the running script, ie. the script that started all the
              > includes. There’s no easy way to include files relative to the current
              > file. This is a real hassle if you’ve got a library file that links to a
              > whole lot of other files. You can use absolute paths (with
              > $DOCUMENT_ROOT) but this is (obviously) less flexible.
              >
              > I’ve finally figured out a solution, using _FILE_, realpath, and basedir:
              >
              > include_once(re alpath(dirname( __FILE__) . "../relative/path/to/file"))''
              >
              > - http://www.ineffable.co.nz/archives/cat_php.html
              >
              > So I reckon something like:
              >
              > function include_once_re lative($path) {
              > include_once(re alpath(dirname( __FILE__)."../".$path));
              > }
              >
              > ...should patch things up - until the PHP designers fix up the problem.[/color]

              That fails miserably on Windows running off a local webserver.

              include_once("C :\Documents\HTM L\~TimTyler\php \test\i.inc.php ");

              ....isn't valid - you see.

              As it stands, this solution is not acceptable - since it doesn't work.
              --
              __________
              |im |yler http://timtyler.org/ tim@tt1lock.org Remove lock to reply.

              Comment

              • Tim Tyler

                #8
                Re: Includes in libraries

                Tim Tyler <tim@tt1lock.or g> wrote or quoted:[color=blue]
                > I, Tim Tyler <tim@tt1lock.or g> wrote or quoted:[/color]
                [color=blue][color=green]
                >> ``If you use a relative path for include or include_one, the path is
                >> relative to the running script, ie. the script that started all the
                >> includes. There’s no easy way to include files relative to the current
                >> file. This is a real hassle if you’ve got a library file that links to a
                >> whole lot of other files. You can use absolute paths (with
                >> $DOCUMENT_ROOT) but this is (obviously) less flexible.
                >>
                >> I’ve finally figured out a solution, using _FILE_, realpath, and basedir:
                >>
                >> include_once(re alpath(dirname( __FILE__) . "../relative/path/to/file"))''
                >>
                >> - http://www.ineffable.co.nz/archives/cat_php.html
                >>
                >> So I reckon something like:
                >>
                >> function include_once_re lative($path) {
                >> include_once(re alpath(dirname( __FILE__)."../".$path));
                >> }
                >>
                >> ...should patch things up - until the PHP designers fix up the problem.[/color]
                >
                > That fails miserably on Windows running off a local webserver.
                >
                > include_once("C :\Documents\HTM L\~TimTyler\php \test\i.inc.php ");
                >
                > ...isn't valid - you see.
                >
                > As it stands, this solution is not acceptable - since it doesn't work.[/color]

                Here is something that /does/ appear to work - at least in *my*
                development and deployment environments, on *my* test data:

                // test code...
                include_once_re lative("test.in c.php");

                function include_once_re lative($path) {
                $from = realpath(dirnam e($_SERVER["SCRIPT_FILENAM E"]));
                $to = realpath(dirnam e(__FILE__)."/".$path);

                include_once(re lative_path($to ,$from));
                }

                function relative_path ($targetfile, $basedir = '.') {
                $basedir = realpath ($basedir);
                $targetfile = realpath ($targetfile);

                // on windows, check that both paths are on the same drive
                if (substr ($basedir, 0, 1) != substr ($targetfile, 0, 1)) {
                return false;
                }

                // split each path into its directories
                $base_parts = split ('\/', str_replace ('\\', '/', $basedir));
                $target_parts = split ('\/', str_replace ('\\', '/', $targetfile));

                // ensure that there are no empty elements at the end (c:\ would cause it)
                for ($i = count($base_par ts) - 1; $i >= 0; $i--) {
                if ($base_parts[$i] == '') {
                unset ($base_parts[$i]);
                } else {
                break;
                }
                }
                for ($i = count($target_p arts) - 1; $i >= 0; $i--) {
                if ($target_parts[$i] == '') {
                unset ($target_parts[$i]);
                } else {
                break;
                }
                }

                // get rid of the common directories at the beginning of the paths
                $common_count = 0;
                for ($i = 0; $i < count($base_par ts); $i++) {
                if ($target_parts[$i] == $base_parts[$i]) {
                $common_count++ ;
                } else {
                break;
                }
                }
                for ($i = 0; $i < $common_count; $i++) {
                unset ($base_parts[$i]);
                unset ($target_parts[$i]);
                }

                // build the resulting string
                $cnt = count($base_par ts) - 1;
                if ($cnt < 1) {
                $cnt = 0;
                }

                return str_repeat ('../', $cnt).implode('/', $target_parts);
                }

                Of course, this is now A Dreadful Hack :-|
                --
                __________
                |im |yler http://timtyler.org/ tim@tt1lock.org Remove lock to reply.

                Comment

                • Ian.H

                  #9
                  Re: Includes in libraries

                  On Tue, 02 Dec 2003 14:58:07 +0000, Tim Tyler wrote:
                  [color=blue]
                  > A fairly simple question:
                  >
                  > I have a library A which depends on library B and C.
                  >
                  > Currently I have:
                  >
                  > <?php
                  > include("A.inc. php");
                  > include("B.inc. php");
                  > include("C.inc. php");
                  > ?>
                  >
                  > ...in my HTML.
                  >
                  > This needs changing to:
                  >
                  > <?php
                  > include("../A.inc.php");
                  > include("../B.inc.php");
                  > include("../C.inc.php");
                  > ?>
                  >
                  > ...if I call it from deeper in the directory tree.
                  >
                  > I don't want lots of includes in my HTML. I want to write:
                  >
                  > <?php
                  > include("A.inc. php");
                  > ?>
                  >
                  > ...and to have the other includes in the "A.inc.php" file.
                  >
                  > However if I put:
                  >
                  > include("B.inc. php");
                  > include("C.inc. php");
                  >
                  > ...in the library, it doesn't fild the files when included using:
                  >
                  > <?php
                  > include("../A.inc.php");
                  > ?>
                  >
                  > ...in an HTML file some distance from the root.
                  >
                  > I don't want to wire absolute paths in.
                  >
                  > I *could* pass the "../" in as a method parameter - but that seems like a
                  > total mess.
                  >
                  > What is the best way to resolve this issue?[/color]


                  Tim..

                  I normally create a 'registry.php' file. This holds the instructions for
                  my includes. It might look something like:


                  <?php
                  /* Script: includes/registry.php */

                  $global_libs = array(
                  'Mysql',
                  'Sessions',
                  'smarty/Smarty'
                  );
                  foreach ($global_libs as $g_lib) {
                  require_once("$ g_lib.class.php ");
                  }

                  $local_includes = array(
                  'functions',
                  'constants'
                  );
                  foreach ($local_include s as $l_inc) {
                  require_once(SI TE_ROOT . "/includes/$l_inc.inc.php" );
                  }
                  ?>


                  Then a script to call this would look like:

                  <?php
                  /* Script: index.php */
                  define('SITE_RO OT', dirname(__FILE_ _));
                  require_once(SI TE_ROOT . '/includes/registry.php');

                  [ ... rest of script ... ]
                  ?>


                  Or if we're in a sub directory:

                  <?php
                  /* Script: subdir/foo.php */
                  define('SITE_RO OT', dirname(__FILE_ _) . '/..');
                  require_once(SI TE_ROOT . '/includes/registry.php');

                  [ ... rest of script ... ]
                  ?>


                  As you an see, it doesn't matter what dir you in or how deep into a tree
                  you are, as long as you define the SITE_ROOT correctly (with enough
                  /../../.. etc) you'll always have the right place to read for the
                  registry.php script.

                  I use arrays to store the stuff in the registry script as it makes life
                  easier if you want to add / remove / whatever any of the files.

                  My £0.02 worth anyway =)



                  Regards,

                  Ian

                  --
                  Ian.H [Design & Development]
                  digiServ Network - Web solutions
                  www.digiserv.net | irc.digiserv.ne t | forum.digiserv. net
                  Programming, Web design, development & hosting.

                  Comment

                  • Tim Tyler

                    #10
                    Re: Includes in libraries

                    Johan Holst Nielsen <johan@weknowth ewayout.com> wrote or quoted:[color=blue]
                    > Tim Tyler wrote:[/color]
                    [color=blue][color=green]
                    >> A fairly simple question:[/color]
                    >
                    > Well, another way (than the other answers) are to add another include
                    > directory by ini_set() and the "include_pa th" option.[/color]

                    Essentially this idea has been suggested twice.

                    Doesn't doing something like this cause everything to become slow
                    if many modules do it, and there's a big string of directories to
                    scan?

                    What is the "scope" of the "include_pa th"?

                    Doesn't using it set you up for probems with name clashes with any
                    other users' scripts that do the same?
                    --
                    __________
                    |im |yler http://timtyler.org/ tim@tt1lock.org Remove lock to reply.

                    Comment

                    • Adi Schwarz

                      #11
                      Re: Includes in libraries

                      Tim Tyler wrote:
                      [color=blue]
                      > Kevin Thorpe <kevin@pricetra k.com> wrote or quoted:
                      >[color=green]
                      >>Best idea is to put all your libraries in a single directory and add it
                      >>to include_path in php.ini.[/color]
                      >
                      > Noooooooooooooo ooooooooooooo! ;-)[/color]

                      why not?

                      Comment

                      • Tim Tyler

                        #12
                        Re: Includes in libraries

                        Adi Schwarz <adolf.schwarz. news.11-03@gmx.at> wrote or quoted:[color=blue]
                        > Tim Tyler wrote:[color=green]
                        >> Kevin Thorpe <kevin@pricetra k.com> wrote or quoted:[/color][/color]
                        [color=blue][color=green][color=darkred]
                        >>>Best idea is to put all your libraries in a single directory and add it
                        >>>to include_path in php.ini.[/color]
                        >>
                        >> Noooooooooooooo ooooooooooooo! ;-)[/color]
                        >
                        > why not?[/color]

                        I expressed some of my qualms about this sort of thing in my reply to
                        Johan Holst Nielsen's suggestion.

                        Also it contains the sentence fragment:

                        "Best idea is to put all your libraries in a single directory".

                        I regard that as a dreadful idea - since I want to use directories
                        for encapsuating/associating files within each library - e.g. like
                        a Java package usually does - and I want my libraries associated
                        with the domains where they are used - to limit the scope of damage
                        if I want to change an API.
                        --
                        __________
                        |im |yler http://timtyler.org/ tim@tt1lock.org Remove lock to reply.

                        Comment

                        • FLEB

                          #13
                          Re: Includes in libraries

                          Regarding this well-known quote, often attributed to Tim Tyler's famous
                          "Tue, 2 Dec 2003 14:58:07 GMT" speech:
                          [color=blue]
                          > A fairly simple question:
                          >
                          > I have a library A which depends on library B and C.
                          >
                          > Currently I have:
                          >
                          > <?php
                          > include("A.inc. php");
                          > include("B.inc. php");
                          > include("C.inc. php");
                          > ?>
                          >
                          > ...in my HTML.
                          >
                          > This needs changing to:
                          >
                          > <?php
                          > include("../A.inc.php");
                          > include("../B.inc.php");
                          > include("../C.inc.php");
                          > ?>
                          >
                          > ...if I call it from deeper in the directory tree.
                          >
                          > I don't want lots of includes in my HTML. I want to write:
                          >
                          > <?php
                          > include("A.inc. php");
                          > ?>
                          >
                          > ...and to have the other includes in the "A.inc.php" file.
                          >
                          > However if I put:
                          >
                          > include("B.inc. php");
                          > include("C.inc. php");
                          >
                          > ...in the library, it doesn't fild the files when included using:
                          >
                          > <?php
                          > include("../A.inc.php");
                          > ?>
                          >
                          > ...in an HTML file some distance from the root.
                          >
                          > I don't want to wire absolute paths in.
                          >
                          > I *could* pass the "../" in as a method parameter - but that
                          > seems like a total mess.
                          >
                          > What is the best way to resolve this issue?[/color]

                          You could just drop a "definition s" script within your root path, and
                          include that from the included files:

                          <includes.inc.p hp> -----------------------------------------------

                          $_ROOT_INC_PATH _ = "/home2/bobdrilo/public_html/php-includes";

                          $_MYSQL_LIB_PAT H_ = "$_ROOT_INC_PAT H_/mysql/mysql-lib.php";
                          $_GRAPHICS_LIB_ PATH_ = "$_ROOT_INC_PAT H_/graphicslib/gfxlib.php";
                          $_TABLEGEN_LIB_ PATH_ = "$_ROOT_INC_PAT H_/tables/tables.php";

                          ....

                          <includes.inc.p hp> -----------------------------------------------

                          then, call your includes with the variables:

                          <dostuff.php> ----------------------------------------------------
                          include("includ es.inc.php"); // this is in the root includes path
                          include($_GRAPH ICS_LIB_PATH_);
                          include($_MYSQL _LIB_PATH);

                          ....
                          <dostuff.php> ----------------------------------------------------

                          --
                          -- Rudy Fleminger
                          -- sp@mmers.and.ev il.ones.will.bo w-down-to.us
                          (put "Hey!" in the Subject line for priority processing!)
                          -- http://www.pixelsaredead.com

                          Comment

                          • Adi Schwarz

                            #14
                            Re: Includes in libraries

                            Tim Tyler wrote:
                            [color=blue]
                            > Johan Holst Nielsen <johan@weknowth ewayout.com> wrote or quoted:
                            >[color=green]
                            >>Tim Tyler wrote:[/color]
                            >
                            >[color=green][color=darkred]
                            >>>A fairly simple question:[/color]
                            >>
                            >>Well, another way (than the other answers) are to add another include
                            >>directory by ini_set() and the "include_pa th" option.[/color][/color]
                            [color=blue]
                            > Doesn't doing something like this cause everything to become slow
                            > if many modules do it, and there's a big string of directories to
                            > scan?[/color]


                            I would not say that.

                            Let's say you have all includes (with subdirectories) in /bla/includes/
                            - this path is in you include_path.

                            If your script is in
                            /bla/scripts/dir/blubb.php
                            and wants to include
                            /bla/includes/modules/blubb.inc.php you just have to
                            include("module s/blubb.inc.php") ;

                            If you want to move your script directory - no problem.
                            If you want to move your include base directory - just adjust the
                            inlude_path

                            [color=blue]
                            > Doesn't using it set you up for probems with name clashes with any
                            > other users' scripts that do the same?[/color]

                            You can set the include_path for each user with an .htaccess (can't
                            you?) or in the script itself.

                            I really see advantages only.

                            Greets,
                            -adi

                            Comment

                            Working...