我有字段'url'的Message实体.和MessageType表单.用户可以在"url"中键入不同的URL,但只有主机持久保存到数据库中.我需要使用Symfony2 Form Event.所以我尝试在下一个代码中实现它:
class MessageType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('url');
$builder->addEventListener(
FormEvents::SUBMIT,
function(FormEvent $event) {
$form = $event->getForm();
$data = $event->getData();
$url = $data->getUrl();
$form->setData(parse_url($url), PHP_URL_HOST);
}
);
}
}
Run Code Online (Sandbox Code Playgroud)
我收到以下通知:
"注意:数组转换为字符串"
这是什么意思?
我的Message实体有方法__toString():
public function __toString()
{
return $this->getUrl();
}
Run Code Online (Sandbox Code Playgroud)
谢谢
您可以尝试使用专为此目的而设计的Data Transformer.例如:
namespace Vendor\MyBundle\Form\DataTransformer;
use Symfony\Component\Form\DataTransformerInterface;
class HostFromUrlTransformer implements DataTransformerInterface
{
public function transform($host)
{
return ($host === null) ? "" : $host;
}
public function reverseTransform($url)
{
return parse_url($url, PHP_URL_HOST);
}
}
Run Code Online (Sandbox Code Playgroud)
然后以表格形式实施:
use Vendor\MyBundle\Form\DataTransformer\HostFromUrlTransformer;
class MessageType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add(
$builder->create('url')
->addModelTransformer(new HostFromUrlTransformer())
);
}
}
Run Code Online (Sandbox Code Playgroud)
然而,这种方法肯定有其缺点.您将无法Assert\URL在实体上添加,因为验证在转换后发生,并且只有主机部分将不再使其有效.你可以通过将Symfony验证器传递给你的数据转换器来解决这个问题,然后验证$ url,Assert\Url类似于这里的方法:结合约束和数据转换器,但这也感觉有点hacky.
比所有这一切更简单的解决方案就是将setUrl($url)实体中的方法更新为以下内容:
public function setUrl($url)
{
$host = parse_url($url, PHP_URL_HOST);
$this->url = $host ?: $url;
}
Run Code Online (Sandbox Code Playgroud)
因此,在这种情况下,如果您传入一个URL,它只保存为$ host,如果您使用setUrl()并且它已经被转换,它将保留已存在的值.
更妙的是,您可以简单地保存他们发送给您的完整URL,这样您就可以维护@Assert\URL验证,然后添加以下两个函数:
public function getHost()
{
return parse_url($this->url, PHP_URL_HOST);
}
public function __toString()
{
return $this->getHost();
}
Run Code Online (Sandbox Code Playgroud)
上面允许您保留所有已保存的数据,并更改解析URL的工作由您的应用程序完成,而不是尝试在数据库层中解析.该__toString()方法将始终返回主机,并且您仍然可以访问在需要时传入的完整URL.你甚至可以摆脱getHost()上面的功能.
如果你想使用FormEvent,你就是在正确的轨道上,但代码有点偏.有关详细信息,请参阅http://symfony.com/doc/current/components/form/form_events.html#b-the-formevents-submit-event.
$builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event)
{
$data = $event->getData();
$data['url'] = parse_url($data['url'], PHP_URL_HOST);
$event->setData($data);
// this one-liner might also work in place of the 3 lines above
$event->setData('url', parse_url($event->getData('url'), PHP_URL_HOST));
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7257 次 |
| 最近记录: |