¿Cómo incluir archivos PHP que requieren una ruta absoluta?

95

Tengo una estructura de directorio como la siguiente;

script.php

inc / include1.php
inc / include2.php

objetos / object1.php
objetos / object2.php

jabón / soap.php

Ahora, uso esos objetos en ambos script.phpy /soap/soap.phppodría moverlos, pero quiero la estructura de directorio así por una razón específica. Cuando se ejecuta script.phpla ruta de inclusión es inc/include.phpy cuando la ejecución /soap/soap.phpEs ../inc, el trabajo caminos absoluta, /mnt/webdev/[project name]/inc/include1.php...pero es una solución fea si quiero mover el directorio a una ubicación diferente.

Entonces, ¿hay alguna forma de usar rutas relativas o una forma de generar programáticamente "/mnt/webdev/[project name]/"?

Xenph Yan
fuente

Respuestas:

149

Esto debería funcionar

$root = realpath($_SERVER["DOCUMENT_ROOT"]);

include "$root/inc/include1.php";

Editar: mejora agregada por aussieviking

Peter Coulton
fuente
2
Tenga cuidado, esto solo funcionará si ejecuta el script a través de un servidor web que se completaDOCUMENT_ROOT
Phil
solo una pregunta, ¿por qué realpath () para $ _SERVER ["DOCUMENT_ROOT"]? ¿Esto no generará siempre la ruta canónica?
João Pimentel Ferreira
44

Puede utilizar rutas relativas. Prueba __FILE__. Esta es una constante de PHP que siempre devuelve la ruta / nombre de archivo del script en el que se encuentra. Entonces, en soap.php, podría hacer:

include dirname(__FILE__).'/../inc/include.php';

La ruta completa y el nombre de archivo del archivo. Si se usa dentro de una inclusión, se devuelve el nombre del archivo incluido. Desde PHP 4.0.2, __FILE__siempre contiene una ruta absoluta con enlaces simbólicos resueltos, mientras que en versiones anteriores contenía una ruta relativa en algunas circunstancias. (fuente)

Otra solución sería establecer una ruta de inclusión en su httpd.conf o un archivo .htaccess.

Kevin
fuente
8
Creo que se debe agregar una /al comienzo de la expresión citada, para separar el ..del ARCHIVO nombre.
Dunaril
9
Tenga en cuenta que desde PHP 5.3.0 puede usar la constante mágica en __DIR__lugar de tener que usar dirname(__FILE__). (Documentos PHP)
Erwin Wessels
3
include dirname(__FILE__).'/../inc/include.php';No olvide la "/" antes de la ruta relativa.
Steven Leimberg
6

Otra forma de manejar esto que elimina la necesidad de incluir es usar la función de carga automática . Incluir todo lo que su script necesita "por si acaso" puede afectar el rendimiento. Si sus inclusiones son todas definiciones de clase o interfaz y desea cargarlas solo cuando sea necesario, puede sobrecargar la __autoload()función con su propio código para encontrar el archivo de clase apropiado y cargarlo solo cuando se llame. Aquí está el ejemplo del manual:

function __autoload($class_name) {
    require_once $class_name . '.php';
}

$obj  = new MyClass1();
$obj2 = new MyClass2(); 

Siempre que establezca sus variables include_path en consecuencia, nunca más necesitará incluir un archivo de clase.

Sam McAfee
fuente
5

Puede definir una constante con la ruta al directorio raíz de su proyecto y luego ponerla al principio de la ruta.

Ryan Fox
fuente
2

Otra opción, relacionada con la de Kevin, es usar __FILE__, pero reemplazar el nombre del archivo php desde dentro:

<?php

$docRoot = str_replace($_SERVER['SCRIPT_NAME'], '', __FILE__);
require_once($docRoot . '/lib/include.php');

?>

He estado usando esto por un tiempo. El único problema es que a veces no tienes $_SERVER['SCRIPT_NAME'], pero a veces hay otra variable similar.

Darryl Hein
fuente
2

¡Encontré que esto funcionaba muy bien!

function findRoot() { 
    return(substr($_SERVER["SCRIPT_FILENAME"], 0, (stripos($_SERVER["SCRIPT_FILENAME"], $_SERVER["SCRIPT_NAME"])+1)));
}

Utilizar:

<?php

