PHP รวมเส้นทางที่สัมพันธ์กับไฟล์หรือรหัสการโทรหรือไม่


111

ฉันมีปัญหาในการทำความเข้าใจชุดกฎเกี่ยวกับเส้นทาง PHP ที่สัมพันธ์กัน ถ้าฉันเรียกใช้ไฟล์ A.PHP- และไฟล์ A.PHP มีไฟล์ B.PHP ซึ่งรวมถึงไฟล์ C.PHP ควรพา ธ สัมพัทธ์ไปยัง C.PHP สัมพันธ์กับตำแหน่งของ B.PHP หรือไปยังตำแหน่งของ A .PHP? นั่นคือไฟล์ที่เรียกว่า include นั้นมีความสำคัญหรือไม่หรือไดเร็กทอรีการทำงานปัจจุบันคืออะไร - และอะไรเป็นตัวกำหนดไดเร็กทอรีการทำงานปัจจุบัน


ถูกต้องมากขึ้นกว่าคำตอบที่ได้รับการยอมรับในความคิดของฉัน: stackoverflow.com/a/23902890/1636522
ใบที่

คำตอบ:


132

มันสัมพันธ์กับสคริปต์หลักในกรณีนี้คือ A.php โปรดจำไว้ว่าinclude()เพียงแค่ใส่โค้ดลงในสคริปต์ที่กำลังทำงานอยู่

นั่นคือมันสำคัญหรือไม่ว่าไฟล์ที่รวมนั้นถูกเรียกมาจากไฟล์ใด

ไม่

หากคุณต้องการทำให้มันมีความสำคัญและทำการรวมที่สัมพันธ์กับ B.php ให้ใช้__FILE__ค่าคงที่ (หรือ__DIR__ตั้งแต่ PHP 5.2 IIRC) ซึ่งจะชี้ไปที่ไฟล์ปัจจุบันตามตัวอักษรที่บรรทัดของโค้ดอยู่เสมอ

include(dirname(__FILE__)."/C.PHP");

@ Pekka- สุดยอด - แค่สิ่งที่ฉันกำลังมองหา ดูข้อมูลเพิ่มเติมได้ที่stackoverflow.com/questions/2184810/…
Yarin

7
คุณยังสามารถใช้__DIR__เพื่อวัตถุประสงค์ที่แน่นอน
Nick Bedford

1
คำตอบนี้ค่อนข้างเกินความจำเป็น: ไม่จำเป็นinclude(dirname(__FILE__)."/C.PHP");เพราะinclude("C.PHP");เพียงพอแล้ว (ใช่ C.PHP สามารถอยู่ในไดเร็กทอรีเดียวกับ B.PHP) อาจล้มเหลวเฉพาะเมื่อมีไฟล์ C.PHP สองไฟล์ในโครงการของคุณ
Johnny Wong

เพื่อให้ชัดเจนยิ่งขึ้น: จะสัมพันธ์กับทั้ง B.php และ A.php ถ้าไม่มี "./" หรือ "../" นำหน้าในเส้นทางรวม ดูคำตอบของฉันด้านล่าง
Johnny Wong

21

@Pekka พาฉันไปที่นั่น แต่แค่อยากแบ่งปันสิ่งที่ฉันเรียนรู้:

getcwd() ส่งคืนไดเร็กทอรีที่ไฟล์ที่คุณเริ่มดำเนินการอยู่

dirname(__FILE__) ส่งคืนไดเร็กทอรีของไฟล์ที่มีโค้ดที่กำลังดำเนินการอยู่

การใช้ฟังก์ชันทั้งสองนี้คุณสามารถสร้างเส้นทางการรวมที่สัมพันธ์กับสิ่งที่คุณต้องการได้ตลอดเวลา

เช่นถ้า b.php และ c.php แชร์ไดเร็กทอรี b.php สามารถรวม c.php เช่น:

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

ไม่ว่า b.php ถูกเรียกมาจากไหน

อันที่จริงนี่เป็นวิธีที่ต้องการในการสร้างพา ธ สัมพัทธ์เนื่องจากโค้ดพิเศษช่วยให้ PHP ไม่ต้องวนซ้ำผ่าน include_path เพื่อพยายามค้นหาไฟล์เป้าหมาย

แหล่งที่มา:

ความแตกต่างระหว่าง getcwd () และ dirname (__ FILE__)? ควรใช้ตัวไหนดี?

ทำไมคุณควรใช้ dirname (__ FILE__)


ฉันต้องการเพิ่มบางอย่างฉันมีไฟล์ชื่อ csb.php รวมไฟล์ฟังก์ชันจากโฟลเดอร์และไฟล์ฟังก์ชันรวมไฟล์ชื่อ t.php จากโฟลเดอร์เดียวกับไฟล์ฟังก์ชันเมื่อฉันลองรวมไฟล์ ไฟล์ชื่อ csb.php จากโฟลเดอร์ t.php คือมันเริ่มต้นรวมถึง csb.php เดียวกันกับที่เรียกไฟล์ฟังก์ชัน แต่เมื่อฉันเปลี่ยน csb.php ที่สองเป็น csbe.php มันก็เริ่มทำงานทันที ดูเหมือนว่าจะจัดลำดับความสำคัญของโฟลเดอร์แรกแล้วโฟลเดอร์ที่สองรวม!
Miguel Vieira

18
  1. หากเส้นทางรวมไม่ได้ขึ้นต้นด้วย./หรือ../เช่น:

    include 'C.php'; // precedence: include_path (which include '.' at first),
                     // then path of current `.php` file (i.e. `B.php`), then `.`.
  2. หากเส้นทางรวมเริ่มต้นด้วย./หรือ../เช่น:

    include './C.php';  // relative to '.'
    
    include '../C.php'; // also relative to '.'

.หรือ..ข้างต้นเป็นญาติgetcwd()ที่เริ่มต้นไปยังเส้นทางของรายการ.phpไฟล์ (เช่นA.php)

ทดสอบบน PHP 5.4.3 (วันที่สร้าง: 8 พฤษภาคม 2555 00:47:34 น.)

(โปรดทราบว่าchdir()สามารถเปลี่ยนผลลัพธ์ของgetcwd().)


โดยสรุปเส้นทางของ A.php จะถูกค้นหาด้วย C.php ก่อนจากนั้นเส้นทางของ B.php จะถูกค้นหาหากไม่มีคำนำหน้า "./" หรือ "../" ในการรวม (สมมติการตั้งค่าเริ่มต้นของ PHP)
Johnny Wong

ขอขอบคุณที่ติดต่อฉันเพื่อใช้chdir(__DIR__)ในการแก้ไขปัญหา
HartleySan

[... ] getcwd()ซึ่งเป็นค่าเริ่มต้นของเส้นทางของไฟล์. php รายการ [... ] - ไม่จำเป็นต้องเป็นจริง หากฉันเรียกใช้ PHP บนบรรทัดคำสั่งgetcwd()ให้อ้างถึงไดเร็กทอรีการทำงานปัจจุบันของเชลล์ไม่ว่า.phpฉันจะเรียกใช้ไฟล์ใดก็ตาม ฉันสามารถจินตนาการได้ว่าหาก PHP ทำงานในสภาพแวดล้อมเว็บเซิร์ฟเวอร์ที่สภาพแวดล้อมเริ่มต้นไดเร็กทอรีการทำงานปัจจุบันไปยัง.phpไฟล์รายการ ทดสอบบน macOS ด้วย PHP 7.2.2 ที่ติดตั้งผ่าน Homebrew
herzbube

17

คำตอบที่ยอมรับของ Pekka นั้นไม่สมบูรณ์และในบริบททั่วไปทำให้เข้าใจผิด หากไฟล์ถูกจัดให้เป็นพา ธ สัมพัทธ์โครงสร้างภาษาที่เรียกincludeจะค้นหาด้วยวิธีต่อไปนี้

ครั้งแรกก็จะผ่านไปเส้นทางของตัวแปรสภาพแวดล้อมซึ่งสามารถตั้งค่าด้วยinclude_path ini_setหากล้มเหลวมันจะค้นหาในไดเร็กทอรีของสคริปต์การเรียกใช้เองdirname(__FILE__)( __DIR__ด้วย php> = 5.3) หากสิ่งนี้ล้มเหลวก็จะค้นหาในไดเร็กทอรีการทำงานเท่านั้น! ปรากฎว่าโดยค่าเริ่มต้นตัวแปรสภาพแวดล้อมinclude_pathเริ่มต้นด้วย.ซึ่งเป็นไดเร็กทอรีการทำงานปัจจุบัน นั่นเป็นเหตุผลเดียวที่ทำให้ค้นหาเป็นอันดับแรกในไดเร็กทอรีการทำงานปัจจุบัน ดูhttp://php.net/manual/en/function.include.php

