Як отримати шлях для публіки: //


43

Мені потрібно отримати шлях для публічного: // під час виконання. Чи є функція, яку я можу використовувати, щоб отримати її?

Відповіді:


34

Ви можете використовувати наступний код, щоб отримати реальний шлях public: //.

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

Цей код є спрощеною версією використовуваного коду file_create_url()з такими відмінностями:

  • Це не дозволяє стороннім модулям змінювати URL-адресу, оскільки ОП запитує шлях, пов’язаний із public: //
  • Він не перевіряє, що URI містить: //, оскільки це явно вірно
  • Він не перевіряє, що URI є кореневим URI, оскільки це явно неправдиво для громадськості: //
  • Він не перевіряє, що URI є протокольним, оскільки це явно неправдиво у випадку ОП
  • Він не перевіряє, що URI не є правильно відформатованим потоком, оскільки public: // - це правильно відформатований потік
  • Він не перевіряє, чи є схема http або https, оскільки в цьому випадку є загальнодоступною
  • Він не дзвонить, $wrapper->getExternalUrl()оскільки ОП запитує шлях, а не URL-адресу

Якби ОП бажала URL-адреси для загальнодоступних: //, я б використав наступний код, який все ще є спрощеною версією коду, який використовується функцією Drupal, який повинен бути більш загальним.

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

3
@ junedkazi's - краща відповідь.
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-адресу, але включає сервер. Я використовував простий регулярний вираз і global $base_urlвидалити його і зробити цей сервер агностиком. global $base_url; $path = file_create_url($file_object->uri); $path = preg_replace('#' . $base_url . '#', '', $path);Не забудьте використати "#" у регулярному виразі, інакше заміна не вдасться через невідкладений "/" в $ base_url.
DrCord

3
ОП запитував шлях, а не 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-адресу, до чого задається питання. На мою думку, це краще, ніж прийнята відповідь.
Скотт Джодрі

api.drupal.org/api/drupal/includes!file.inc/function/… . drupal_realpath () застаріло, як видно в коментарях.
Wordzilla

1
@Wordzilla, ну це не так. Якщо ви перевірите останнє джерело Drupal, то виявите, що його використовують у великій кількості місць, воно не застаріле, але його використання потрібно обмежити. Документація у file.inc говорить про те, що вона " відсторонена ", але не застаріла.
Андрій Руденко

@ScottJoudry ОП запитує шлях для публіки: // , а не URL.
kiamlaluno

@Wordzilla: Документи не кажуть, що вона застаріла; вони сказали, що це не рекомендується, оскільки він обробляє лише локальні шляхи до файлів (якими буде публічна файлова система). З документів: "Використовуйте цю функцію, лише якщо вам відомо, що обгортка потоку в URI використовує локальну файлову систему, і вам потрібно пройти абсолютний шлях до функції, несумісної з URI потоків."
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']працює лише для певних конфігурацій сервера.

Якщо ви не хочете використовувати обтікачі потоків, ви можете спробувати більш просте рішення:

$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 у відносний шлях?


Пов'язані:

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.