Since I change the tree, absolute and relative pat

2019-03-03 14:06发布

问题:

I tried to use the absolute path to include my files :

I have 4 files (I have other file on my localhost but oddly the inclusion works well) :

header.php (C:\wamp\www\MySite\layout\header.php)

<?php session_start (); 
require_once '/pdo.php';
....

pdo.php (C:\wamp\www\MySite\pdo.php)

<?php
require_once '/class/User.php';
require_once '/class/Order.php';
....

forms/login.php (C:\wamp\www\MySite\forms\login.php)

<?php
session_start (); 
include '/pdo.php';
....

login.php (C:\wamp\www\MySite\login.php)

<?php
  $title = 'Connexion'; 
  include ("/layout/header.php");
...

So it's look like :

Root
    - forms
        - login.php
    -layout
        - header.php
    - pdo.php
    - login.php

And I have this errors :

( ! ) Warning: include(/pdo.php): failed to open stream: No such file or directory in C:\wamp\www\MySite\forms\login.php on line 3 Call Stack

( ! ) Warning: include(): Failed opening '/pdo.php' for inclusion (include_path='.;C:\php\pear') in C:\wamp\www\MySite\forms\login.php on line 3

( ! ) Fatal error: Class 'User' not found in C:\wamp\www\MySite\forms\login.php on line 12

But I have this problem on a lot of files since I wanted to change the arboresence (tree) of files and folder ..

How I can solve this problem ? and how I can do to avoid this problem in the future ?

Thank you

回答1:

I tried to use the absolute path to include my files :

header.php (C:\wamp\www\MySite\layout\header.php)

<?php session_start (); 
require_once '/pdo.php';

The PHP code is executed on the server. An absolute path in this context means a file-system absolute path, not a web host path. Since you are on Windows, /pdo.php in fact means C:/pdo.php and not C:\wamp\www\MySite\pdo.php as it seems you think.

The best way to work with paths in PHP, regarding include and require is to use the __FILE__ and __DIR__ magic constants and the dirname() PHP function to build the (file-system) absolute paths of files starting from their relative locations.

Your code becomes:

header.php (C:\wamp\www\MySite\layout\header.php):

<?php
session_start (); 
// 'pdo.php' is one level up
require_once dirname(__DIR__).'/pdo.php';
....

pdo.php (C:\wamp\www\MySite\pdo.php)

<?php
// User.php is inside the 'class' subdirectory
require_once __DIR__.'/class/User.php';
require_once __DIR__.'/class/Order.php';
....

dir1/dir2/dir3/file.php (C:\wamp\www\MySite\dir1\dir2\dir3\file.php)

<?php
// 'header.php' is in the 'layout' subdirectory of the grand-grand parent directory
include dirname(dirname(dirname(__DIR__))).'/layout/header.php';

Remark

The solution presented here makes the code independent of its actual location in the file system. You can move the entire project (everything in C:\wamp\www\MySite) in a different directory or on a different computer and it will work without changes. Even more, if you use forward slashes (/) as directory names separators it works on Windows, macOS or any Linux flavor.



回答2:

One convention is to include a configuration file in every php script. This configuration file would set the include path, allowing you to include other files, classes, etc and would continue to work regardless of whether your current working directory had changed - it will allow you to better organise your classes and functions into meaningful directories and include them without worrying about the full path:

An example below:

Create file at C:\wamp\www\MySite\config.php

<?php
set_include_path(get_include_path() . PATH_SEPARATOR . 'C:\wamp\www\MySite\class' . PATH_SEPARATOR . 'C:\wamp\www\MySite\conf');
?>

Then in header.php (C:\wamp\www\MySite\layout\header.php)

<?php 
require_once('C:\wamp\www\MySite\config.php');
session_start (); 
require_once '/pdo.php';    // put pdo.php in C:\wamp\www\MySite\conf\ directory and it will be included
....

In pdo.php (C:\wamp\www\MySite\pdo.php):

<?php
require_once 'User.php';
require_once 'Order.php';
....