ฉันจะหาเส้นทางสู่สาธารณะได้อย่างไร: //


43

ฉันต้องการเส้นทางสำหรับสาธารณะ: // ที่รันไทม์ มีฟังก์ชั่นที่ฉันสามารถใช้เพื่อรับมันได้หรือไม่?

คำตอบ:


34

คุณสามารถใช้รหัสต่อไปนี้เพื่อรับเส้นทางที่แท้จริงของสาธารณะ: //

if ($wrapper = file_stream_wrapper_get_instance_by_uri('public://')) {
  $realpath = $wrapper->realpath();
  // ...
}

รหัสนี้เป็นเวอร์ชั่นที่เรียบง่ายของรหัสที่ใช้โดยfile_create_url()มีความแตกต่างดังต่อไปนี้:

  • ไม่อนุญาตให้โมดูลบุคคลที่สามแก้ไข URL เนื่องจาก OP ขอเส้นทางที่เกี่ยวข้องกับสาธารณะ: //
  • ไม่ได้ตรวจสอบ URI ประกอบด้วย: // เนื่องจากนี่เป็นความจริงที่ชัดเจน
  • ไม่ได้ตรวจสอบว่า URI นั้นเป็น URI ที่สัมพันธ์กับรูตเนื่องจากเป็นเท็จอย่างชัดเจนสำหรับสาธารณะ: //
  • ไม่ได้ตรวจสอบว่า URI เป็นโปรโตคอลที่เกี่ยวข้องเนื่องจากเป็นเท็จในกรณีของ OP
  • ไม่ได้ตรวจสอบว่า URI ไม่ใช่รูปแบบสตรีมที่เหมาะสมเนื่องจาก public: // เป็นรูปแบบที่เหมาะสม
  • ไม่ได้ตรวจสอบว่ารูปแบบเป็น http หรือ https หรือไม่เนื่องจากในกรณีนี้เป็นแบบสาธารณะ
  • ไม่เรียกใช้$wrapper->getExternalUrl()เนื่องจาก OP กำลังขอเส้นทางไม่ใช่สำหรับ URL

หาก OP ต้องการ URL สำหรับสาธารณะ: // ฉันจะใช้รหัสต่อไปนี้ซึ่งยังคงเป็นเวอร์ชันที่เรียบง่ายของรหัสที่ใช้โดยฟังก์ชัน Drupal ซึ่งจำเป็นต้องมีทั่วไปมากกว่า

if ($wrapper = file_stream_wrapper_get_instance_by_uri('public://')) {
  $url = $wrapper->getExternalUrl();
}

3
@ junedkazi เป็นคำตอบที่ดีกว่า
AlessMascherpa

1
อ่านรหัสที่ใช้โดยfile_create_url(); คุณจะเห็นรหัสที่ถูกเรียกใช้ในกรณีนี้คือสิ่งที่ฉันเขียนไว้ในคำตอบของฉัน
kiamlaluno

1
สิ่งนี้จะทำให้คุณได้รับเส้นทางเซิร์ฟเวอร์แบบเต็มไม่ใช่ URL
DrCord

@DrCord มันให้สิ่งเดียวกับfile_create_url()คุณ
kiamlaluno

1
ไม่มันไม่ได้ให้เส้นทางเซิร์ฟเวอร์กับคุณเหมือนกัน/var/www/webroot/etc/more_folders/
DrCord

39

คุณสามารถใช้ฟังก์ชันfile_create_url

$uri = 'public://';
$path= file_create_url($uri)

นี่ทำให้คุณได้รับ URL แต่รวมถึงเซิร์ฟเวอร์ด้วย ฉันใช้ regex ง่าย ๆ และในglobal $base_urlการลบและทำให้เซิร์ฟเวอร์นี้ไม่เชื่อเรื่องพระเจ้า global $base_url; $path = file_create_url($file_object->uri); $path = preg_replace('#' . $base_url . '#', '', $path);ตรวจสอบให้แน่ใจว่าใช้ '#' ใน regex มิฉะนั้นการแทนที่จะล้มเหลวเนื่องจาก un-escaped '/' ใน $ base_url
DrCord

