Symfony3 Doctrine2 不能访问循环中的变量



环境

我正在使用:

  • Symfony v3.1.0;
  • 教义 v2.5.4

问题

我正在从XML文件导入数据。导入工作正常,但我在更新时遇到问题。

我只是无法在循环中获得适当的day_id

$newest_day_id = $this->getNewestDayId();
...
->setParameter(7, $newest_day_id)
给出的 ID 比

实际 ID 小 1

如果我尝试:

$newest_day_id = $this->getNewestDayId();
...
->setParameter(7, $newest_day_id + 1)

它给出一个错误

An exception occurred while executing 'UPDATE item SET name_lv = ?, name_ru = ?, description_lv = ?, description_ru = ?, price = ?, in_stock = ?, day_id = ? WHERE unique_id = ?' with params ["EDIT My Product Name LV", "EDIT My Product Name RU", "EDIT", "EDIT", "999.00", "99", 34, "0361-my-product-unique-id"]:
SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`tevlvnews`.`item`, CONSTRAINT `FK_1F1B251E9C24126` FOREIGN KEY (`day_id`) REFERENCES `day` (`id`) ON DELETE CASCADE)

如果我尝试:

....
->setParameter(7, $day->getId)

我在数据库的day_id字段中得到NULL

法典

这是我的控制器:

