【问题标题】:How to get the full url for an asset in Controller?如何在 Controller 中获取资产的完整 url?
【发布时间】:2012-02-07 08:03:08
【问题描述】:

我需要在控制器中生成一些 JSON 内容,并且我需要获取位于此处的上传图像的完整 URL:/web/uploads/myimage.jpg

我怎样才能得到它的完整网址?

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

【问题讨论】:

    标签: symfony assetic


    【解决方案1】:

    你可以从请求对象生成url:

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

    您可以制作一个树枝扩展来切断路径的/web 部分并使用请求生成基本网址。

    请参阅Symfony\Component\Routing\Generator\UrlGenerator::doGenerate 以获得更可靠的实现。

    另外,Twig 可以访问来自app.request 的请求。

    【讨论】:

    • $request = $this->getRequest();
    • getRequest() 已弃用,有利于注入 Requestobject
    • $request = $this->container->get('request'); 当您无法注入 Request 对象时(例如覆盖具有预定义签名的 setContainer())
    【解决方案2】:

    您可以在 Controller 中使用它:

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

    编辑:此方法还包括app.phpapp_dev.php 到网址。意思是只有在启用 url-rewriting 时才能在生产环境中工作

    【讨论】:

    • 对我来说,这个解决方案也适用于开发环境。
    • @RayOnAir,问题是如果你使用app_dev.php url,一个资产会被附加到这个url,例如http://bla.com/app_dev.php/uploads/test.png - 不存在。
    • 不适用于 Symfony 2.5。此代码返回路径中包含 app.php 或 app_dev.php 的 URL。顺便说一句,它可以使用,但你必须使用 str_replace() 来生成合法的 URL。
    • THX。在 Symfony 3.4.13 中工作正常。 $request->getUriForPath('/uploads/myimage.jpg');
    【解决方案3】:

    您可以使用templating.helper.assets 服务。

    首先定义你的assets base 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();
        }
    }
    

    【讨论】:

    • 这是一个很好的解决方案,因为它是最灵活的解决方案!您可以在未来将您的资产放在您想要的任何位置(即 CDN),并且只需更改配置文件中的 assets_base_url 值。
    • 请记住,templating.helper.assets 仅在启用php 模板引擎时可用。
    • 对于 Symfony 3.0+,在 PHP 中获取资产信息的等效服务是 assets.packages
    【解决方案4】:

    如果您想从树枝模板中获取此网址,请使用:

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

    【讨论】:

    • 或 {{ 资产('/uploads/myimage.jpg') }}。并不是说问题与视图有关,只是说在 twig 中有一种更简单的方法 =)
    • @MattiasSvensson asset 给了我完整的路径,但不是 uri(不是绝对的)
    • 问题是“在控制器中”而不是在树枝中
    • @barius 资产有绝对选择权
    • 适用于资产:{% image '@AcmeBundle/Resources/public/images/myimage.jpg' %} {% endimage %}
    【解决方案5】:

    从 Symfony 2.1 开始,您可以使用:

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

    注意:此解决方案的优势在于可以在 DEV 和 PROD 环境中工作。

    【讨论】:

      【解决方案6】:

      最好的解决方案是恕我直言,看看Twigasset 的实现,您可以在以下位置找到:

      \Symfony\Bundle\TwigBundle\Extension\AssetsExtension
      

      在方法中:

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

      它基本上使用类似于@iamdto 的答案的templating.helper.assets 服务:

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

      或者直接分别使用AssetsExtension服务或者类。

      【讨论】:

      • 是的,使用“asset”twig 函数的扩展助手是最安全的方法。谢谢!!
      【解决方案7】:
      app.request.uriForPath('/uploads/myimage.jpg') | replace({'/app_dev.php': ''})
      

      这样就避免了app_dev.php的问题

      【讨论】:

      • 提问者询问控制器代码,这是树枝。如果您不想将 app_dev.php 添加到您的 URL 中,您应该简单地使用 prod 控制器(app.php 或简单的“/”,如果配置正确)。
      • 感谢 Nacho,作为快速而肮脏的测试非常有用;)
      【解决方案8】:

      此解决方案不需要在配置中添加任何变量或参数,并且与 Twig 用于{{ absolute_url() }} 的函数相同

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

      您的资产的完整网址将在$assetFullUrl

      【讨论】:

        【解决方案9】:

        这个适合我

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

        【讨论】:

        • 这样就可以了。在此代码连接您的文件夹和图像文件名之后。
        • 但是从 Symfony 2.1 开始有一个快捷方式,请查看我的答案。
        【解决方案10】:

        方法app.request.uriForPath() 给出来自路径的绝对URL。 Helper asset() 给出了资产的路径。

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

        对于应用程序不在域根目录的情况,两者兼备很重要,例如:

        http://mydomain.com/myapp/app.php
        

        【讨论】:

          【解决方案11】:

          对于 CDN,您还可以将 Packages 直接注入您的服务中。

          首先是config.yml中的asset base url:

          framework:
              assets:
                  base_url:
                      - 'http://cdn.mysite.com'
          

          然后是有趣的部分:

          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']
          

          【讨论】:

            【解决方案12】:

            @Al Jey 解决方案适用于 Assetic(在 Symfony 2.6 上测试)

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

            【讨论】:

              【解决方案13】:

              Symfony 3.3+ 中的工作解决方案

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

              在你的控制器动作中得到它:

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

              您现在可以将您的图片附加到它上面,例如:$baseUrl . '/uploads/' . $image,或者如果您愿意,您可以在 config.yml 中定义上传的资产基础 url 并在控制器操作中访问它。

              此解决方案的最佳之处在于能够为不同的环境预先定义它,例如:config.ymlconfig_dev.ymlconfig_test.yml,因此当您在不同环境之间移动项目时,您不必改变它,因为它已经存在..

              干杯!

              【讨论】:

                【解决方案14】:

                您可以使用函数 getSchemeAndHttpHost() 获取方案和 HTTP 主机,并使用函数 getBasePath() 获取执行此请求的根路径

                $request->getSchemeAndHttpHost().$request->getBasePath()."/uploads/myimage.jpg"
                

                此方法适用于 app.php 和 app_dev.php。

                【讨论】:

                  【解决方案15】:

                  您可以使用以下代码获取站点 url,即指向 web 文件夹

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

                  【讨论】:

                    猜你喜欢
                    • 2019-04-08
                    • 2012-04-28
                    • 2015-03-11
                    • 2016-07-05
                    • 2012-06-06
                    • 1970-01-01
                    • 2013-06-08
                    • 2017-06-06
                    相关资源
                    最近更新 更多