Wie bekomme ich die volle URL für einen Vermögenswert im Controller?
Frage
Ich muss JSON -Inhalte in Controller generieren und die vollständige URL in ein hochgeladenes Bild hier bringen: hier gelegen: /web/uploads/myimage.jpg
.
Wie kann ich die volle URL davon bekommen?
http://www.mywebsite.com/uploads/myimage.jpg
Lösung
Sie können die URL aus dem Anforderungsobjekt generieren:
$baseurl = $request->getScheme() . '://' . $request->getHttpHost() . $request->getBasePath();
Sie könnten eine Zweigverlängerung machen, die die schneidet /web
Ein Teil Ihres Pfades und verwendet die Anforderung, die Basis -URL zu generieren.
sehen Symfony\Component\Routing\Generator\UrlGenerator::doGenerate
für eine solide Implementierung.
Außerdem hat Twig Zugriff auf die Anfrage von app.request
.
Andere Tipps
Sie können dies in Controller verwenden:
$this->getRequest()->getUriForPath('/uploads/myimage.jpg');
BEARBEITEN : Diese Methode enthält auch die app.php
und app_dev.php
zur URL. Bedeutung Dies funktioniert nur in der Produktion, wenn URL-Wrewriting aktiviert ist!
Du kannst den ... benutzen templating.helper.assets
Service.
Definieren Sie zuerst Ihre Assets Basis -URL :
# app/config/config.yml
framework:
templating:
assets_base_url: "http://www.mywebsite.com/"
Rufen Sie dann einfach den Dienst in Ihrem Controller, Befehl, Befehl oder wo immer Sie sind:
<?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();
}
}
Wenn Sie diese URL innerhalb einer Zweigvorlage verwenden möchten, verwenden Sie:
{{ app.request.uriForPath('/uploads/myimage.jpg') }}
Zum Symfony 2.1 Sie können verwenden:
$request->getSchemeAndHttpHost(). '/uploads/myimage.jpg';
Notiz: Diese Lösung hat den Vorteil zu arbeiten beide Entwicklungs- und Produktumgebungen.
Die beste Lösung wäre IMHO Twig
Implementierung von asset
, was Sie finden können in:
\Symfony\Bundle\TwigBundle\Extension\AssetsExtension
in der Methode:
public function getAssetUrl($path, $packageName = null, $absolute = false, $version = null)
das verwendet im Grunde die templating.helper.assets
Service ähnlich wie bei der Antwort von @iamdto:
$url = $this->container->get('templating.helper.assets')->getUrl($path, $packageName, $version);
Oder direkt verwenden AssetsExtension
Service oder Klasse jeweils.
app.request.uriForPath('/uploads/myimage.jpg') | replace({'/app_dev.php': ''})
Dies vermeiden das Problem von app_dev.php
Diese Lösung erfordert kein Hinzufügen von Variablen oder Parametern für die Konfiguration und ist dieselbe Funktion, die von Twig für verwendet wird {{ absolute_url() }}
public function yourAction(AssetsHelper $assetsHelper, HttpFoundationExtension $httpExtension)
{
$assetsPath = $assetsHelper->getUrl('/img/test.jpg');
$assetFullUrl = $httpExtension->generateAbsoluteUrl($assetPath);
}
Die vollständige URL Ihres Vermögenswerts wird eingeschaltet sein $assetFullUrl
Dieser funktioniert für mich
$baseurl = $this->getRequest()->getScheme() . '://' . $this->getRequest()->getHttpHost() . $this->getRequest()->getBasePath();
Methode app.request.uriForPath()
gibt eine absolute URL von einem Pfad. Helfer asset()
gibt den Weg eines Vermögenswerts.
{{ app.request.uriForPath(asset('bundles/mybundle/images/name.png')) }}
Es ist wichtig, beide für den Fall zu haben, in dem sich die Anwendung nicht an der Wurzel der Domäne befindet, für z. B.:
http://mydomain.com/myapp/app.php
Die @al Jey -Lösung funktioniert gut mit assetic (getestet auf Symfony 2.6)
{% image '@AcmeBundle/Resources/public/images/myimage.jpg' %}
<img src="{{ app.request.uriForPath(asset_url) }}">
{% endimage %}
Arbeitslösung in Symfony 3.3+
# app/config/config.yml
parameters:
...
base_url: 'http://mywebsite.com'
Um es in Ihre Controller -Aktion zu bekommen:
$baseUrl = $this->getParameter('base_url');
Sie können jetzt Ihr Bild an die Anhängerschaft anhängen, z. B.: $baseUrl . '/uploads/' . $image
Oder wenn Sie mögen, können Sie hochgeladene Assets Basis -URL in config.yml definieren und in Controller -Aktion darauf zugreifen.
Das Beste an dieser Lösung wäre die Fähigkeit, sie für verschiedene Umgebungen vorzu definieren, z. B. in config.yml
, config_dev.yml
und config_test.yml
Wenn Sie Ihr Projekt zwischen verschiedenen Umgebungen verschieben, müssen Sie es nicht ändern, da es bereits da ist.
Prost!
Für CDNs können Sie auch die injizieren Packages
direkt in Ihren Service.
Zuerst die Asset -Basis -URL in config.yml:
framework:
assets:
base_url:
- 'http://cdn.mysite.com'
Dann der lustige Teil:
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);
}
}
Wenn Sie die automatische Autobahneinstellung aktivieren, müssen Sie nichts in Ihrem konfigurieren services.yml
, sonst so etwas wie:
services:
App\Service\SomeClass:
class: App\Service\SomeClass
arguments: ['@assets.packages']
Sie können die Funktion verwenden GetSchemeandhttphost () Für den Schema und den HTTP -Host erhält und die Funktion verwenden getBasepath () Um den Stammpfad zu erhalten, aus dem diese Anfrage ausgeführt wird
$request->getSchemeAndHttpHost().$request->getBasePath()."/uploads/myimage.jpg"
Diese Methode funktioniert einwandfrei für App.php und app_dev.php.
Sie können die URL -Site -URL auf Webordner erhalten, indem Sie den folgenden Code verwenden
$ 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;