<?php
namespace AppBundleController;
use DateTime;
use AppBundleEntityDay;
use AppBundleEntityItem;
use SensioBundleFrameworkExtraBundleConfigurationRoute;
use SymfonyBundleFrameworkBundleControllerController;
use SymfonyComponentHttpFoundationRequest;
use SymfonyComponentFilesystemFilesystem;
use SymfonyComponentFilesystemExceptionIOExceptionInterface;
use SymfonyComponentDomCrawlerCrawler;
class AdminController extends Controller
{
    /**
     * @Route("/import", name="admin_import")
     */
    public function importAction(Request $request)
    {
        $document = new DOMDocument();
        $tev_file_path = 'http://dev.izjoko.lv/test.xml';
        $document->loadXml(file_get_contents($tev_file_path));
        $now_date_time = date('Y-m-d H:i:s');
        $nodeList = $document->getElementsByTagName('item');
        $crawler = new Crawler();
        $crawler->addDocument($document);
        $crawler->addNodeList($nodeList);
        $xml_item_counts = $nodeList->length;
        // find newest DAY record
        $em = $this->getDoctrine()->getManager();
        $query = $em->createQueryBuilder()
            ->select('d')
            ->from('AppBundle:Day', 'd')
            ->orderBy('d.updated_at', 'DESC')
            ->getQuery();
        $db_date_time = $query->getResult();
        $db_date_time_size = sizeof($db_date_time);
        // setup www folder for image path
        $current_env = $this->container->get('kernel')->getEnvironment();
        if ($current_env == 'dev') 
        {
            $www_dir = 'web';
        }
        elseif ($current_env == 'prod')
        {
            $www_dir = 'www';
        }
        $fs = new Filesystem();
        $local_image_uploads_path = $this->container->getParameter('kernel.root_dir') . '/../' . $www_dir . '/uploads/';
        $local_image_uploads_path = str_replace("app/../", "", $local_image_uploads_path);
        // make folder uploads inside web
        if (!$fs->exists($local_image_uploads_path)) 
        {
            try 
            {
                $fs->mkdir($local_image_uploads_path);
            }
            catch (IOExceptionInterface $e) 
            {
                echo "An error occurred while creating your directory at " . $e->getPath();
            }
        }
        // if database is empty
        if ($db_date_time_size == 0)
        {
            $day = new Day();
            $day->setUpdatedAt(new DateTime($now_date_time));
            for ($i = 0; $i < $xml_item_count; $i++)
            {
                $unique_id = $document->getElementsByTagName('unique_id')->item($i)->textContent;
                $name_lv = $document->getElementsByTagName('name_lv')->item($i)->textContent;
                $name_ru = $document->getElementsByTagName('name_ru')->item($i)->textContent;
                $link_lv = $document->getElementsByTagName('link_lv')->item($i)->textContent;
                $link_ru = $document->getElementsByTagName('link_ru')->item($i)->textContent;
                $category = $document->getElementsByTagName('category')->item($i)->textContent;
                $category_full = $document->getElementsByTagName('category_full')->item($i)->textContent;
                $external_image_small = $document->getElementsByTagName('image_th')->item($i)->textContent;
                $external_image_big = $document->getElementsByTagName('image')->item($i)->textContent;
                $description_lv = $document->getElementsByTagName('description_lv')->item($i)->textContent;
                $description_ru = $document->getElementsByTagName('description_ru')->item($i)->textContent;
                $price = $document->getElementsByTagName('price')->item($i)->textContent;
                $in_stock = $document->getElementsByTagName('in_stock')->item($i)->textContent;
                // add new record to database
                $item = new Item();
                $item->setUniqueId($unique_id);
                $item->setNameLv($name_lv);
                $item->setNameRu($name_ru);
                $item->setLinkLv($link_lv);
                $item->setLinkRu($link_ru);
                $item->setCategory($category);
                $item->setCategoryFull($category_full);
                /* -----------------------------------------------------
                 * small picture
                ----------------------------------------------------- */
                $image_small = file_get_contents($external_image_small);
                $hex_random_bytes = bin2hex(random_bytes(8));
                $file_name_small = 'img_' . $hex_random_bytes . '_th.jpg';
                $local_image_small_full_path = $this->container->getParameter('kernel.root_dir') . '/../' . $www_dir . '/uploads/' . $file_name_small;
                $local_image_small_full_path = str_replace("app/../", "", $local_image_small_full_path);
                try 
                {
                    $fs->dumpFile($local_image_small_full_path, $image_small);
                }
                catch (IOExceptionInterface $e) 
                {
                    echo "An error occurred while saving your image at " . $e->getPath();
                }
                $local_image_small_path = 'uploads/' . $file_name_small;
                $item->setLocalImageSmallUrl($local_image_small_path);
                /* -----------------------------------------------------
                 * big picture
                ----------------------------------------------------- */
                $image_big = file_get_contents($external_image_big);
                $file_name_big = 'img_' . $hex_random_bytes . '.jpg';
                $local_image_big_full_path = $this->container->getParameter('kernel.root_dir') . '/../' . $www_dir . '/uploads/' . $file_name_big;
                $local_image_big_full_path = str_replace("app/../", "", $local_image_big_full_path);
                try 
                {
                    $fs->dumpFile($local_image_big_full_path, $image_big);
                }
                catch (IOExceptionInterface $e) 
                {
                    echo "An error occurred while saving your image at " . $e->getPath();
                }
                $local_image_big_path = 'uploads/' . $file_name_big;
                $item->setLocalImageBigUrl($local_image_big_path);
                $item->setDescriptionLv($description_lv);
                $item->setDescriptionRu($description_ru);
                $item->setPrice($price);
                $item->setInStock($in_stock);
                $em->persist($item);
                $item->setDay($day);
            }
            $em->persist($day);
            $em->flush();
        }
        return $this->render('admin/import_tev.html.twig', array('tev_file_path' => $tev_file_path, 'xml_date_time' => $now_date_time, 'xml_item_count' => $xml_item_count));
    }
    /**
     * @Route("/update", name="admin_update")
     */
    public function updateAction(Request $request)
    {
        $document = new DOMDocument();
        $tev_file_path = 'http://dev.izjoko.lv/test.xml';
        $document->loadXml(file_get_contents($tev_file_path));
        $now_date_time = date('Y-m-d H:i:s');
        $nodeList = $document->getElementsByTagName('item');
        $crawler = new Crawler();
        $crawler->addDocument($document);
        $crawler->addNodeList($nodeList);
        $xml_item_count = $nodeList->length;
        // find newest DAY record
        $em = $this->getDoctrine()->getManager();
        $query = $em->createQueryBuilder()
            ->select('d')
            ->from('AppBundle:Day', 'd')
            ->orderBy('d.updated_at', 'DESC')
            ->getQuery();
        $db_date_time = $query->getResult();
        $db_date_time_size = sizeof($db_date_time);
        // setup www folder for image path
        $current_env = $this->container->get('kernel')->getEnvironment();
        if ($current_env == 'dev')
        {
            $www_dir = 'web';
        } 
        elseif ($current_env == 'prod')
        {
            $www_dir = 'www';
        }
        $fs = new Filesystem();
        $local_image_uploads_path = $this->container->getParameter('kernel.root_dir') . '/../' . $www_dir . '/uploads/';
        $local_image_uploads_path = str_replace("app/../", "", $local_image_uploads_path);
        // make folder uploads inside web
        if (!$fs->exists($local_image_uploads_path))
        {
            try
            {
                $fs->mkdir($local_image_uploads_path);
            }
            catch (IOExceptionInterface $e)
            {
                echo "An error occurred while creating your directory at " . $e->getPath();
            }
        }
        $day = new Day();
        $day->setUpdatedAt(new DateTime($now_date_time));
        for ($i = 0; $i < $xml_item_count; $i++)
        {
            $unique_id = $document->getElementsByTagName('unique_id')->item($i)->textContent;
            $name_lv = $document->getElementsByTagName('name_lv')->item($i)->textContent;
            $name_ru = $document->getElementsByTagName('name_ru')->item($i)->textContent;
            $link_lv = $document->getElementsByTagName('link_lv')->item($i)->textContent;
            $link_ru = $document->getElementsByTagName('link_ru')->item($i)->textContent;
            $category = $document->getElementsByTagName('category')->item($i)->textContent;
            $category_full = $document->getElementsByTagName('category_full')->item($i)->textContent;
            $external_image_small = $document->getElementsByTagName('image_th')->item($i)->textContent;
            $external_image_big = $document->getElementsByTagName('image')->item($i)->textContent;
            $description_lv = $document->getElementsByTagName('description_lv')->item($i)->textContent;
            $description_ru = $document->getElementsByTagName('description_ru')->item($i)->textContent;
            $price = $document->getElementsByTagName('price')->item($i)->textContent;
            $in_stock = $document->getElementsByTagName('in_stock')->item($i)->textContent;
            if ($this->checkIfUniqueIdRecordExistsAction($unique_id) == true)
            {
                // update existing record
                $newest_day_id = $this->getNewestDayId();
                $em = $this->getDoctrine()->getManager();
                $qb = $em->createQueryBuilder();
                $q = $qb->update('AppBundle:Item', 'i')
                    ->set('i.name_lv', '?1')
                    ->set('i.name_ru', '?2')
                    ->set('i.description_lv', '?3')
                    ->set('i.description_ru', '?4')
                    ->set('i.price', '?5')
                    ->set('i.in_stock', '?6')
                    ->set('i.day', '?7')
                    ->where('i.unique_id = :unique_id')
                    ->setParameter('unique_id', $unique_id)
                    ->setParameter(1, $name_lv)
                    ->setParameter(2, $name_ru)
                    ->setParameter(3, $description_lv)
                    ->setParameter(4, $description_ru)
                    ->setParameter(5, $price)
                    ->setParameter(6, $in_stock)
                    ->setParameter(7, $newest_day_id)
                    ->getQuery();
                $q->execute();
            }
            elseif ($this->checkIfUniqueIdRecordExistsAction($unique_id) == false)
            {
                //TODO: add new data
                $item = new Item();
                $item->setUniqueId($unique_id);
                $item->setNameLv($name_lv);
                $item->setNameRu($name_ru);
                $item->setLinkLv($link_lv);
                $item->setLinkRu($link_ru);
                $item->setCategory($category);
                $item->setCategoryFull($category_full);
                /* -----------------------------------------------------
                 * small image
                ----------------------------------------------------- */
                $image_small = file_get_contents($external_image_small);
                $hex_random_bytes = bin2hex(random_bytes(8));
                $file_name_small = 'img_' . $hex_random_bytes . '_th.jpg';
                $local_image_small_full_path = $this->container->getParameter('kernel.root_dir') . '/../' . $www_dir . '/uploads/' . $file_name_small;
                $local_image_small_full_path = str_replace("app/../", "", $local_image_small_full_path);
                try
                {
                    $fs->dumpFile($local_image_small_full_path, $image_small);
                }
                catch (IOExceptionInterface $e)
                {
                    echo "An error occurred while saving your image at " . $e->getPath();
                }
                $local_image_small_path = 'uploads/' . $file_name_small;
                $item->setLocalImageSmallUrl($local_image_small_path);
                /* -----------------------------------------------------
                 * big image
                ----------------------------------------------------- */
                $image_big = file_get_contents($external_image_big);
                $file_name_big = 'img_' . $hex_random_bytes . '.jpg';
                $local_image_big_full_path = $this->container->getParameter('kernel.root_dir') . '/../' . $www_dir . '/uploads/' . $file_name_big;
                $local_image_big_full_path = str_replace("app/../", "", $local_image_big_full_path);
                try
                {
                    $fs->dumpFile($local_image_big_full_path, $image_big);
                }
                catch (IOExceptionInterface $e)
                {
                    echo "An error occurred while saving your image at " . $e->getPath();
                }
                $local_image_big_path = 'uploads/' . $file_name_big;
                $item->setLocalImageBigUrl($local_image_big_path);
                $item->setDescriptionLv($description_lv);
                $item->setDescriptionRu($description_ru);
                $item->setPrice($price);
                $item->setInStock($in_stock);
                $em->persist($item);
                $item->setDay($day);
            }
        }
        $em->persist($day);
        $em->flush();
        return $this->render('admin/import_tev.html.twig', array('tev_file_path' => $tev_file_path, 'xml_date_time' => $now_date_time, 'xml_item_count' => $xml_item_count));
    }
    private function checkIfUniqueIdRecordExistsAction($unique_id)
    {
        // check if record with identic unique_id is already in database
        $em = $this->getDoctrine()->getManager();
        $query = $em->createQueryBuilder()
            ->select('i')
            ->from('AppBundle:Item', 'i')
            ->where('i.unique_id = :unique_id')
            ->setParameter('unique_id', $unique_id)
            ->setMaxResults(1)
            ->getQuery();
        $db_unique_id = $query->getResult();
        $db_unique_id_size = sizeof($db_unique_id);
        if ($db_unique_id_size == 0) {
            // not in database
            return false;
        } elseif ($db_unique_id_size > 0) {
            // exists in database
            return true;
        }
    }
    private function getNewestDayId()
    {
        // fnd newest DAY record id
        $em = $this->getDoctrine()->getManager();
        $query = $em->createQueryBuilder()
            ->select('d')
            ->from('AppBundle:Day', 'd')
            ->orderBy('d.updated_at', 'DESC')
            ->setMaxResults(1)
            ->getQuery();
        $db_date_time = $query->getResult();
        $db_date_time_id = $db_date_time[0]->getId();
        return $db_date_time_id;
    }
}

