Как мне получить путь для общественности: //

43

Мне нужно получить путь для public: // во время выполнения. Есть ли функция, которую я могу использовать, чтобы получить ее?

vintorg
источник

Ответы:

34

Вы можете использовать следующий код, чтобы получить реальный путь public: //.

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

Этот код является упрощенной версией используемого кода file_create_url()со следующими отличиями:

  • Он не позволяет сторонним модулям изменять URL, так как OP запрашивает путь, связанный с public: //
  • Он не проверяет URI, содержащий: //, поскольку это явно верно
  • Он не проверяет, является ли URI корневым URI, поскольку для public это явно ложь: //
  • Он не проверяет URI относительно протокола, так как это явно ложно в случае OP
  • Он не проверяет, что URI не является правильно отформатированным потоком, так как public: // является правильно отформатированным потоком
  • Он не проверяет, является ли схема http или https, так как в этом случае является публичной
  • Он не вызывает, $wrapper->getExternalUrl()так как OP запрашивает путь, а не URL

Если бы ОП требовал URL для public: //, я бы использовал следующий код, который все еще является упрощенной версией кода, используемого функцией 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)
junedkazi
источник
Это дает вам 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 OP запрашивает путь для public: // , а не 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 в относительный путь?


Связанный:

kenorb
источник