จะรวมไฟล์ PHP ที่ต้องการพา ธ สัมบูรณ์ได้อย่างไร?


96

ฉันมีโครงสร้างไดเร็กทอรีดังต่อไปนี้

script.php

inc
/ include1.php inc / include2.php

วัตถุ / object1.php
วัตถุ / object2.php

soap / soap.php

ตอนนี้ฉันใช้วัตถุเหล่านั้นทั้งในscript.phpและ/soap/soap.phpฉันสามารถย้ายพวกมันได้ แต่ฉันต้องการโครงสร้างไดเร็กทอรีแบบนั้นด้วยเหตุผลเฉพาะ เมื่อการดำเนินการscript.phpรวมถึงเส้นทางinc/include.phpและเมื่อดำเนินการ/soap/soap.phpก็../incแน่นอนการทำงานของเส้นทาง/mnt/webdev/[project name]/inc/include1.php...แต่มันเป็นวิธีการแก้ปัญหาที่น่าเกลียดถ้าฉันเคยต้องการย้ายไดเรกทอรีไปยังสถานที่ที่แตกต่างกัน

ดังนั้นจึงมีวิธีใช้เส้นทางสัมพัทธ์หรือวิธีสร้างโดยทางโปรแกรม"/mnt/webdev/[project name]/"หรือไม่?

คำตอบ:


150

สิ่งนี้ควรใช้งานได้

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

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

แก้ไข:เพิ่มimporvementโดยaussieviking


2
โปรดระวังสิ่งนี้จะใช้ได้เฉพาะเมื่อคุณเรียกใช้สคริปต์ผ่านเว็บเซิร์ฟเวอร์ที่เติมDOCUMENT_ROOT
Phil

แค่คำถามทำไม realpath () ราคา $ _SERVER ["DOCUMENT_ROOT"] สิ่งนี้จะไม่ส่งผลลัพธ์ตามเส้นทางที่บัญญัติเสมอไป?
João Pimentel Ferreira

44

คุณสามารถใช้เส้นทางสัมพัทธ์ ลอง__FILE__. นี่คือค่าคงที่ PHP ซึ่งจะส่งคืนพา ธ / ชื่อไฟล์ของสคริปต์ที่อยู่ในนั้นเสมอดังนั้นในsoap.phpคุณสามารถทำได้:

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

พา ธ เต็มและชื่อไฟล์ของไฟล์ หากใช้ภายในการรวมชื่อของไฟล์ที่รวมจะถูกส่งกลับ ตั้งแต่ PHP 4.0.2 __FILE__จะมีเส้นทางแบบสัมบูรณ์ที่มีการแก้ไข symlinks เสมอในขณะที่เวอร์ชันเก่าจะมีเส้นทางสัมพัทธ์ภายใต้สถานการณ์บางอย่าง (ที่มา)

อีกวิธีหนึ่งคือการตั้งเส้นทางการรวมใน httpd.conf หรือไฟล์. htaccess


8
ฉันคิดว่าคุณควรเพิ่ม/ที่จุดเริ่มต้นของนิพจน์ที่ยกมาเพื่อแยกออก..จากชื่อไฟล์
Dunaril

9
หมายเหตุว่าตั้งแต่ PHP 5.3.0 คุณสามารถใช้เวทมนตร์คงแทนที่จะต้องใช้__DIR__ (เอกสาร PHP)dirname(__FILE__)
Erwin Wessels

3
include dirname(__FILE__).'/../inc/include.php';อย่าลืม "/" ก่อนเส้นทางสัมพัทธ์
Steven Leimberg

6

อีกวิธีหนึ่งในการจัดการสิ่งนี้ที่ไม่จำเป็นต้องมีการรวมเลยก็คือการใช้คุณสมบัติโหลดอัตโนมัติ การรวมทุกสิ่งที่สคริปต์ของคุณต้องการ "Just in Case" อาจเป็นอุปสรรคต่อประสิทธิภาพ หากการรวมของคุณเป็นข้อกำหนดคลาสหรืออินเทอร์เฟซทั้งหมดและคุณต้องการโหลดเมื่อจำเป็นเท่านั้นคุณสามารถโอเวอร์โหลด__autoload()ฟังก์ชันด้วยรหัสของคุณเองเพื่อค้นหาไฟล์คลาสที่เหมาะสมและโหลดเฉพาะเมื่อมีการเรียก นี่คือตัวอย่างจากคู่มือ:

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

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

ตราบเท่าที่คุณตั้งค่าตัวแปร include_path ตามนั้นคุณไม่จำเป็นต้องรวมไฟล์คลาสอีก



5

คุณสามารถกำหนดค่าคงที่ด้วยพา ธ ไปยังไดเร็กทอรีรูทของโปรเจ็กต์ของคุณจากนั้นวางไว้ที่จุดเริ่มต้นของเส้นทาง


2

อีกทางเลือกหนึ่งที่เกี่ยวข้องกับ Kevin คือ use __FILE__แต่แทนที่ชื่อไฟล์ php จากภายใน:

<?php

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

?>

ฉันใช้สิ่งนี้มาระยะหนึ่งแล้ว ปัญหาเดียวคือบางครั้งคุณไม่มี$_SERVER['SCRIPT_NAME']แต่บางครั้งก็มีตัวแปรอื่นที่คล้ายกัน


