2010-11-04 53 views
0

(fixe et fonctionne très bien, mais si quelqu'un veut encore factoriser, laisser une note)optimisation php nécessaire: plage de dates -> mois

Ceci est une version dépouillée d'une fonction je, qui le fait sur une plage de dates et attribue un entier unique à chaque ...

Lorsque vous travaillez avec des ensembles de données volumineux, en les exécutant plusieurs fois sur des plages de dates différentes, j'obtiens une erreur fatale, en affectant trop de mémoire au script et il meurt dans cette boucle ...

Fatal error: Allowed memory size of 268435456 bytes exhausted

fixe, était un problème avec l'itération ne prenant pas en compte le potentiel lumière du jour épargne-temps

Alors, je me demandais si quelqu'un pourrait recommander une façon plus optimale de production cette liste de mois/ints ...

Il doit me permettre de commencer Int quel que soit le nombre que j'aime et

<?php 
// updated: 2010.11.04 with Qwerty's recommendations 
// for fixing daylight savings time issue 
function monthIterate($monthInt, $startDate, $stopDate) { 
    $epoch = $startMain = strtotime($startDate); 
    $stopMain = strtotime($stopDate); 
    while ($epoch <= $stopMain) { 
     // get the start/stop dates for "this month" 
     $start = date("Y-m-01", $epoch); 
     $stop = date("Y-m-t", $epoch); 
     // uniqueID for the month 
     $monthKey = "Month#-".str_pad($monthInt, 3, "0", STR_PAD_LEFT); 
     $months[$monthKey] = compact('start', 'stop'); 
     // move forward in loop, +1 day should get us to the next month 
     $epoch = strtotime($stop); 
     $currentMonth = $nextMonth = date('m', $epoch); 
     while ($currentMonth == $nextMonth) { 
      $epoch = $epoch + 86400; 
      $nextMonth = date('m', $epoch); 
     } 
     $monthInt++; 
    } 
    return $months; 
} 
?> 
+0

Bien que vous pourriez être mieux servis en utilisant la nouvelle 'DateInterval' classe et autres, cela semble fonctionner, et je doute sérieusement que c'est le porc de mémoire, le problème est probablement dans une autre partie du code (run avec 'xdebug' et activer delta de la mémoire pour une belle vue d'ensemble) – Wrikken

+0

http://stackoverflow.com/questions/2155110/php-loop-thru-all-months-in-date-range essayez celui-là –

Répondre

2

On dirait que votre fonction se passe en boucle sans fin en raison de l'heure supplémentaire dans le temps d'économie de lumière.

echo date('Y-m-d H:i:s', strtotime('2010-10-31') + 60*60*2); // adding 2 hours 
echo date('Y-m-d H:i:s', strtotime('2010-10-31') + 60*60*3); // adding 3 hours 

les deux afficheront 2010-10-31 02:00:00. Ainsi, strtotime('2010-10-31') + 86400 est actuellement 2010-10-31 23:00:00, mais pas le lendemain.

Vous devez donc ajouter plus de 86400 secondes pour être sûr que vous avez activé le lendemain :-)

+0

brillant - c'est exactement le problème ... au lieu d'incrémenter de 86400 secondes ... Je vérifie maintenant le mois et continue d'incrémenter jusqu'à ce que ça change ... plus de timeouts ...! – zeroasterisk

+0

génial raccomandation – dynamic

+0

FYI - J'ai également trouvé cette bibliothèque vraiment facile à utiliser et fiable: https://github.com/jkonieczny/PHP-Crontab peut simplement utiliser les notifications cron standard et il passera à la prochaine période d'action correspondante - - il est vraiment facile de générer la liste des options ... – zeroasterisk

0

Je pense que votre index de tableau devient trop fou.

-à-dire:

[Month#-Month#-Month#-Month#-Month#-Month#-Month#-Month#-Month#-Month#-Month#-Month#-Month#-Month#-Month#-Month#-Month#-Month#-Month#-Month#-Month#-Month#-Month#-Month#-123] => Array 
(
    [start] => 2011-12-01 
    [stop] => 2011-12-31 
) 

Je proposerais votre "$ monthInt = "# mois -". Str_pad (monthInt $, 3, "0", STR_PAD_LEFT);" lignes en dehors de votre boucle.

<?php 
function monthIterate($monthInt, $startDate, $stopDate) { 

$monthInt = "Month#-".str_pad($monthInt, 3, "0", STR_PAD_LEFT); <-- 

$epoch = $startMain = strtotime($startDate); 
$stopMain = strtotime($stopDate); 
while ($epoch <= $stopMain) { 
    // get the start/stop dates for "this month" 
    $start = date("Y-m-01", $epoch); 
    $stop = date("Y-m-t", $epoch); 
    // uniqueID for the month 
    $months[$monthInt] = compact('start', 'stop'); 
    // move forward in loop, +1 day should get us to the next month 
    $epoch = strtotime($stop) + 86400; 
    $monthInt++; 
} 
return $months; 
}?> 
+0

Vous avez raison, mais c'est seulement parce que je démontais les choses pour communiquer cette fonction ... [Qwerty] a compris que c'était un jour-économies-temps problème ... mise à jour de la fonction à corriger. – zeroasterisk