Comment puis-je obtenir le chemin pour public: //

43

Je dois obtenir le chemin pour public: // à l'exécution. Existe-t-il une fonction que je peux utiliser pour l'obtenir?

Vintorg
la source

Réponses:

34

Vous pouvez utiliser le code suivant pour obtenir le chemin réel de public: //.

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

Ce code est la version simplifiée du code utilisé par file_create_url(), avec les différences suivantes:

  • Il ne permet pas aux modules tiers de modifier l'URL, car l'OP demande le chemin associé à public: //
  • Il ne vérifie pas que l'URI contient: //, puisque c'est clairement vrai
  • Il ne vérifie pas que l'URI est un URI relatif à la racine, car c'est clairement faux pour public: //
  • Il ne vérifie pas si l'URI est relatif au protocole, car c'est clairement faux dans le cas du PO
  • Il ne vérifie pas que l'URI n'est pas un flux correctement formaté, car public: // est un flux correctement formaté
  • Il ne vérifie pas si le schéma est http ou https, car dans ce cas est public
  • Il n'appelle pas $wrapper->getExternalUrl()puisque l'OP demande le chemin, pas l'URL

Si l'OP voulait l'URL pour public: //, j'aurais utilisé le code suivant, qui est toujours une version simplifiée du code utilisé par la fonction Drupal, qui doit être plus générique.

if ($wrapper = file_stream_wrapper_get_instance_by_uri('public://')) {
  $url = $wrapper->getExternalUrl();
}
kiamlaluno
la source
3
@ junedkazi est une meilleure réponse.
AlessMascherpa
1
Lire le code utilisé par file_create_url(); vous verrez que le code exécuté, dans ce cas, est exactement celui que j'ai écrit dans ma réponse.
kiamlaluno
1
cela vous donnera le chemin complet du serveur, pas l'url.
DrCord
@DrCord Il vous donne la même chose que file_create_url()vous.
kiamlaluno
1
non ça ne /var/www/webroot/etc/more_folders/
marche
39

Vous pouvez utiliser la fonction file_create_url .

$uri = 'public://';
$path= file_create_url($uri)
Junedkazi
la source
Cela vous donne l'URL, mais y compris le serveur. J'ai utilisé un regex simple et le global $base_urlpour le supprimer et rendre ce serveur agnostique. global $base_url; $path = file_create_url($file_object->uri); $path = preg_replace('#' . $base_url . '#', '', $path);Assurez-vous d'utiliser le '#' dans l'expression régulière, sinon le remplacement échouera à cause d'un '/' non échappé dans $ base_url.
DrCord
3
L'OP a demandé le chemin, pas l'URL.
kiamlaluno
20

Si vous utilisez uniquement des fichiers locaux ( pas à distance! ), Vous pouvez également essayer drupal_realpath ()

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

Il reviendra:

D:\Work\OpenServer\domains\local.testsite.com\sites\default\files\custom_map
Andrey Rudenko
la source
4
Cela renvoie un chemin et non une URL, comme le demande la question. À mon avis, c'est mieux que la réponse acceptée.
Scott Joudry
api.drupal.org/api/drupal/includes!file.inc/function/… . drupal_realpath () est obsolète, comme indiqué dans les commentaires.
Wordzilla
1
@ Wordzilla, eh bien ce n'est pas. Si vous voulez vérifier la dernière source Drupal, vous constaterez que son utilisation est très répandue. Elle n'est pas obsolète, mais son utilisation doit être restreinte. La documentation dans file.inc indique que cela est "déconseillé", mais pas obsolète.
Andrey Rudenko
@ScottJoudry L'OP demande le chemin pour public: // , pas l'URL.
kiamlaluno
@Wordzilla: Les docs ne disent pas que c'est obsolète; ils ont dit que c'est découragé car il ne gère que les chemins de fichiers locaux (ce que serait le système de fichiers public). Dans la documentation: "N'utilisez cette fonction que si vous savez que l'encapsuleur de flux de l'URI utilise le système de fichiers local et que vous devez transmettre un chemin absolu à une fonction incompatible avec les URI de flux."
GuyPaddock
3

Voir les exemples suivants:

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

Vérifiez l'API pour DrupalPublicStreamWrapper.

L'utilisation file_create_url()ne fonctionne pas dans tous les cas (comme le suggèrent les autres réponses), car l'URL renvoyée ne doit pas nécessairement se trouver sur le même serveur. Et l'utilisation $_SERVER['DOCUMENT_ROOT']ne fonctionne que pour certaines configurations de serveur.

Si vous ne souhaitez pas utiliser les wrappers de flux, vous pouvez essayer une solution plus simple:

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

Sinon, si vous avez besoin de quelque chose qui fonctionne de manière plus générale, vérifiez la solution 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.
}

En savoir plus: Comment convertir un fichier URI en chemin relatif?


En relation:

Kenorb
la source