2

ฉันพบว่ามันทำงานได้ดีมาก!

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

ใช้:

<?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');

?>

1

ฉันคิดว่าวิธีที่ดีที่สุดคือใส่การรวมไว้ในพา ธ รวม PHP ของคุณ มีหลายวิธีในการดำเนินการนี้ขึ้นอยู่กับการตั้งค่าของคุณ

จากนั้นคุณสามารถอ้างถึง

require_once 'inc1.php';

จากภายในไฟล์ใด ๆ ไม่ว่าไฟล์นั้นจะอยู่ที่ใดไม่ว่าจะอยู่ในไฟล์รวมหรือไฟล์ที่สามารถเข้าถึงได้บนเว็บของคุณหรือไดเร็กทอรีย่อยที่ซ้อนกันในระดับใดก็ตาม

วิธีนี้ช่วยให้คุณมีไฟล์รวมของคุณนอกรูทของเว็บเซิร์ฟเวอร์ซึ่งเป็นแนวทางปฏิบัติที่ดีที่สุด

เช่น

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

นอกจากนี้ตรวจสอบ __autoload สำหรับการโหลดไฟล์คลาสที่ขี้เกียจ

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

http://www.google.co.th/search?q=__autoload


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

ฉันใช้รหัสบรรทัดนี้ จะกลับไปที่ "ด้านบน" ของแผนผังไซต์จากนั้นไปที่ไฟล์ที่ต้องการ

ตัวอย่างเช่นสมมติว่าฉันมีแผนผังไฟล์นี้:

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

ฉันสามารถรวมไฟล์ functions.php ได้จากทุกที่เพียงแค่คัดลอกมาวาง

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

หากคุณจำเป็นต้องใช้รหัสนี้หลายครั้งคุณอาจสร้างฟังก์ชันที่ส่งคืนstr_repeat('../',(substr_count(getenv('SCRIPT_URL'),'/')-1))ส่วนนั้น จากนั้นเพียงแค่ใส่ฟังก์ชันนี้ในไฟล์แรกที่คุณรวมไว้ ฉันมีไฟล์ "initialize.php" ที่ฉันรวมไว้ที่ด้านบนสุดของแต่ละหน้า php และมีฟังก์ชันนี้ ในครั้งต่อไปที่ฉันต้องรวมไฟล์อันที่จริงฉันแค่ใช้ฟังก์ชัน (ชื่อpath_back):

require(path_back()."/_resources/another_php_file.php");

0

@ Flubba สิ่งนี้อนุญาตให้ฉันมีโฟลเดอร์ในไดเร็กทอรีรวมของฉันหรือไม่ ไดเรกทอรีรวมแบนทำให้ฉันฝันร้าย เนื่องจากไดเร็กทอรีอ็อบเจ็กต์ทั้งหมดควรอยู่ในไดเร็กทอรี inc

โอ้ใช่แน่นอน ตัวอย่างเช่นเราใช้โฟลเดอร์ย่อยชั้นเดียวโดยทั่วไป:

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

คุณต้องระมัดระวังในการใช้พา ธ รวมมากเกินไปในไซต์ที่มีการเข้าชมสูงจริงๆเนื่องจาก php ต้องค้นหาผ่านไดเร็กทอรีปัจจุบันจากนั้นไดเร็กทอรีทั้งหมดบนพา ธ รวมเพื่อดูว่าไฟล์ของคุณอยู่ที่นั่นหรือไม่และอาจทำให้ช้าลง จะเกิดอะไรขึ้นหากคุณถูกทุบ

ตัวอย่างเช่นหากคุณกำลังทำ MVC คุณจะต้องกำหนดเส้นทางไปยัง directoy แอปพลิเคชันของคุณในเส้นทางรวมจากนั้นระบุอ้างถึงสิ่งต่างๆในแบบฟอร์ม

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

หรืออะไรก็ตาม

แต่โดยทั่วไปแล้วมันช่วยให้คุณสามารถทำงานกับเส้นทางสั้น ๆ ใน PHP ของคุณซึ่งจะทำงานได้จากทุกที่และอ่านง่ายกว่า malarkey รูทของเอกสาร realpath ทั้งหมด

ประโยชน์ของทางเลือกที่ใช้สคริปต์เหล่านั้นที่คนอื่น ๆ แนะนำคือสามารถทำงานได้ทุกที่แม้กระทั่งในกล่องที่ใช้ร่วมกัน การตั้งค่าเส้นทางรวมต้องใช้ความคิดและความพยายามมากขึ้นเล็กน้อย แต่อย่างที่ฉันได้กล่าวไปช่วยให้คุณเริ่มใช้ __autoload ซึ่งเจ๋งที่สุด


0

หากคุณจะรวมพา ธ เฉพาะในไฟล์ส่วนใหญ่ในแอปพลิเคชันของคุณให้สร้างตัวแปร Global ไปยังโฟลเดอร์รูทของคุณ

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

ตอนนี้ตัวแปร Global " APPLICATION_PATH " สามารถใช้เพื่อรวมไฟล์ทั้งหมดแทนที่จะเรียก realpath () ทุกครั้งที่คุณรวมไฟล์ใหม่

EX:

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

หวังว่ามันจะช่วย ;-)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.