我的项目实体:

namespace AppBundleEntity;
use DoctrineORMMapping as ORM;
use SymfonyComponentValidatorConstraints as Assert;
/**
 * @ORMEntity
 * @ORMTable(name="item")
 */
class Item
{
    /**
     * @ORMColumn(type="integer")
     * @ORMId
     * @ORMGeneratedValue(strategy="AUTO")
     */
    protected $id;
    /**
     * @ORMColumn(type="string", length=100)
     */
    protected $name_lv;
    /**
     * @ORMColumn(type="string", length=100)
     */
    protected $name_ru;
    /**
     * @ORMColumn(type="string", length=200)
     */
    protected $category;
    /**
     * @ORMColumn(type="string", length=500)
     */
    protected $category_full;
    /**
     * @ORMColumn(type="string", length=500)
     */
    protected $link_lv;
    /**
     * @ORMColumn(type="string", length=500)
     */
    protected $link_ru;
    /**
     * @ORMColumn(type="string", length=500)
     */
    protected $local_image_small_url;
    /**
     * @ORMColumn(type="string", length=500)
     */
    protected $local_image_big_url;
    /**
     * @ORMColumn(type="string", length=3000)
     */
    protected $description_lv;
    /**
     * @ORMColumn(type="string", length=3000)
     */
    protected $description_ru;
    /**
     * @ORMColumn(type="decimal", scale=2)
     */
    protected $price;
    /**
     * @ORMColumn(type="integer")
     */
    protected $in_stock;
    /**
     * @ORMManyToOne(targetEntity="Day", inversedBy="items")
     * @ORMJoinColumn(name="day_id", referencedColumnName="id", onDelete="CASCADE")
     */
    protected $day;
    /**
     * Get id
     *
     * @return integer
     */
    public function getId()
    {
        return $this->id;
    }
    /**
     * Set nameLv
     *
     * @param string $nameLv
     *
     * @return Item
     */
    public function setNameLv($nameLv)
    {
        $this->name_lv = $nameLv;
        return $this;
    }
    /**
     * Get nameLv
     *
     * @return string
     */
    public function getNameLv()
    {
        return $this->name_lv;
    }
    /**
     * Set nameRu
     *
     * @param string $nameRu
     *
     * @return Item
     */
    public function setNameRu($nameRu)
    {
        $this->name_ru = $nameRu;
        return $this;
    }
    /**
     * Get nameRu
     *
     * @return string
     */
    public function getNameRu()
    {
        return $this->name_ru;
    }
    /**
     * Set category
     *
     * @param string $category
     *
     * @return Item
     */
    public function setCategory($category)
    {
        $this->category = $category;
        return $this;
    }
    /**
     * Get category
     *
     * @return string
     */
    public function getCategory()
    {
        return $this->category;
    }
    /**
     * Set categoryFull
     *
     * @param string $categoryFull
     *
     * @return Item
     */
    public function setCategoryFull($categoryFull)
    {
        $this->category_full = $categoryFull;
        return $this;
    }
    /**
     * Get categoryFull
     *
     * @return string
     */
    public function getCategoryFull()
    {
        return $this->category_full;
    }
    /**
     * Set linkLv
     *
     * @param string $linkLv
     *
     * @return Item
     */
    public function setLinkLv($linkLv)
    {
        $this->link_lv = $linkLv;
        return $this;
    }
    /**
     * Get linkLv
     *
     * @return string
     */
    public function getLinkLv()
    {
        return $this->link_lv;
    }
    /**
     * Set linkRu
     *
     * @param string $linkRu
     *
     * @return Item
     */
    public function setLinkRu($linkRu)
    {
        $this->link_ru = $linkRu;
        return $this;
    }
    /**
     * Get linkRu
     *
     * @return string
     */
    public function getLinkRu()
    {
        return $this->link_ru;
    }
    /**
     * Set localImageSmallUrl
     *
     * @param string $localImageSmallUrl
     *
     * @return Item
     */
    public function setLocalImageSmallUrl($localImageSmallUrl)
    {
        $this->local_image_small_url = $localImageSmallUrl;
        return $this;
    }
    /**
     * Get localImageSmallUrl
     *
     * @return string
     */
    public function getLocalImageSmallUrl()
    {
        return $this->local_image_small_url;
    }
    /**
     * Set localImageBigUrl
     *
     * @param string $localImageBigUrl
     *
     * @return Item
     */
    public function setLocalImageBigUrl($localImageBigUrl)
    {
        $this->local_image_big_url = $localImageBigUrl;
        return $this;
    }
    /**
     * Get localImageBigUrl
     *
     * @return string
     */
    public function getLocalImageBigUrl()
    {
        return $this->local_image_big_url;
    }
    /**
     * Set descriptionLv
     *
     * @param string $descriptionLv
     *
     * @return Item
     */
    public function setDescriptionLv($descriptionLv)
    {
        $this->description_lv = $descriptionLv;
        return $this;
    }
    /**
     * Get descriptionLv
     *
     * @return string
     */
    public function getDescriptionLv()
    {
        return $this->description_lv;
    }
    /**
     * Set descriptionRu
     *
     * @param string $descriptionRu
     *
     * @return Item
     */
    public function setDescriptionRu($descriptionRu)
    {
        $this->description_ru = $descriptionRu;
        return $this;
    }
    /**
     * Get descriptionRu
     *
     * @return string
     */
    public function getDescriptionRu()
    {
        return $this->description_ru;
    }
    /**
     * Set price
     *
     * @param string $price
     *
     * @return Item
     */
    public function setPrice($price)
    {
        $this->price = $price;
        return $this;
    }
    /**
     * Get price
     *
     * @return string
     */
    public function getPrice()
    {
        return $this->price;
    }
    /**
     * Set inStock
     *
     * @param integer $inStock
     *
     * @return Item
     */
    public function setInStock($inStock)
    {
        $this->in_stock = $inStock;
        return $this;
    }
    /**
     * Get inStock
     *
     * @return integer
     */
    public function getInStock()
    {
        return $this->in_stock;
    }
    /**
     * Set day
     *
     * @param AppBundleEntityDay $day
     *
     * @return Item
     */
    public function setDay(AppBundleEntityDay $day = null)
    {
        $this->day = $day;
        return $this;
    }
    /**
     * Get day
     *
     * @return AppBundleEntityDay
     */
    public function getDay()
    {
        return $this->day;
    }
}