3
OP ขอเส้นทางไม่ใช่ URL
kiamlaluno

20

ในกรณีที่คุณใช้เฉพาะไฟล์ในตัวเครื่อง ( ไม่ใช่รีโมท! ) คุณสามารถลองใช้drupal_realpath ()

$path = 'public://custom_map';
drupal_realpath($path);

มันจะกลับมา:

D:\Work\OpenServer\domains\local.testsite.com\sites\default\files\custom_map

4
สิ่งนี้จะคืนค่าพา ธ ไม่ใช่ URL ซึ่งเป็นคำถามที่ถาม ในความคิดของฉันนี้ดีกว่าคำตอบที่ยอมรับ
Scott Joudry

api.drupal.org/api/drupal/includes!file.inc/function/… . drupal_realpath () เลิกใช้แล้วตามที่เห็นในความคิดเห็น
Wordzilla

1
@Wordzilla ก็ไม่เป็นเช่นนั้น หากคุณจะตรวจสอบแหล่งที่มาล่าสุดของ Drupal คุณจะพบว่ามีการใช้งานในสถานที่จำนวนมากมันไม่ได้ถูกคัดค้าน แต่การใช้งานจะต้องถูก จำกัด เอกสารในfile.incบอกว่ามันเป็น "ท้อแท้" แต่ไม่คัดค้าน
Andrey Rudenko

@ScottJoudry OP ขอเส้นทางสำหรับสาธารณะ: //ไม่ใช่ URL
kiamlaluno

@Wordzilla: เอกสารไม่ได้บอกว่ามันเลิก; พวกเขาบอกว่ามันหมดกำลังใจเพราะมันรองรับเฉพาะพา ธ ไฟล์ในตัวเครื่อง (ซึ่งระบบไฟล์สาธารณะจะเป็น) จากเอกสาร: "ใช้ฟังก์ชั่นนี้เฉพาะเมื่อคุณรู้ว่าตัวห่อข้อมูลใน URI ใช้ระบบไฟล์ในเครื่องและคุณต้องผ่านเส้นทางสัมบูรณ์ไปยังฟังก์ชั่นที่เข้ากันไม่ได้กับสตรีม URIs"
GuyPaddock

3

ดูตัวอย่างต่อไปนี้:

$scheme = file_uri_scheme($file);

if ($scheme && file_stream_wrapper_valid_scheme($scheme)) {
  $wrapper = file_stream_wrapper_get_instance_by_scheme($scheme);
  $path = $wrapper->getLocalPath($file);
}

หรือ:

$wrapper = file_stream_wrapper_get_instance_by_uri($uri);
$path = $wrapper->getDirectoryPath() . "/" . file_uri_target($uri);
print $path;

ตรวจสอบ API DrupalPublicStreamWrapperสำหรับ

การใช้file_create_url()ไม่สามารถใช้ได้ในทุกกรณี (ตามคำแนะนำอื่น ๆ ) เนื่องจาก URL ที่ส่งคืนไม่จำเป็นต้องอยู่บนเซิร์ฟเวอร์เดียวกัน และใช้$_SERVER['DOCUMENT_ROOT']งานได้เฉพาะสำหรับการกำหนดค่าเซิร์ฟเวอร์บางอย่าง

หากคุณไม่ต้องการใช้ stream wrappers คุณอาจลองวิธีแก้ปัญหาที่ง่ายกว่า:

$path = variable_get('file_public_path', conf_path() . '/files') . '/' . file_uri_target($uri);

มิฉะนั้นหากคุณต้องการบางสิ่งที่ใช้งานได้มากกว่าปกติให้ตรวจสอบโซลูชันของ @ hannanxp :

$wrapper = file_stream_wrapper_get_instance_by_uri($uri);
if ($wrapper instanceof DrupalLocalStreamWrapper) {
  $path = $wrapper->getDirectoryPath() . '/' . file_uri_target($uri);
}
else {
  // This does not appear to be a local file so there's no such thing as
  // a relative path; do appropriate error handling here.
}

อ่านเพิ่มเติม: ฉันจะแปลงไฟล์ uri เป็นเส้นทางสัมพัทธ์ได้อย่างไร


ที่เกี่ยวข้อง:

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