ไฟล์จะถูกรวมตามเส้นทางไฟล์ที่กำหนดหรือหากไม่มีการระบุจะระบุ include_path หากไม่พบไฟล์ใน include_path สุดท้าย include จะตรวจสอบในไดเร็กทอรีของสคริปต์การโทรและไดเร็กทอรีการทำงานปัจจุบันก่อนที่จะล้มเหลว

ดังนั้นคำตอบที่ถูกต้องสำหรับส่วนแรกของคำถามก็คือว่าสคริปต์การโทรที่รวมอยู่นั้นจะอยู่ที่ใด คำตอบสำหรับส่วนสุดท้ายของคำถามคือไดเร็กทอรีการทำงานเริ่มต้นในบริบทเว็บเซิร์ฟเวอร์คือไดเร็กทอรีของสคริปต์ที่เรียกว่าสคริปต์ที่รวมส่วนอื่น ๆ ทั้งหมดในขณะที่ PHP จัดการ ในบริบทบรรทัดคำสั่งไดเร็กทอรีการทำงานเริ่มต้นคืออะไรก็ได้เมื่อเรียกใช้ php ที่พรอมต์ไม่จำเป็นต้องเป็นไดเร็กทอรีที่มีสคริปต์ที่เรียกว่าอยู่ ปัจจุบันไดเรกทอรีการทำงาน chdirแต่สามารถเปลี่ยนแปลงได้ตลอดเวลาทำงานกับฟังก์ชั่นของ ดูhttp://php.net/manual/en/function.chdir.php

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


"ถ้าล้มเหลวมันจะค้นหาในไดเรกทอรีของสคริปต์การเรียกเองdirname(__FILE__) (__DIR__)ด้วย php> = 5.3)"คุณแน่ใจหรือไม่? เอกสารอยู่ที่ไหน? ฉันหวังว่าคุณจะคิดผิดและ PHP ไม่ใช้__FILE__และ__DIR__เพื่อจุดประสงค์นี้เนื่องจากจะทำลายสคริปต์ "พี่น้อง" จากสคริปต์ที่เชื่อมโยงกันในทันที! : -o (ซึ่งโชคดีที่ดูเหมือนจะทำงานได้ดีที่นี่ในการตั้งค่า 7.1 ของฉัน)
Sz

6

คำตอบสั้น ๆ : สัมพันธ์กับสคริปต์รวม

TFMอธิบายได้อย่างถูกต้อง:

หากไม่พบไฟล์ใน include_path, include จะตรวจสอบในไดเร็กทอรีของสคริปต์การโทรและไดเร็กทอรีการทำงานปัจจุบัน

ดังนั้นถ้า/app/main.phpกล่าวinclude("./inc.php")ว่าจะพบ/app/inc.php

./ไม่จำเป็นอย่างเคร่งครัด แต่เอาพึ่งพาใด ๆ บน include_path

chdir()ฉันจะไม่พึ่งพาการค้นพบรวมถึงไฟล์ในไดเรกทอรีการทำงานปัจจุบันในกรณีที่มีคนเปลี่ยนแปลงมันด้วย


ดังนั้นหากคุณเริ่มสตริงด้วย./จะตรวจสอบไดเร็กทอรีสคริปต์การโทรก่อนหรือไดเร็กทอรีการทำงานปัจจุบันก่อนหรือไม่?
Pacerier

2
@Denis Howe ./ไม่มีคุณมีอยู่แล้วขึ้นอยู่กับไดเรกทอรีการทำงานปัจจุบันถ้าคุณมีการเริ่มต้นเส้นทางด้วย เช่น chdir ("/ app / other") จะทำให้include("./inc.php")ล้มเหลว ดังนั้นควรใช้include("inc.php")ให้ปลอดภัยในกรณีนี้
Johnny Wong

@Pacerier ถ้าสตริงขึ้นต้นด้วย. / หรือ ../ จะตรวจสอบไดเร็กทอรีการทำงานปัจจุบันเท่านั้น (include_path และไดเร็กทอรีของสคริปต์การโทร (B.php) ถูกละเว้น) ดูคำตอบของฉันสำหรับรายละเอียดเพิ่มเติม
Johnny Wong

-2
dir
-> a.php
-> c.php

- dir2 
-> b.php

ในการรวมaไว้bคุณจำเป็นต้องinclude("../a.php");

ในการรวมbไว้cคุณจำเป็นต้องinclude("dir2/b.php");


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