function findRoot() {
    return(substr($_SERVER["SCRIPT_FILENAME"], 0, (stripos($_SERVER["SCRIPT_FILENAME"], $_SERVER["SCRIPT_NAME"])+1)));
}

include(findRoot() . 'Post.php');
$posts = getPosts(findRoot() . 'posts_content');

include(findRoot() . 'includes/head.php');

for ($i=(sizeof($posts)-1); 0 <= $i; $i--) {
    $posts[$i]->displayArticle();
}

include(findRoot() . 'includes/footer.php');

?>
Thane Gill
fuente
1

Creo que la mejor manera es poner sus inclusiones en su ruta de inclusión de PHP. Hay varias formas de hacer esto dependiendo de su configuración.

Entonces puede simplemente consultar

require_once 'inc1.php';

desde el interior de cualquier archivo, independientemente de dónde se encuentre, ya sea en sus archivos incluidos o accesibles en la web, o en cualquier nivel de subdirectorios anidados.

Esto le permite tener sus archivos de inclusión fuera de la raíz del servidor web, lo cual es una buena práctica.

p.ej

site directory
    html (web root)
        your web-accessible files
    includes
        your include files

Además, consulte __autoload para la carga diferida de archivos de clase

http://www.google.com/search?q=setting+php+include+path

http://www.google.com/search?q=__autoload

Polsonby
fuente
1
require(str_repeat('../',(substr_count(getenv('SCRIPT_URL'),'/')-1))."/path/to/file.php");

Yo uso esta línea de código. Vuelve a la "parte superior" del árbol del sitio, luego va al archivo deseado.

Por ejemplo, digamos que tengo este árbol de archivos:

dominio.com/aaa/index.php
dominio.com/bbb/ccc/ddd/index.php
dominio.com/_resources/functions.php

Puedo incluir el archivo functions.php desde donde esté, simplemente copiando y pegando

require(str_repeat('../',(substr_count(getenv('SCRIPT_URL'),'/')-1))."/_resources/functions.php");

Si necesita usar este código muchas veces, puede crear una función que devuelva la str_repeat('../',(substr_count(getenv('SCRIPT_URL'),'/')-1))pieza. Luego, inserte esta función en el primer archivo que incluya. Tengo un archivo "initialize.php" que incluyo en la parte superior de cada página php y que contiene esta función. La próxima vez que tenga que incluir archivos, de hecho solo uso la función (nombrada path_back):

require(path_back()."/_resources/another_php_file.php");
Machavity
fuente
0

@Flubba, ¿esto me permite tener carpetas dentro de mi directorio de inclusión? planos incluyen directorios que me dan pesadillas. ya que todo el directorio de objetos debe estar en el directorio inc.

Oh sí, absolutamente. Entonces, por ejemplo, usamos una sola capa de subcarpetas, generalmente:

require_once('library/string.class.php')

Debe tener cuidado al confiar demasiado en la ruta de inclusión en sitios de mucho tráfico, porque php tiene que buscar en el directorio actual y luego en todos los directorios de la ruta de inclusión para ver si su archivo está allí y esto puede ralentizar las cosas si te golpean.

Entonces, por ejemplo, si está haciendo MVC, pondría la ruta al directorio de su aplicación en la ruta de inclusión y luego especificaría referirse a cosas en el formulario

'model/user.class'
'controllers/front.php'

o lo que sea.

Pero en términos generales, solo le permite trabajar con rutas realmente cortas en su PHP que funcionarán desde cualquier lugar y es mucho más fácil de leer que todo el malarkey raíz del documento realpath.

El beneficio de esas alternativas basadas en scripts que otros han sugerido es que funcionan en cualquier lugar, incluso en cajas compartidas; configurar la ruta de inclusión requiere un poco más de pensamiento y esfuerzo, pero como mencioné le permite comenzar a usar __autoload, que es el más genial.

Polsonby
fuente
0

Si va a incluir una ruta específica en la mayoría de los archivos de su aplicación, cree una variable global en su carpeta raíz.

define("APPLICATION_PATH", realpath(dirname(__FILE__) . '/../app'));
or 
define("APPLICATION_PATH", realpath(DIR(__FILE__) . '/../app'));

Ahora, esta variable global " APPLICATION_PATH " se puede utilizar para incluir todos los archivos en lugar de llamar a realpath () cada vez que incluye un nuevo archivo.

EX:

include(APPLICATION_PATH ."/config/config.ini";

Espero eso ayude ;-)

yuvraj
fuente