dongruolin5324 2017-03-28 13:10
浏览 100

Symfony搜索框问题

I've an issue to make a search-box with Symfony and Doctrine. I use the 2.8 version of Symfony.

My issue is :

EntityManager#persist() expects parameter 1 to be an entity object, array given. 500 Internal Server Error - ORMInvalidArgumentException

So, this is my Type for my search-box type :

/**
 * {@inheritdoc}
 */
public function buildForm(FormBuilderInterface $builder, array $options)  {

    $builder->add('searchBox',SearchType::class,array('label'=>'Vous cherchez : Un auteur ? Un éditeur ? Un ouvrage ?','attr'=>array('class'=>'form-control')));

}

/**
 * {@inheritdoc}
 */
public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setDefaults(array(
        'data_class1' => 'SB\MainBundle\Entity\Ouvrages',
        'data_class2' => 'SB\MainBundle\Entity\Auteurs',
        'data_class3' => 'SB\MainBundle\Entity\Editeurs'
    ));
}

And this is my controller code after edit :

public function indexAction(Request $request) {
    $ouvragesVentes = $this->getDoctrine()->getRepository('SBMainBundle:Ouvrages')->getOuvragesVentes();
    $ouvragesEchanges = $this->getDoctrine()->getRepository('SBMainBundle:Ouvrages')->getOuvragesEchanges();
    $categories = $this->getDoctrine()->getRepository('SBMainBundle:Categories')->getAllCats();

    $form = $this->createForm(SearchBoxType::class);
    $form->handleRequest($request);

    if ($form->isSubmitted() && $form->isValid()) {

        $searchBoxValue = $form->getData();

        $bookName = $this->getDoctrine()->getRepository('SBMainBundle:Ouvrages')->getOuvrageName($searchBoxValue);
        $editorName = $this->getDoctrine()->getRepository('SBMainBundle:Editeurs')->getEditeurName($searchBoxValue);
        $autorName = $this->getDoctrine()->getRepository('SBMainBundle:Auteurs')->getAuteurName($searchBoxValue);

        //if author
        if ($searchBoxValue == $autorName){
            return $this->redirect($this->generateUrl('sb_main_auteur'));
        }
        //if editor
        if ($searchBoxValue == $editorName){
            return $this->redirect($this->generateUrl('sb_main_editeur'));
        }
        //if book name
        if ($searchBoxValue == $bookName){
            return $this->redirect($this->generateUrl('sb_main_ouvrage'));
        }
    }

    $datas = array('categories'=>$categories,'form'=>$form->createView(),'ouvragesEchanges'=>$ouvragesEchanges,'ouvragesVentes'=>$ouvragesVentes);
    return $this->render('SBMainBundle:Main:index.html.twig',$datas);
}

Edit : My formHandler

    protected $request;
protected $form;
protected $em;


//faire une injection de dépendance avec Request,Manager,Form(Objet)
public function __construct(Request $request,EntityManager $em, Form $form){
    $this->request = $request;
    $this->em = $em;
    $this->form = $form;
}

//vérifie si le formulaire est soumis et valide
public function process(){

    if ($this->request->getMethod() == "POST"){
        //récupération des données de la requête de la superglobale $_POST
        $this->form->handleRequest($this->request);
        //si ok, on appel onSuccess()
        if ($this->form->isValid()){
            $this->onSuccess($this->form->getData());
            return true;
        }
    }
    return false;

}

//si formulaire soumis et valide, on presiste l'objet (enregistre dans la DB)
public function onSuccess($object){
    //on persiste dans la DB via le manager Doctrine
    $this->em->persist($object);
    $this->em->flush();
}

I've look here but I think is not the solution of my issue. Then, someone can tell me what is wrong ? Do I need a search-box entity even with a search-box ?

Thanks for your help !

Edit :

Stack Trace

in src\SB\MainBundle\Repository\OuvragesRepository.php at line 130   -

