web-dev-qa-db-fra.com

Comment obtenir l'URL complète d'un actif dans Controller?

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

47
i.am.michiel

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.

52
solarc

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!

38
smatyas

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();
    }
}
28
iamdto

Si vous voulez obtenir cette URL depuis un template twig, utilisez:

{{ app.request.uriForPath('/uploads/myimage.jpg') }}
15
Eugene Kuzmenko

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.

10
COil

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.

8
stryba
app.request.uriForPath('/uploads/myimage.jpg') | replace({'/app_dev.php': ''})

cela évite le problème de app_dev.php

4
Ignacio

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

3
Rui Cardoso

Celui-ci fonctionne pour moi

$baseurl = $this->getRequest()->getScheme() . '://' . $this->getRequest()->getHttpHost() . $this->getRequest()->getBasePath();
2
debianek

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
2
Quentin

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 %}
1
ke20

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.

0
pedram shabani

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']
0
Yes Barry

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é!

0
Muzafar Ali