Jak uzyskać ścieżkę do publicznego: //

43

Muszę uzyskać ścieżkę do public: // w czasie wykonywania. Czy jest funkcja, której mogę użyć, aby ją uzyskać?

Vintorg
źródło

Odpowiedzi:

34

Możesz użyć następującego kodu, aby uzyskać prawdziwą ścieżkę public: //.

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

Ten kod jest uproszczoną wersją używanego kodu file_create_url(), z następującymi różnicami:

  • Nie pozwala modułom zewnętrznym zmieniać adresu URL, ponieważ OP prosi o ścieżkę związaną z public: //
  • Nie sprawdza, czy identyfikator URI zawiera: //, ponieważ jest to oczywiście prawda
  • Nie sprawdza, czy identyfikator URI jest identyfikatorem URI zależnym od katalogu głównego, ponieważ jest to oczywiście fałsz dla public: //
  • Nie sprawdza, czy identyfikator URI jest względny względem protokołu, ponieważ w przypadku PO jest to oczywiście nieprawda
  • Nie sprawdza, czy identyfikator URI nie jest poprawnie sformatowanym strumieniem, ponieważ public: // jest poprawnie sformatowanym strumieniem
  • Nie sprawdza, czy schemat jest http czy https, ponieważ w tym przypadku jest publiczny
  • Nie dzwoni, $wrapper->getExternalUrl()ponieważ OP prosi o ścieżkę, a nie o adres URL

Gdyby OP chciał, aby adres URL był publiczny: //, użyłbym następującego kodu, który wciąż jest uproszczoną wersją kodu używanego przez funkcję Drupal, która musi być bardziej ogólna.

if ($wrapper = file_stream_wrapper_get_instance_by_uri('public://')) {
  $url = $wrapper->getExternalUrl();
}
kiamlaluno
źródło
3
@ junedkazi's jest lepszą odpowiedzią.
AlessMascherpa
1
Przeczytaj kod używany przez file_create_url(); zobaczysz, że wykonany kod jest w tym przypadku dokładnie tym, który napisałem w mojej odpowiedzi.
kiamlaluno
1
dostaniesz pełną ścieżkę do serwera, a nie adres URL.
DrCord,
@DrCord To daje to samo, co file_create_url()daje.
kiamlaluno
1
nie, nie robi, daje ci ścieżkę do serwera jak/var/www/webroot/etc/more_folders/
DrCord,
39

Możesz użyć funkcji file_create_url .

$uri = 'public://';
$path= file_create_url($uri)
junedkazi
źródło
Otrzymasz adres URL, ale wraz z serwerem. Użyłem prostego wyrażenia regularnego i global $base_urlaby go usunąć i uczynić ten serwer agnostycznym. global $base_url; $path = file_create_url($file_object->uri); $path = preg_replace('#' . $base_url . '#', '', $path);Upewnij się, że używasz „#” w wyrażeniu regularnym, w przeciwnym razie zastąpienie nie powiedzie się z powodu nieskasowanego znaku „/” w $ base_url.
DrCord,
3
OP poprosił o podanie ścieżki, a nie adresu URL.
kiamlaluno
20

Jeśli używasz tylko plików lokalnych ( nie zdalnych! ), Możesz także wypróbować drupal_realpath ()

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

Zwróci:

D:\Work\OpenServer\domains\local.testsite.com\sites\default\files\custom_map
Andrey Rudenko
źródło
4
Zwraca ścieżkę, a nie adres URL, o co pyta pytanie. Moim zdaniem jest to lepsze niż zaakceptowana odpowiedź.
Scott Joudry
api.drupal.org/api/drupal/includes!file.inc/function/… . Funkcja drupal_realpath () jest przestarzała, jak widać w komentarzach.
Wordzilla
1
@Wordzilla, cóż, nie jest. Jeśli sprawdzisz najnowsze źródło Drupala, zobaczysz, że jest ono używane w dużej ilości miejsc, nie jest przestarzałe, ale jego użycie musi być ograniczone. Dokumentacja w pliku.in.in mówi, że jest „odradzany”, ale nie przestarzały.
Andrey Rudenko
@ScottJoudry OP prosi o podanie ścieżki public: // , a nie adresu URL.
kiamlaluno
@Wordzilla: Dokumenty nie mówią, że jest przestarzałe; powiedzieli, że jest to odradzane, ponieważ obsługuje tylko lokalne ścieżki plików (którym byłby publiczny system plików). Z dokumentacji: „Użyj tej funkcji tylko wtedy, gdy wiesz, że opakowanie strumienia w identyfikatorze URI korzysta z lokalnego systemu plików i musisz podać ścieżkę bezwzględną do funkcji niezgodnej z identyfikatorami URI strumienia”.
GuyPaddock,
3

Zobacz następujące przykłady:

$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);
}

lub:

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

Sprawdź API dla DrupalPublicStreamWrapper.

Używanie file_create_url()nie działa we wszystkich przypadkach (jak sugerują inne odpowiedzi), ponieważ zwracany adres URL nie musi znajdować się na tym samym serwerze. Używanie $_SERVER['DOCUMENT_ROOT']działa tylko w przypadku niektórych konfiguracji serwerów.

Jeśli nie chcesz używać owijania strumieniowego, możesz wypróbować prostsze rozwiązanie:

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

W przeciwnym razie, jeśli potrzebujesz czegoś, co działa bardziej ogólnie, sprawdź rozwiązanie @ 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.
}

Czytaj więcej: Jak przekonwertować plik URI na ścieżkę względną?


Związane z:

kenorb
źródło