public function getOuvrageName($titre){
    $query = $this->getEntityManager()->createQuery(
        "SELECT o FROM SBMainBundle:Ouvrages o WHERE o.titreOuvrage = $titre ORDER BY o.id DESC "
    );
    return $query->getResult();


at ErrorHandler ->handleError ('8', 'Array to string conversion',     'C:\wamp\www\switchbook\src\SB\MainBundle\Repository\OuvragesRepository.php', '130', array('titre' => array('searchBox' => 'flammarion'))) 
in src\SB\MainBundle\Repository\OuvragesRepository.php at line 130   +
at OuvragesRepository ->getOuvrageName (array('searchBox' => 'flammarion')) 
in src\SB\MainBundle\Controller\MainController.php at line 35   +
at MainController ->indexAction (object(Request))
at call_user_func_array (array(object(MainController), 'indexAction'),   array(object(Request))) 
in vendor\symfony\symfony\src\Symfony\Component\HttpKernel\HttpKernel.php at line 144   +
at HttpKernel ->handleRaw (object(Request), '1') 

in vendor\symfony\symfony\src\Symfony\Component\HttpKernel\HttpKernel.php at line 64 + at HttpKernel ->handle (object(Request), '1', true) in vendor\symfony\symfony\src\Symfony\Component\HttpKernel\DependencyInjection\ContainerAwareHttpKernel.php at line 69 + at ContainerAwareHttpKernel ->handle (object(Request), '1', true) in vendor\symfony\symfony\src\Symfony\Component\HttpKernel\Kernel.php at line 185 + at Kernel ->handle (object(Request)) in web\app_dev.php at line 28 +

New Edit :

Some mandatory parameters are missing ("titreOuvrage") to generate a URL for route "sb_main_ouvrage".

sb_main_ouvrage:
path:     /ouvrage/{titreOuvrage}
defaults: { _controller: SBMainBundle:Main:ouvrage}

Stack Trace

in app\cache\dev\classes.php at line 911

$variables = array_flip($variables);
$mergedParams = array_replace($defaults, $this->context->getParameters(), $parameters);
if ($diff = array_diff_key($variables, $mergedParams)) {throw new MissingMandatoryParametersException(sprintf('Some mandatory parameters are missing ("%s") to generate a URL for route "%s".', implode('", "', array_keys($diff)), $name));}
$url ='';
$optional = true;

at UrlGenerator ->doGenerate (array('titreOuvrage'), array('_controller' => 'SB\MainBundle\Controller\MainController::ouvrageAction'), array(), array(array('variable', '/', '[^/]++', 'titreOuvrage'), array('text', '/ouvrage')), array(), 'sb_main_ouvrage', '1', array(), array()) 
in app\cache\dev\appDevDebugProjectContainerUrlGenerator.php at line 92   +
at appDevDebugProjectContainerUrlGenerator ->generate ('sb_main_ouvrage', array(), '1') 
in app\cache\dev\classes.php at line 1286   +
at Router ->generate ('sb_main_ouvrage', array(), '1') 
in vendor\symfony\symfony\src\Symfony\Bundle\FrameworkBundle\Controller\Controller.php at line 52   +
at Controller ->generateUrl ('sb_main_ouvrage') 
in src\SB\MainBundle\Controller\MainController.php at line 49   +
at MainController ->indexAction (object(Request))
at call_user_func_array (array(object(MainController), 'indexAction'), array(object(Request))) 
in vendor\symfony\symfony\src\Symfony\Component\HttpKernel\HttpKernel.php at line 144   +
at HttpKernel ->handleRaw (object(Request), '1') 
in vendor\symfony\symfony\src\Symfony\Component\HttpKernel\HttpKernel.php at line 64   +
at HttpKernel ->handle (object(Request), '1', true) 
in vendor\symfony\symfony\src\Symfony\Component\HttpKernel\DependencyInjection\ContainerAwareHttpKernel.php at line 69   +
at ContainerAwareHttpKernel ->handle (object(Request), '1', true) 
in vendor\symfony\symfony\src\Symfony\Component\HttpKernel\Kernel.php at line 185   +
at Kernel ->handle (object(Request)) 
in web\app_dev.php at line 28

And my controller for the mapping page :

    public function ouvrageAction(Ouvrages $ouvrages){
    $ouvrage =  $ouvrages->getTitreOuvrage();
    $categories = $this->getDoctrine()->getRepository('SBMainBundle:Categories')->getAllCats();
    $ouvragesVentes = $this->getDoctrine()->getRepository('SBMainBundle:Ouvrages')->getOuvragesVentesByName($ouvrage);
    $ouvragesEchanges = $this->getDoctrine()->getRepository('SBMainBundle:Ouvrages')->getOuvragesEchangesByName($ouvrage);
    $datas = array('ouvragesVentes'=>$ouvragesVentes,'ouvragesEchanges'=>$ouvragesEchanges,'categories'=>$categories,'ouvrages'=>$ouvrages);
    return $this->render('SBMainBundle:Main:ouvrage.html.twig',$datas);
}
  • 写回答

1条回答 默认 最新

  • douniwan_0025 2017-03-28 16:45
    关注

    Your form has no entity (or multiple) which means your $form->getData() will return an array. And, as the error says, you cannot pass an array to the persist() method.

    If your goal is to save each search sent in your db you need to create an entity SearchBox (or whatever you want to call it), and set the data_class accordingly.

    If you don't want to store the search then, you won't need to call your handler. (because it does nothing except call a persist()) And you don't need an entity, check how to handle the submit without data_class

    Btw. in your handler you call $form->isValid() without $form->isSubmitted() and this code

    if ($formHandler->process()){
        return $this->redirect($this->generateUrl(''));
    }
    
    if ($form->isSubmitted() && $form->isValid()) {
    // You will never come here, because $formHandler->process() will return true if your form is valid, and leave your indexAction
    }
    

    Hope it may helps you.

    Edit

    The data you pass to your repository is

    $searchBoxValue = $form->getData();
    

    This will return mark searchBoxValue as an array, because you ask for all the form data.

    But what you want is to get the specific search field data, you need to do

    $searchBoxValue = $form->get('searchBox')->getData();
    

    Note that I would recommend to use a queryBuilder, or at least protect your query against sql injections.

    e.g

    public function getOuvrageName($titre){
        $query = $this->getEntityManager()->createQuery(
            "SELECT o FROM SBMainBundle:Ouvrages o WHERE o.titreOuvrage = :titre ORDER BY o.id DESC "
        )
        ->setParameter('titre', $titre);
        return $query->getResult();
    }
    
    评论

报告相同问题?

悬赏问题

  • ¥20 腾讯企业邮箱邮件可以恢复么
  • ¥15 有人知道怎么将自己的迁移策略布到edgecloudsim上使用吗?
  • ¥15 错误 LNK2001 无法解析的外部符号
  • ¥50 安装pyaudiokits失败
  • ¥15 计组这些题应该咋做呀
  • ¥60 更换迈创SOL6M4AE卡的时候,驱动要重新装才能使用,怎么解决?
  • ¥15 让node服务器有自动加载文件的功能
  • ¥15 jmeter脚本回放有的是对的有的是错的
  • ¥15 r语言蛋白组学相关问题
  • ¥15 Python时间序列如何拟合疏系数模型