gpt4 book ai didi

php - Symfony2 中 $em->clear() 的未定义索引错误

转载 作者:IT王子 更新时间:2023-10-29 00:03:53 26 4
gpt4 key购买 nike

我编写了一个 Symfony 命令来从 API 导入一些数据。它可以工作,但问题是当我在我的数据库中插入一个大 JSON 时,我的 PHP 内存使用量会增加。每次导入事件后,我的 unitOfWork 都会增加“2”。

我已经取消了我所有使用过的对象,当你想要做大批量时,我已经阅读了 Symfony2 的文档:http://www.doctrine-project.org/blog/doctrine2-batch-processing.html

但是当我使用 $em->clear() 我的实体管理器给出了这个错误:

Notice: Undefined index: 000000007b56ea7100000000e366c259 in path-to-application\vendor\doctrine\lib\Doctrine\ORM\UnitOfWork.php line 2228

这是我的完整代码:

 /**
* @see Command
*/
protected function configure() {
$this
->setName('ks:user:runkeepersync')
->setDescription('Synchroniser les activités d\'un utilisateur runkeeper')
->setDefinition(array(
new InputArgument('access_token', InputArgument::REQUIRED, 'Access token'),
))
}

/**
* @see Command
*/
protected function execute(InputInterface $input, OutputInterface $output) {
$accessToken = $input->getArgument('access_token');
$em = $this->getContainer()->get('doctrine')->getEntityManager();
$UserHasServices = $em->getRepository('KsUserBundle:UserHasServices')->findOneByToken($accessToken);
if (!is_object($UserHasServices) ) {
echo "Impossible de trouver l'utilisateur qui possède le jeton ".$accessToken."";
}
$user = $UserHasServices->getUser();
$service = $UserHasServices->getService();
echo "avant de requérir l'api : ".memory_get_usage()."\n";
try {
$rkApi = $this->getContainer()->get('ks_user.runkeeper');
$rkApi->setAccessToken($accessToken);
$activities = $rkApi->getFitnessActivities(0,25);
$nbParPages = 25;
$nomberActivitites = $activities->size;
$aActivities = $activities->items;
$nbPages = floor ($nomberActivitites/$nbParPages);
$aEndurance = array("Running", "Cycling", "Mountain Biking", "Walking", "Hiking", "Downhill Skiing", "Cross-Country Skiing", "Snowboarding", "Skating","Wheelchair", "Rowing", "Elliptical", "Other");
$aEnduranceUnderWater = array("Swimming");
$enduranceOnEarthType = $em->getRepository('KsActivityBundle:SportType')->findOneByLabel("endurance");
if (!is_object($enduranceOnEarthType) ) {
echo "Impossible de trouver le type de sport d'endurance";
}
$enduranceUnderWaterType = $em->getRepository('KsActivityBundle:SportType')->findOneByLabel("endurance_under_water");
if (!is_object($enduranceUnderWaterType) ) {
echo "Impossible de trouver le type de sport d'endurance sous l'eau ";
}
echo "Après avoir récupéré 25 activités : ".memory_get_usage()."\n";
$a = 0;
for($i=0;$i<=$nbPages;$i++){
if($i!=0){
$activities = $rkApi->getFitnessActivities($i,25);
$aActivities = $activities->items;
}
foreach ($aActivities as $activity) {
$a = $a+1;
$codeSport = $this->formatNameSport($activity->type);
$sport = $em->getRepository('KsActivityBundle:Sport')->findOneByCodeSport($codeSport);
if (!is_object($sport) ) {
$sport = new \Ks\ActivityBundle\Entity\Sport();
$sport->setLabel($codeSport);
$sport->setCodeSport($codeSport);
$sport->setSportType($enduranceOnEarthType);
$em->persist($sport);
$em->flush();
}
$activityDetail = json_decode($rkApi->requestJSONHealthGraph($activity->uri));
if(in_array($activity->type, $aEndurance)){
$urlActivitieDetail = $activityDetail->activity;
$ActivitySessionEnduranceOnEarth = new \Ks\ActivityBundle\Entity\ActivitySessionEnduranceOnEarth($user);
isset($activity->total_distance)? $ActivitySessionEnduranceOnEarth->setDistance($activity->total_distance) : "";
isset($activity->duration)? $ActivitySessionEnduranceOnEarth->setDuration($this->secondesToTimeDuration($activity->duration)) : "";
isset($activity->start_time)? $ActivitySessionEnduranceOnEarth->setIssuedAt(new \DateTime($activity->start_time)) : "";
$ActivitySessionEnduranceOnEarth->setModifiedAt(new \DateTime('Now'));
$ActivitySessionEnduranceOnEarth->setSport($sport);
isset($activityDetail->total_calories)? $ActivitySessionEnduranceOnEarth->setCalories($activityDetail->total_calories) : "";
isset($activityDetail->climb)? $ActivitySessionEnduranceOnEarth->setElevationGain($activityDetail->climb) : "";
$maxElevation = 0;
$minElevation = 10000;
if(isset($activityDetail->path)){
foreach($activityDetail->path as $gpsPoint){
if($gpsPoint->altitude > $maxElevation){
$maxElevation = $gpsPoint->altitude;
}
if($gpsPoint->altitude < $minElevation){
$minElevation = $gpsPoint->altitude;
}
}
$ActivitySessionEnduranceOnEarth->setElevationMin($minElevation);
$ActivitySessionEnduranceOnEarth->setElevationMax($maxElevation);
}
$em->persist($ActivitySessionEnduranceOnEarth);
$em->flush();
//Pour chaque activité on a un identifiant relatif au service qu'on synchronise
$ActivityComeFromService = new \Ks\ActivityBundle\Entity\ActivityComeFromService();
$ActivityComeFromService->setActivity($ActivitySessionEnduranceOnEarth);
$ActivityComeFromService->setService($service);
$ActivityComeFromService->setIdWebsiteActivityService($activity->uri);
$ActivityComeFromService->setSourceDetailsActivity($rkApi->requestJSONHealthGraph($activity->uri));
$ActivityComeFromService->setTypeSource("JSON");
$em->persist($ActivityComeFromService);
$em->flush();
echo "Import de l'activite num ".$a." type :".$activity->type." effectue avec success \n";
unset($ActivitySessionEnduranceOnEarth);
unset($ActivityComeFromService);
echo "UnitOFWOrk -> ".$em->getUnitOfWork()->size()."\n";
}
if(in_array($activity->type, $aEnduranceUnderWater)){
$ActivitySessionEnduranceUnderWater = new \Ks\ActivityBundle\Entity\ActivitySessionEnduranceUnderWater($user);
isset($activity->total_distance)? $ActivitySessionEnduranceUnderWater->setDistance($activity->total_distance) : "";
isset($activity->duration)? $ActivitySessionEnduranceUnderWater->setDuration($this->secondesToTimeDuration($activity->duration)) : "";
isset($activity->start_time) && !empty($activity->start_time)? $ActivitySessionEnduranceUnderWater->setIssuedAt(new \DateTime($activity->start_time)) : "";
$ActivitySessionEnduranceUnderWater->setModifiedAt(new \DateTime('Now'));
$ActivitySessionEnduranceUnderWater->setSport($sport);
isset($activityDetail->total_calories)? $ActivitySessionEnduranceUnderWater->setCalories($activityDetail->total_calories) : "";
isset($activityDetail->notes)? $ActivitySessionEnduranceUnderWater->setDescription($activityDetail->notes) : "";
$em->persist($ActivitySessionEnduranceUnderWater);
$em->flush();
$ActivityComeFromService = new \Ks\ActivityBundle\Entity\ActivityComeFromService();
$ActivityComeFromService->setActivity($ActivitySessionEnduranceUnderWater);
$ActivityComeFromService->setService($service);
$ActivityComeFromService->setIdWebsiteActivityService($activity->uri);
$ActivityComeFromService->setSourceDetailsActivity($rkApi->requestJSONHealthGraph($activity->uri));
$ActivityComeFromService->setTypeSource("JSON");
$em->persist($ActivityComeFromService);
$em->flush();
echo "Import de l'activité num ".$a." type :".$activity->type." effectué avec succès\n";
unset($ActivitySessionEnduranceUnderWater);
unset($ActivityComeFromService);
}
echo "Après chaque activité : ".memory_get_usage()."\n";
unset($sport);
unset($activityDetail);
$em->clear();
}
}
} catch (\Exception $e) {
throw $e;
}
}

谢谢,@AdrienBrault。我用--env=prod --no-debug测试过,确实是消耗的内存少了,但是内存还是增加了。我怎样才能真正清除实体管理器?并稳定内存?

最佳答案

Symfony 在开发环境中记录所有的 SQL 查询,所以首先你需要禁用它

// disable logger
$em->getConnection()->getConfiguration()->setSQLLogger(null);

您可以在实体上使用事件监听器,这也可能会增加内存使用量。您可以像这样禁用它们

// remove all listeners
foreach ($em->getEventManager()->getListeners() as $event => $listeners) {
foreach ($listeners as $listener) {
$em->getEventManager()->removeEventListener($event, $listener);
}
}

从您的代码中删除 unset,不需要它们,因为您在循环的每一步都清除了实体管理器。

// save and clear
$em->flush();
$em->getUnitOfWork()->clear();

请记住,如果您将查询分组到一个 flush 中,原则可以优化您的查询并提高性能。因此,最佳做法是对数据的某些部分执行一次 flush。例如:

// collect 100 entities and then save them
if (($i % 100) == 0) {
$em->flush();
$em->getUnitOfWork()->clear();
}

关于php - Symfony2 中 $em->clear() 的未定义索引错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11392931/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com