我的 DAY 实体:

namespace AppBundleEntity;
use DoctrineORMMapping as ORM;
use DoctrineCommonCollectionsArrayCollection;
use SymfonyComponentValidatorConstraints as Assert;
/**
 * @ORMEntity
 * @ORMTable(name="day")
 */
class Day
{
    /**
     * @ORMColumn(type="integer")
     * @ORMId
     * @ORMGeneratedValue(strategy="AUTO")
     */
    protected $id;
    /**
     * @ORMColumn(type="datetime", name="updated_at")
     */
    protected $updated_at;
    /**
     * @ORMOneToMany(targetEntity="Item", mappedBy="day")
     */
    protected $items;
    public function __construct()
    {
        $this->items = new ArrayCollection();
    }
    /**
     * Get id
     *
     * @return integer
     */
    public function getId()
    {
        return $this->id;
    }
    /**
     * Set updatedAt
     *
     * @param DateTime $updatedAt
     *
     * @return Day
     */
    public function setUpdatedAt($updatedAt)
    {
        $this->updated_at = $updatedAt;
        return $this;
    }
    /**
     * Get updatedAt
     *
     * @return DateTime
     */
    public function getUpdatedAt()
    {
        return $this->updated_at;
    }
    /**
     * Add item
     *
     * @param AppBundleEntityitem $item
     *
     * @return Day
     */
    public function addItem(item $item)
    {
        $this->items[] = $item;
        return $this;
    }
    /**
     * Remove item
     *
     * @param AppBundleEntityitem $item
     */
    public function removeItem(item $item)
    {
        $this->items->removeElement($item);
    }
    /**
     * Get items
     *
     * @return DoctrineCommonCollectionsCollection
     */
    public function getItems()
    {
        return $this->items;
    }
}

感谢您的时间和知识。

我没有足够的声誉来评论一些事情来问一些事情,但我将根据我所看到的来尝试答案......

  1. 我建议您使用存储库来完成ImportAction和UpdateAction中的大部分重复工作。如果可能,您希望使控制器操作更薄。
  2. 我还建议您使用实体管理器,即使是更新。您正在执行查询,而不是让 Doctrine 管理它。这可能会解决它。检索项目并使用 $item->set*() 方法对其进行更新。

我希望这有助于解决您的问题。我建议您尝试尽可能多地使用实体管理器。我注意到您正在运行一些查询,并且您可能可以通过 EntityManager 获得所需的内容。

我设法让它工作。

  • 重要提示:我先保存了我的 DAY 实体
  • 然后我从数据库中检索了最新的DAY
  • 然后像以前一样继续
  • 此时,$newest_day_id = $this->getNewestDayId();返回数据库中的实际最新记录。
  • 所以我的代码工作了...

相关内容

  • 没有找到相关文章

最新更新