What Does the Dot-Slash Do to PHP Include Calls

What does the dot-slash do to PHP include calls?

./ is the current directory. It is largely the same as just file.php, but in many cases (this one included) it doesn't check any standard places PHP might look for a file, instead checking only the current directory.

From the PHP documentation (notice the last sentence):

Files for including are first looked for in each include_path entry relative to the current working directory, and then in the directory of current script. E.g. if your include_path is libraries, current working directory is /www/, you included include/a.php and there is include "b.php" in that file, b.php is first looked in /www/libraries/ and then in /www/include/. If filename begins with ./ or ../, it is looked only in the current working directory.

What does ./ (dot slash) refer to in terms of an HTML file path location?

./ is the the folder that the working file is in:

So in /index.htm ./ is the root directory

but in /css/style.css ./ is the css folder.

This is important to remember because if you move CSS from /index.htm to /css/style.css the path will change.

Difference between ./ and ../ in PHP

This is a system thing and NOT just a PHP thing.

The ./ indicates the current directory. If you ever list the contents of a *nix system you will get the following at the top.

.
../

The top one (.) is the same as ./ which means "this directory". So if including a file like such:

include('./config.php')

You are telling PHP to look in the current directory for "config.php". Which is the same as

include('config.php')

The ../ indicates the directory above or "parent directory"

include('../config.php')

This is telling PHP to go one directory up and look for "config.php". These commands can be chained like so:

../../config.php

This tells the system to go up one directory, go up again and then look for "config.php"

PHP require, dot as prefix

The . gives you the ability to set the path of the included files relatively to the path of the original file that run (the file that included them).

Lets take the following structure:

/index.php
/file2.php
/folder/
/file1.php

If index.php includes file1.php, and you want file1.php to include file2.php - you can do this using require './file2.php'; (inside file1.php, which is in the inner folder).

If you use require 'file2.php'; inside file1.php you are looking for file2.php inside the folder (which will give you an error, because the file is not there).

Why doesnt ../ (dot dot slash) work in my root directory?

The ../ convention indicates to move up one directory level from where you are. If you are in the root directory, you cannot move up any more levels.

If your /admin folder is in the root directory and you call this from the /public directory, then ../admin/ would allow you to select the /admin folder from one level below

Difference between ./ and ../ in PHP

This is a system thing and NOT just a PHP thing.

The ./ indicates the current directory. If you ever list the contents of a *nix system you will get the following at the top.

.
../

The top one (.) is the same as ./ which means "this directory". So if including a file like such:

include('./config.php')

You are telling PHP to look in the current directory for "config.php". Which is the same as

include('config.php')

The ../ indicates the directory above or "parent directory"

include('../config.php')

This is telling PHP to go one directory up and look for "config.php". These commands can be chained like so:

../../config.php

This tells the system to go up one directory, go up again and then look for "config.php"

PHP will include a file relative to a calling script, but not if the include path contains ../

PHP's a bit odd in how it looks for files. If you include a file whose name starts with a slash or a dot, PHP ignores the include_path entirely. If a dot, it assumes the name is relative to the script that kicked off everything (ie: the one the web server decided to run).

If you want to specify a path relative to the included script and not the startup one, what you really want is an absolute include that specifies the full name of the file. That's easy to do with the __FILE__ and __DIR__ constants, which reflect the name and directory of the currently running script.

include __DIR__ . '/../dirB/c.php';

If you like, you can also set the include_path config setting to include the root of the app, and just specify all filenames relative to that.

File execution with dot space versus dot slash

Let's start with how the command path works and when it's used. When you run a command like:

ls /tmp

The ls here doesn't contain a / character, so the shell searches the directories in your command path (the value of the PATH environment variable) for a file named ls. If it finds one, it executes that file. In the case of ls, it's usually in /bin or /usr/bin, and both of those directories are typically in your path.

When you issue a command with a / in the command word:

/bin/ls /tmp

The shell doesn't search the command path. It looks specifically for the file /bin/ls and executes that.

Running ./A is an example of running a command with a / in its name. The shell doesn't search the command path; it looks specifically for the file named ./A and executes that. "." is shorthand for your current working directory, so ./A refers to a file that ought to be in your current working directory. If the file exists, it's run like any other command. For example:

cd /bin
./ls

would work to run /bin/ls.

Running . A is an example of sourcing a file. The file being sourced must be a text file containing shell commands. It is executed by the current shell, without starting a new process. The file to be sourced is found in the same way that commands are found. If the name of the file contains a /, then the shell reads the specific file that you named. If the name of the file doesn't contain a /, then the shell looks for it in the command path.

. A        # Looks for A using the command path, so might source /bin/A for example
. ./A # Specifically sources ./A

So, your script tries to execute . B and fails claiming that B doesn't exist, even though there's a file named B right there in your current directory. As discussed above, the shell would have searched your command path for B because B didn't contain any / characters. When searching for a command, the shell doesn't automatically search the current directory. It only searches the current directory if that directory is part of the command path.

In short, . B is probably failing because you don't have "." (current directory) in your command path, and the script which is trying to source B is assuming that "." is part of your path. In my opinion, this is a bug in the script. Lots of people run without "." in their path, and the script shouldn't depend on that.

Edit:

You say the script uses ksh, while you are using bash. Ksh follows the POSIX standard--actually, KSH was the basis for the POSIX standard--and always searches the command path as I described. Bash has a flag called "POSIX mode" which controls how strictly it follows the POSIX standard. When not in POSIX mode--which is how people generally use it--bash will check the current directory for the file to be sourced if it doesn't find the file in the command path.

If you were to run bash -posix and run . B within that bash instance, you should find that it won't work.



Related Topics



Leave a reply



Submit