Como obtenho o caminho para o público: //

43

Eu preciso pegar o caminho para public: // em tempo de execução. Existe uma função que eu possa usar para obtê-la?

vintorg
fonte

Respostas:

34

Você pode usar o seguinte código, para obter o caminho real do público: //.

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

Este código é a versão simplificada do código usado por file_create_url(), com as seguintes diferenças:

  • Ele não permite que módulos de terceiros alterem a URL, pois o OP está solicitando o caminho associado a public: //
  • Não verifica se o URI contém: //, pois isso é claramente verdade
  • Ele não verifica se o URI é um URI relativo à raiz, pois isso é claramente falso para public: //
  • Ele não verifica se o URI é relativo ao protocolo, pois isso é claramente falso no caso do OP
  • Ele não verifica se o URI não é um fluxo formatado corretamente, pois public: // é um fluxo formatado corretamente
  • Não verifica se o esquema é http ou https, pois nesse caso é público
  • Não chama, $wrapper->getExternalUrl()pois o OP está pedindo o caminho, não o URL

Se o OP quisesse a URL para public: //, eu teria usado o código a seguir, que ainda é uma versão simplificada do código usado pela função Drupal, que precisa ser mais genérica.

if ($wrapper = file_stream_wrapper_get_instance_by_uri('public://')) {
  $url = $wrapper->getExternalUrl();
}
kiamlaluno
fonte
3
@ junedkazi's é uma resposta melhor.
AlessMascherpa 29/04
1
Leia o código usado por file_create_url(); você verá que o código executado, neste caso, é exatamente o que escrevi na minha resposta.
kiamlaluno
1
isso fornecerá o caminho completo do servidor, não o URL.
DrCord 29/07
@DrCord Dá a mesma coisa que a file_create_url()você.
kiamlaluno
1
não, não, ele fornece um caminho do servidor como #/var/www/webroot/etc/more_folders/
DrCord 30/07/14
39

Você pode usar a função file_create_url .

$uri = 'public://';
$path= file_create_url($uri)
junedkazi
fonte
Isso fornece o URL, mas inclui o servidor. Eu usei um regex simples e o global $base_urlpara removê-lo e tornar esse servidor independente. global $base_url; $path = file_create_url($file_object->uri); $path = preg_replace('#' . $base_url . '#', '', $path);Certifique-se de usar o '#' no regex, caso contrário, a substituição falhará devido a um '/' não escapado no $ base_url.
DrCord 29/07
3
O OP solicitou o caminho, não o URL.
kiamlaluno
20

Caso esteja usando apenas arquivos locais ( não remotos! ), Você também pode tentar drupal_realpath ()

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

Voltará:

D:\Work\OpenServer\domains\local.testsite.com\sites\default\files\custom_map
Andrey Rudenko
fonte
4
Isso retorna um caminho e não um URL, que é o que a pergunta pede. Na minha opinião, isso é melhor do que a resposta aceita.
Scott Joudry
api.drupal.org/api/drupal/includes!file.inc/function/… . drupal_realpath () está obsoleto como visto nos comentários.
Wordzilla
1
@ Wordzilla, bem, não é. Se você verificar a fonte mais recente do Drupal, encontrará seu uso em grande quantidade de lugares, não é preterido, mas deve ser restrito. A documentação em file.inc diz que é "desencorajada", mas não obsoleta.
precisa
@ScottJoudry O OP solicita o caminho public: // , não o URL.
kiamlaluno
@Wordzilla: Os documentos não dizem que está obsoleto; eles disseram que é desencorajado porque ele lida apenas com caminhos de arquivos locais (o que o sistema de arquivos público seria). Dos documentos: "Use esta função apenas se você souber que o wrapper de fluxo no URI usa o sistema de arquivos local e precisar passar um caminho absoluto para uma função que é incompatível com os URIs de fluxo".
precisa saber é o seguinte
3

Veja os seguintes exemplos:

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

ou:

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

Verifique a API para DrupalPublicStreamWrapper.

O uso file_create_url()não funciona em todos os casos (como as outras respostas sugerem), porque o URL retornado não precisa estar no mesmo servidor. E o uso $_SERVER['DOCUMENT_ROOT']funciona apenas para determinadas configurações do servidor.

Se você não quiser usar wrappers de fluxo, tente a solução mais simples:

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

Caso contrário, se você precisar de algo que funcione de maneira mais geral, verifique a solução do @ 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.
}

Leia mais: Como converter uma interface de usuário de arquivo em caminho relativo?


Relacionado:

kenorb
fonte