Je dois générer du contenu JSON dans le contrôleur et obtenir l'URL complète d'une image téléchargée située ici: /web/uploads/myimage.jpg
.
Comment puis-je obtenir l'URL complète?
http://www.mywebsite.com/uploads/myimage.jpg
Vous pouvez générer l'URL à partir de l'objet de requête:
$baseurl = $request->getScheme() . '://' . $request->getHttpHost() . $request->getBasePath();
Vous pouvez créer une extension twig qui coupe le /web
fait partie de votre chemin et utilise la demande pour générer l’URL de base.
voir Symfony\Component\Routing\Generator\UrlGenerator::doGenerate
pour une mise en œuvre plus solide.
De plus, Twig a accès à la requête de app.request
.
Vous pouvez l'utiliser dans Controller:
$this->getRequest()->getUriForPath('/uploads/myimage.jpg');
EDIT: Cette méthode inclut également le app.php
et app_dev.php
à l'URL. Signification cela ne fonctionnera en production que lorsque la réécriture d'URL est activée!
Vous pouvez utiliser le templating.helper.assets
un service.
Définissez d’abord votre RL de base de l’actif :
# app/config/config.yml
framework:
templating:
assets_base_url: "http://www.mywebsite.com/"
Ensuite, appelez simplement le service depuis votre contrôleur, votre commande ou où que vous soyez:
<?php
// src/Acme/Bundle/DemoBundle/Controller/DemoController.php
namespace Acme\Bundle\DemoBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class DemoController extends Controller
{
public function indexAction()
{
$myAssetUrl = $this
->get('templating.helper.assets')
->getUrl('bundles/acmedemo/js/main.js', $packageName = null)
;
// $myAssetUrl is "http://www.mywebsite.com/bundles/acmedemo/js/main.js"
return array();
}
}
Si vous voulez obtenir cette URL depuis un template twig, utilisez:
{{ app.request.uriForPath('/uploads/myimage.jpg') }}
A partir de Symfony 2.1 vous pouvez utiliser:
$request->getSchemeAndHttpHost(). '/uploads/myimage.jpg';
Remarque: Cette solution présente l'avantage de fonctionner dans les environnements les deux DEV et PROD.
La meilleure solution serait IMHO d’examiner la mise en oeuvre de Twig
par asset
, que vous pouvez trouver dans:
\Symfony\Bundle\TwigBundle\Extension\AssetsExtension
dans la méthode:
public function getAssetUrl($path, $packageName = null, $absolute = false, $version = null)
qui utilise essentiellement le templating.helper.assets
service similaire à la réponse de @ iamdto:
$url = $this->container->get('templating.helper.assets')->getUrl($path, $packageName, $version);
Ou utilisez directement le service ou la classe AssetsExtension
respectivement.
app.request.uriForPath('/uploads/myimage.jpg') | replace({'/app_dev.php': ''})
cela évite le problème de app_dev.php
Cette solution ne nécessite pas l’ajout de variable ou de paramètre dans config et est la même fonction utilisée par Twig pour {{ absolute_url() }}
public function yourAction(AssetsHelper $assetsHelper, HttpFoundationExtension $httpExtension)
{
$assetsPath = $assetsHelper->getUrl('/img/test.jpg');
$assetFullUrl = $httpExtension->generateAbsoluteUrl($assetPath);
}
L’URL complète de votre bien sera sur $assetFullUrl
Celui-ci fonctionne pour moi
$baseurl = $this->getRequest()->getScheme() . '://' . $this->getRequest()->getHttpHost() . $this->getRequest()->getBasePath();
La méthode app.request.uriForPath()
donne une URL absolue à partir d'un chemin. Helper asset()
donne le chemin d'un actif.
{{ app.request.uriForPath(asset('bundles/mybundle/images/name.png')) }}
Il est important d'avoir les deux pour le cas où l'application n'est pas à la racine du domaine, par exemple:
http://mydomain.com/myapp/app.php
La solution @Al Jey fonctionne bien avec Assetic (testée sur Symfony 2.6)
{% image '@AcmeBundle/Resources/public/images/myimage.jpg' %}
<img src="{{ app.request.uriForPath(asset_url) }}">
{% endimage %}
Vous pouvez utiliser la fonction getSchemeAndHttpHost () pour obtenir le schéma et l'hôte HTTP et utiliser la fonction getBasePath () pour obtenir le chemin racine à partir duquel cette demande est exécutée.
$request->getSchemeAndHttpHost().$request->getBasePath()."/uploads/myimage.jpg"
Cette méthode fonctionne bien pour app.php et app_dev.php.
Pour les CDN, vous pouvez également injecter le Packages
directement dans votre service.
D'abord l'URL de la base d'actifs dans config.yml:
framework:
assets:
base_url:
- 'http://cdn.mysite.com'
Puis la partie amusante:
namespace App\Service;
use Symfony\Component\Asset\Packages;
class SomeClass
{
private $packages;
public function __construct(Packages $packages)
{
$this->packages = $packages;
}
public function proxyToAssetUrl(string $path): string
{
return $this->packages->getUrl($path);
}
}
Si le câblage automatique est activé, vous n'avez pas besoin de configurer quoi que ce soit dans votre services.yml
, sinon quelque chose comme:
services:
App\Service\SomeClass:
class: App\Service\SomeClass
arguments: ['@assets.packages']
Solution de travail dans Symfony 3.3+
# app/config/config.yml
parameters:
...
base_url: 'http://mywebsite.com'
Pour l'obtenir dans l'action de votre contrôleur:
$baseUrl = $this->getParameter('base_url');
Vous pouvez maintenant y ajouter votre image e-g: $baseUrl . '/uploads/' . $image
ou si vous le souhaitez, vous pouvez définir l'URL de la base des ressources téléchargées dans config.yml et y accéder via l'action du contrôleur.
Le meilleur atout de cette solution serait la possibilité de la prédéfinir pour différents environnements. E-g: in config.yml
, config_dev.yml
et config_test.yml
Ainsi, lorsque vous déplacez votre projet entre différents environnements, vous n'avez pas besoin de le changer car il est déjà là.
À votre santé!