【发布时间】:2012-02-07 08:03:08
【问题描述】:
我需要在控制器中生成一些 JSON 内容,并且我需要获取位于此处的上传图像的完整 URL:/web/uploads/myimage.jpg。
我怎样才能得到它的完整网址?
http://www.mywebsite.com/uploads/myimage.jpg
【问题讨论】:
我需要在控制器中生成一些 JSON 内容,并且我需要获取位于此处的上传图像的完整 URL:/web/uploads/myimage.jpg。
我怎样才能得到它的完整网址?
http://www.mywebsite.com/uploads/myimage.jpg
【问题讨论】:
你可以从请求对象生成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())
您可以在 Controller 中使用它:
$this->getRequest()->getUriForPath('/uploads/myimage.jpg');
编辑:此方法还包括app.php 和app_dev.php 到网址。意思是只有在启用 url-rewriting 时才能在生产环境中工作!
【讨论】:
app_dev.php url,一个资产会被附加到这个url,例如http://bla.com/app_dev.php/uploads/test.png - 不存在。
您可以使用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();
}
}
【讨论】:
templating.helper.assets 仅在启用php 模板引擎时可用。
assets.packages。
如果您想从树枝模板中获取此网址,请使用:
{{ app.request.uriForPath('/uploads/myimage.jpg') }}
【讨论】:
asset 给了我完整的路径,但不是 uri(不是绝对的)
从 Symfony 2.1 开始,您可以使用:
$request->getSchemeAndHttpHost().'/uploads/myimage.jpg';
注意:此解决方案的优势在于可以在 DEV 和 PROD 环境中工作。
【讨论】:
最好的解决方案是恕我直言,看看Twig 对asset 的实现,您可以在以下位置找到:
\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服务或者类。
【讨论】:
app.request.uriForPath('/uploads/myimage.jpg') | replace({'/app_dev.php': ''})
这样就避免了app_dev.php的问题
【讨论】:
此解决方案不需要在配置中添加任何变量或参数,并且与 Twig 用于{{ absolute_url() }} 的函数相同
public function yourAction(AssetsHelper $assetsHelper, HttpFoundationExtension $httpExtension)
{
$assetsPath = $assetsHelper->getUrl('/img/test.jpg');
$assetFullUrl = $httpExtension->generateAbsoluteUrl($assetPath);
}
您的资产的完整网址将在$assetFullUrl
【讨论】:
这个适合我
$baseurl = $this->getRequest()->getScheme() . '://' . $this->getRequest()->getHttpHost() . $this->getRequest()->getBasePath();
【讨论】:
方法app.request.uriForPath() 给出来自路径的绝对URL。 Helper asset() 给出了资产的路径。
{{ app.request.uriForPath(asset('bundles/mybundle/images/name.png')) }}
对于应用程序不在域根目录的情况,两者兼备很重要,例如:
http://mydomain.com/myapp/app.php
【讨论】:
对于 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']
【讨论】:
@Al Jey 解决方案适用于 Assetic(在 Symfony 2.6 上测试)
{% image '@AcmeBundle/Resources/public/images/myimage.jpg' %}
<img src="{{ app.request.uriForPath(asset_url) }}">
{% endimage %}
【讨论】:
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.yml、config_dev.yml 和config_test.yml,因此当您在不同环境之间移动项目时,您不必改变它,因为它已经存在..
干杯!
【讨论】:
您可以使用函数 getSchemeAndHttpHost() 获取方案和 HTTP 主机,并使用函数 getBasePath() 获取执行此请求的根路径
$request->getSchemeAndHttpHost().$request->getBasePath()."/uploads/myimage.jpg"
此方法适用于 app.php 和 app_dev.php。
【讨论】:
您可以使用以下代码获取站点 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;
【讨论】: