¿Cómo obtener la URL completa para un activo en el controlador?
Pregunta
Necesito generar un contenido JSON en el controlador y necesito obtener la URL completa en una imagen cargada situada aquí: /web/uploads/myimage.jpg
.
¿Cómo puedo obtener la URL completa?
http://www.mywebsite.com/uploads/myimage.jpg
Solución
Puede generar la URL desde el objeto de solicitud:
$baseurl = $request->getScheme() . '://' . $request->getHttpHost() . $request->getBasePath();
Podrías hacer una extensión de ramita que corta el /web
Parte de su ruta y usa la solicitud para generar la URL base.
ver Symfony\Component\Routing\Generator\UrlGenerator::doGenerate
para una implementación más sólida.
Además, Twig tiene acceso a la solicitud desde app.request
.
Otros consejos
Puedes usar esto en el controlador:
$this->getRequest()->getUriForPath('/uploads/myimage.jpg');
EDITAR : Este método también incluye el app.php
y app_dev.php
a la url. Sentido Esto solo funcionará en producción cuando la reducción de URL esté habilitada!
Puedes usar el templating.helper.assets
Servicio.
Primero defina tu URL base de activos :
# app/config/config.yml
framework:
templating:
assets_base_url: "http://www.mywebsite.com/"
Luego, simplemente llame al servicio desde su controlador, comando o donde sea que esté:
<?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();
}
}
Si desea obtener esta URL dentro de una plantilla de ramita, use:
{{ app.request.uriForPath('/uploads/myimage.jpg') }}
A partir de Symfony 2.1 puedes usar:
$request->getSchemeAndHttpHost(). '/uploads/myimage.jpg';
Nota: Esta solución tiene la ventaja de trabajar en ambas cosas Entornos de desarrollo y prod.
La mejor solución sería en mi humilde opinión ver Twig
Implementación de asset
, que puedes encontrar en:
\Symfony\Bundle\TwigBundle\Extension\AssetsExtension
En el método:
public function getAssetUrl($path, $packageName = null, $absolute = false, $version = null)
que básicamente usa el templating.helper.assets
Servicio similar a la respuesta de @iamdto:
$url = $this->container->get('templating.helper.assets')->getUrl($path, $packageName, $version);
O usar directamente el AssetsExtension
servicio o clase respectivamente.
app.request.uriForPath('/uploads/myimage.jpg') | replace({'/app_dev.php': ''})
Esto evita el problema de app_dev.php
Esta solución no requiere agregar ninguna variable o parámetro en la configuración y es la misma función que utiliza Twig para {{ absolute_url() }}
public function yourAction(AssetsHelper $assetsHelper, HttpFoundationExtension $httpExtension)
{
$assetsPath = $assetsHelper->getUrl('/img/test.jpg');
$assetFullUrl = $httpExtension->generateAbsoluteUrl($assetPath);
}
La URL completa de su activo estará en $assetFullUrl
Esta funciona para mí
$baseurl = $this->getRequest()->getScheme() . '://' . $this->getRequest()->getHttpHost() . $this->getRequest()->getBasePath();
Método app.request.uriForPath()
Da una URL absoluta de un camino. Ayudante asset()
da el camino de un activo.
{{ app.request.uriForPath(asset('bundles/mybundle/images/name.png')) }}
Es importante tener ambos para el caso donde la aplicación no está en la raíz del dominio, por ejemplo:
http://mydomain.com/myapp/app.php
La solución @al Jey funciona bien con Assetic (probada en Symfony 2.6)
{% image '@AcmeBundle/Resources/public/images/myimage.jpg' %}
<img src="{{ app.request.uriForPath(asset_url) }}">
{% endimage %}
Solución de trabajo en Symfony 3.3+
# app/config/config.yml
parameters:
...
base_url: 'http://mywebsite.com'
Para obtenerlo en la acción de su controlador:
$baseUrl = $this->getParameter('base_url');
Ahora puede agregar su imagen a él, por ejemplo: $baseUrl . '/uploads/' . $image
O si lo desea, puede definir la URL base de activos cargados en config.yml y acceder a ella en la acción del controlador.
Lo mejor de esta solución sería la capacidad de predefinir predefinir para diferentes entornos, por ejemplo: en config.yml
, config_dev.yml
y config_test.yml
Entonces, cuando mueve su proyecto entre diferentes entornos, no tiene que cambiarlo, ya que ya está allí.
¡Salud!
Para CDN, también puede inyectar el Packages
directamente en su servicio.
Primero la URL base de activos en config.yml:
framework:
assets:
base_url:
- 'http://cdn.mysite.com'
Entonces la parte divertida:
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 tiene habilitado automáticamente automáticamente, no necesitará configurar nada en su services.yml
, de lo contrario, algo como:
services:
App\Service\SomeClass:
class: App\Service\SomeClass
arguments: ['@assets.packages']
Puedes usar la función getSchemeAndHttTphost () para obtener el esquema y el host HTTP y usar la función getBasepath () para obtener la ruta raíz desde la cual se ejecuta esta solicitud
$request->getSchemeAndHttpHost().$request->getBasePath()."/uploads/myimage.jpg"
Este método funciona bien para App.php y app_dev.php.
Puede obtener la URL del sitio, IE, punto a la carpeta web utilizando el siguiente código
$ Protocol = StripOS ($ _ Server ['server_protocol'], 'https') === verdadero? '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;