Как получить полный URL-адрес для актива в контроллере?

44

Мне нужно создать некоторый контент JSON в контроллере, и мне нужно получить полный URL-адрес загруженного изображения, расположенного здесь: /web/uploads/myimage.jpg.

Как я могу получить полный URL-адрес?

http://www.mywebsite.com/uploads/myimage.jpg

Теги:
assetic

17 ответов

46
Лучший ответ

Вы можете сгенерировать URL-адрес из объекта запроса:

$baseurl = $request->getScheme() . '://' . $request->getHttpHost() . $request->getBasePath();

Вы можете сделать расширение ветки, которое сокращает часть /web вашего пути и использует запрос для генерации базового url.

см. Symfony\Component\Routing\Generator\UrlGenerator::doGenerate для более надежной реализации.

Кроме того, Twig имеет доступ к запросу от app.request.

  • 5
    $request = $this->getRequest();
  • 7
    getRequest() устарела в пользу внедрения объекта Request
Показать ещё 1 комментарий
39

Вы можете использовать это в контроллере:

$this->getRequest()->getUriForPath('/uploads/myimage.jpg');

EDIT: Этот метод также включает в себя app.php и app_dev.php к URL-адресу. Значение будет работать только в том случае, если включена функция перезаписи URL!

  • 8
    Похоже, это работает только в продуктивной среде.
  • 2
    Для меня это решение работало и в среде разработки.
Показать ещё 3 комментария
27

Вы можете использовать службу templating.helper.assets.

Сначала определите свой базовый URL-адрес активов:

# app/config/config.yml
framework:
    templating:
        assets_base_url: "http://www.mywebsite.com/"

Затем просто вызовите службу из своего контроллера, команды или где бы вы ни были:

<?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();
    }
}
  • 0
    Это отличное решение, так как оно самое гибкое! Вы можете разместить свои активы в любом месте (например, CDN) в будущем и изменить только значение assets_base_url в своем конфигурационном файле.
  • 0
    Имейте в виду, что templating.helper.assets доступен только при включенном шаблонизаторе php .
Показать ещё 1 комментарий
15

Если вы хотите получить этот URL-адрес из шаблона ветки, используйте:

{{ app.request.uriForPath('/uploads/myimage.jpg') }}
  • 8
    или {{asset ('/ uploads / myimage.jpg')}}. Не то чтобы вопрос касался вида, просто сказать, что в ветке есть более легкий путь =)
  • 5
    @MattiasSvensson asset дает мне полный путь, но не URI (не абсолютное)
Показать ещё 3 комментария
9

С Symfony 2.1 вы можете использовать:

$request->getSchemeAndHttpHost(). '/uploads/myimage.jpg';

Примечание. Это решение имеет преимущество для работы в и средах DEV и PROD.

8

Лучшим решением было бы ИМХО посмотреть Twig реализацию asset, которую вы можете найти в:

\Symfony\Bundle\TwigBundle\Extension\AssetsExtension

в методе:

public function getAssetUrl($path, $packageName = null, $absolute = false, $version = null)

который в основном использует службу templating.helper.assets, похожую на @iamdto:

$url = $this->container->get('templating.helper.assets')->getUrl($path, $packageName, $version);

Или непосредственно используйте службу или класс AssetsExtension соответственно.

  • 1
    Да, использование помощника расширения функции ветки «актив» является наиболее безопасным способом. Спасибо !!
4
app.request.uriForPath('/uploads/myimage.jpg') | replace({'/app_dev.php': ''})

это позволяет избежать проблемы с app_dev.php

  • 0
    Спрашивающий спросил код контроллера, это ветка. Если вы не хотите, чтобы app_dev.php был добавлен в ваши URL, вам просто нужно использовать контроллер prod (app.php или просто «/», если он настроен правильно).
  • 0
    спасибо начо, очень полезный как быстрый и грязный тест;)
3

Это решение не требует добавления какой-либо переменной или параметра в конфигурацию и является той же функцией, которая используется Twig для {{ absolute_url() }}

public function yourAction(AssetsHelper $assetsHelper, HttpFoundationExtension $httpExtension)
{
    $assetsPath = $assetsHelper->getUrl('/img/test.jpg');
    $assetFullUrl = $httpExtension->generateAbsoluteUrl($assetPath);
}

Полный URL вашего актива будет на $assetFullUrl

3

Метод app.request.uriForPath() дает абсолютный URL-адрес из пути. Помощник asset() дает путь к активу.

{{ app.request.uriForPath(asset('bundles/mybundle/images/name.png')) }}

Важно иметь как для случая, когда приложение не находится в корне домена, например:

http://mydomain.com/myapp/app.php
  • 0
    Только этот работает для версии 1.24 Twig.
2

Это работает для меня

$baseurl = $this->getRequest()->getScheme() . '://' . $this->getRequest()->getHttpHost() . $this->getRequest()->getBasePath();
  • 0
    Это сделает свое дело. После этого кода конкаталируйте вашу папку и имя файла изображения.
  • 0
    Но есть ярлык с Symfony 2.1, проверьте мой ответ.
1

Решение @Al Jey отлично работает с Assetic (проверено на Symfony 2.6)

{% image '@AcmeBundle/Resources/public/images/myimage.jpg' %} 
    <img src="{{ app.request.uriForPath(asset_url) }}"> 
{% endimage %}
0

Вы также можете внедрить Packages непосредственно в ваш сервис.

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

Если у вас включена автопроводка, вам не нужно ничего настраивать в вашем services.yml, иначе что-то вроде:

services:
    App\Service\SomeClass:
        class: App\Service\SomeClass
        arguments: ['@assets.packages']
0

В моем случае рабочим решением для получения абсолютного URL было:

$request->getUri('/web/uploads/myimage.jpg.');
0

В Symfony 4 и, возможно, до этого, в действиях контроллера вы можете просто использовать generateUrl() с флагом ABSOLUTE_URL следующим образом:

$this->generateUrl(
        'my_route', [], UrlGeneratorInterface::ABSOLUTE_URL
    );
0

Для Twig это тоже должно работать (проще):

{{ url(asset('...')) }}
0

Вы можете получить URL-адрес сайта, чтобы указать веб-папку, используя следующий код

$protocol = stripos ($ _ SERVER ['SERVER_PROTOCOL'], 'https') === true? 'https://': 'http://';

    $hostName = $request->server->get('HTTP_HOST');

    $baseDirectory = "";

    if(!empty($this->container->get('router')->getContext()->getBaseUrl())){

        $baseDirectory = str_replace('app_dev.php', '', $this->container->get('router')->getContext()->getBaseUrl());
    }

    $rootUrl = $protocol.$hostName.$baseDirectory;
0

Рабочее решение Symfony 3.3 +

# app/config/config.yml
parameters:
    ...
    base_url: 'http://mywebsite.com'

Чтобы получить его в действии вашего контроллера:

$baseUrl = $this->getParameter('base_url');

Теперь вы можете добавить свое изображение к нему e-g: $baseUrl . '/uploads/' . $image или, если хотите, вы можете определить URL базы данных загруженных ресурсов в config.yml и получить доступ к ней в действии контроллера.

Самое лучшее в этом решении - это возможность предварительно определить его для разных сред, например: в config.yml, config_dev.yml и config_test.yml, поэтому, когда вы перемещаете проект между разными средами, вам не нужно измените его, как он уже там.

Ура!

Ещё вопросы

Сообщество Overcoder
Наверх
Меню