¿Cómo obtengo el camino para público: //

43

Necesito obtener la ruta para public: // en tiempo de ejecución. ¿Hay alguna función que pueda usar para obtenerla?

vintorg
fuente

Respuestas:

34

Puede usar el siguiente código para obtener la ruta real de public: //.

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

Este código es la versión simplificada del código utilizado por file_create_url(), con las siguientes diferencias:

  • No permite que los módulos de terceros alteren la URL, ya que el OP solicita la ruta asociada con public: //
  • No comprueba que el URI contiene: //, ya que esto es claramente cierto
  • No comprueba que el URI sea un URI relativo a la raíz, ya que esto es claramente falso para público: //
  • No comprueba que el URI sea relativo al protocolo, ya que esto es claramente falso en el caso del OP
  • No comprueba que el URI no sea una secuencia formateada correctamente, ya que public: // es una secuencia formateada correctamente
  • No comprueba si el esquema es http o https, ya que en este caso es público
  • No llama $wrapper->getExternalUrl()porque el OP pregunta por la ruta, no por la URL

Si el OP quisiera la URL para public: //, habría utilizado el siguiente código, que sigue siendo una versión simplificada del código utilizado por la función Drupal, que debe ser más genérica.

if ($wrapper = file_stream_wrapper_get_instance_by_uri('public://')) {
  $url = $wrapper->getExternalUrl();
}
kiamlaluno
fuente
3
@ junedkazi es una mejor respuesta.
AlessMascherpa
1
Lea el código utilizado por file_create_url(); verá que el código ejecutado, en este caso, es exactamente el que escribí en mi respuesta.
kiamlaluno
1
esto le dará la ruta completa del servidor, no la url.
DrCord
@DrCord Te da lo mismo que file_create_url()te da a ti.
kiamlaluno
1
no, no lo hace, te da una ruta de servidor como/var/www/webroot/etc/more_folders/
DrCord
39

Puede usar la función file_create_url .

$uri = 'public://';
$path= file_create_url($uri)
junedkazi
fuente
Esto te da la URL, pero incluye el servidor. Utilicé una expresión regular simple y la global $base_urlpara eliminarla y hacer que este servidor sea agnóstico. global $base_url; $path = file_create_url($file_object->uri); $path = preg_replace('#' . $base_url . '#', '', $path);Asegúrese de usar el '#' en la expresión regular, de lo contrario, el reemplazo fallará debido a un '/' sin escape en $ base_url.
DrCord
3
El OP solicitó la ruta, no la URL.
kiamlaluno
20

En caso de que solo use archivos locales (¡ no remotos! ), También puede probar drupal_realpath ()

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

Regresará:

D:\Work\OpenServer\domains\local.testsite.com\sites\default\files\custom_map
Andrey Rudenko
fuente
44
Esto devuelve una ruta y no una URL, que es lo que pide la pregunta. En mi opinión, esto es mejor que la respuesta aceptada.
Scott Joudry
api.drupal.org/api/drupal/includes!file.inc/function/… . drupal_realpath () está en desuso como se ve en los comentarios.
Wordzilla
1
@ Wordzilla, bueno, no lo es. Si verifica la última fuente de Drupal, encontrará que se usa en una gran cantidad de lugares, no está en desuso, pero su uso debe estar restringido. La documentación en file.inc dice que está "desaconsejada", pero no en desuso.
Andrey Rudenko
@ScottJoudry El OP solicita la ruta para public: // , no la URL.
kiamlaluno
@ Wordzilla: los documentos no dicen que está en desuso; dijeron que se desaconseja porque solo maneja rutas de archivos locales (que sería el sistema de archivos público). De los documentos: "Solo use esta función si sabe que el contenedor de flujo en el URI usa el sistema de archivos local, y necesita pasar una ruta absoluta a una función que es incompatible con los URI de flujo".
GuyPaddock el
3

Vea los siguientes ejemplos:

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

o:

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

Verifica API para DrupalPublicStreamWrapper.

El uso file_create_url()no funciona en todos los casos (como sugieren las otras respuestas), porque la URL devuelta no tiene que estar en el mismo servidor. Y el uso $_SERVER['DOCUMENT_ROOT']funciona solo para ciertas configuraciones de servidor.

Si no desea utilizar envoltorios de flujo, puede intentar una solución más simple:

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

De lo contrario, si necesita algo que funcione de manera más general, consulte la solución de @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.
}

Leer más: ¿Cómo puedo convertir una uri de archivo en una ruta relativa?


Relacionado:

kenorb
fuente