5
\$\begingroup\$

I wrote a very simple quick and easy script to migrate a bunch of data to another table in my database.

Can I accomplish this task without using so many foreach loops?
I realize I'm imputting similar data in each of my loops and it just seems redundant and wrong.

I thought of using array_merge on talkers, pros & anons and I thought that because each of the second loops use the same field, I would write code to retrieve getYI and then write code to determine if it belonged to a talker, anon, or pro.
However I wasn't sure if either of those solutions would make my script any more efficient/better.

Certainly any insight would be appreciated. Thanks in advance!

And if it helps I'm using Symfony 2.3.

public function migratingDataScript()
{
 $em = $this->getDoctrine()->getManager();
 $talkers = $em->getRepository('AppBundle:Talker')->findAll();
 $anons = $em->getRepository('AppBundle:Anon')->findAll();
 $pros = $em->getRepository('AppBundle:Pro')->findAll();
 foreach ($talkers as $talker) {
 echo "Talker: ".$talker->getId()."<br>";
 foreach ($talker->getYI() as $year => $status) {
 $rounds = $em->getRepository('AppBundle:Round')->findByYear($year);
 foreach ($rounds as $round) {
 $newTalkerInvitation = new Invitation($round);
 $newTalkerInvitation->setStatus($status);
 $newTalkerInvitation->setTalker($talker);
 // $newTalkerInvitation->setNumAt(); No Data For Talker
 // $newTalkerInvitation->setStart(); No Data For Talker
 $em->persist($newTalkerInvitation);
 }
 }
 }//Ends Talker Migration
 foreach ($anons as $anon) {
 echo "Anon: ".$anon->getId()."<br>";
 foreach ($anon->getYI() as $year => $status) {
 $rounds = $em->getRepository('AppBundle:Round')->findByYear($year);
 foreach ($rounds as $round) {
 $newAnonInvitation = new Invitation($round);
 $newAnonInvitation->setStatus($status);
 $newAnonInvitation->setAnon($anon);
 // $newAnonInvitation->setNumAt(); No Data For Anon
 // $newAnonInvitation->setStart(); No Data For Anon
 $em->persist($newAnonInvitation);
 }
 }
 }//Ends Anon Migration
 foreach ($pros as $pro) {
 echo "Pro: ".$pro->getId()."<br>";
 foreach ($pro->getYI() as $year => $status) {
 $rounds = $em->getRepository('AppBundle:Round')->findByYear($year);
 foreach ($rounds as $round) {
 $newProInvitation = new Invitation($round);
 $newProInvitation->setStatus($status);
 $newProInvitation->setPro($pro);
 if(is_null($pro->getNumOfAttempts())){
 $newProInvitation->setNumAt('0');
 }else {
 $newProInvitation->setNumAt($pro->getNumOfAttempts());
 }
 // $newProInvitation->setStart(); No Data For Pro
 $em->persist($newProInvitation);
 }
 }
 }//Ends Pro Migration
 $em->flush();
 echo "Completed.";
 die;
}
yuri
4,5383 gold badges19 silver badges40 bronze badges
asked Jul 3, 2017 at 11:45
\$\endgroup\$
1

1 Answer 1

1
\$\begingroup\$

Can I accomplish this task without using so many foreach loops?

Depends.

If you want to stick with database-agnostic abstraction such as Doctrine, there is no way to avoid loops.

But if you want an efficient solution, you can write a database-specific query to copy all records in a single query. For example, for mysql it would be something like

INSERT INTO invitation (field1, field2, status, talker) 
 SELECT field1, field2, ?, ? FROM talker

and then bind $status and $talker to this query.

answered Jul 5, 2017 at 9:40
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.