Goedenavond,

Ik heb een (zwaar) script gemaakt die 4000+ YouTube video's moet scannen en in een database stoppen. M'n probleem is nu het memory limit.


Fatal error: Allowed memory size of 209715200 bytes exhausted (tried to allocate 47 bytes) in C:\xampp\htdocs\gamerspawnfeed\Zend\Gdata\App\Base.php on line 380


Ik heb php.ini al aangepast naar 8196M, maar dit lijkt niet te werken... Heeft iemand een oplossing?

Alvast bedankt!
Hahaha, als je server meer dan 8 GB intern geheugen heeft, zou het geen probleem moeten zijn.

Je kan er voor zorgen dat je het geheugen zo optimaal mogelijk gebruikt.
Dit doe je door zo efficient mogelijk je processen af te handelen.

Verder kun je natuurlijk in één keer proberen alle 8,000 filmpjes te scannen, maar je kan het ook verdelen in parten van bijvoorbeeld 100 stuks. Je laat het script bijhouden welke filmpjes je al hebt gehad.

Laat een cronjob het script aanroepen en verder gaan bij het laatste filmpje.
Ik dacht echt dat 16GB genoeg moest zijn voor m'n server... :/

Tevens heb ik al geprobeerd om variables te unsetten, maar zonder succes. Ik krijg een error wanneer ik objects (YouTube API werkt met objects) in een session probeer te zetten. Ook met serialize()
Zou je wat code kunnen posten? Niet alles, maar ongeveer dat waarin globaal staat wat je doet (het ophalen, het verwerken, het opslaan)

Ik denk dat je daar een heleboel kan verbeteren, want in principe heb je hiervoor amper geheugen nodig: gewoon één filmpje per keer verwerken, dan hoef je altijd maar data voor één filmpje in het geheugen te houden. En aangezien PHP toch niet threaded is en ik niet aanneem dat je ingewikkelde dingen met curl aan het doen bent, denk ik dat dat prima mogelijk is.
function printEntireFeed($videoFeed, $counter) {
    mysql_connect("", "", "");
    mysql_select_db("");
 foreach($videoFeed as $videoEntry) {
     $videoThumbnails = $videoEntry->getVideoThumbnails();
     foreach($videoThumbnails as $videoThumbnail) {
        $thumbnails[] = $videoThumbnail['url'];
     }
     $query = "INSERT INTO videos (video_id, title, added, updated, private, description, tags, category, viewcount, rating, watch_page_url, flash_url, mobile_rtsp_url, thumbnails) VALUES ('" . $videoEntry->getVideoId() ."', '" . addslashes($videoEntry->getVideoTitle()) . "', '" . $videoEntry->getPublished() . "', '" . $videoEntry->getUpdated() . "', '" . $videoEntry->isVideoPrivate() . "', '" . addslashes($videoEntry->getVideoDescription()) . "', '" . addslashes(implode(", ", $videoEntry->getVideoTags())) . "', '" . $videoEntry->getVideoCategory() . "', '" . $videoEntry->getVideoViewCount() . "', '" . serialize($videoEntry->getVideoRatingInfo()) . "', '" . $videoEntry->getVideoWatchPageUrl() . "', '" . $videoEntry->getFlashPlayerUrl() . "', '" . addslashes(serialize($videoEntry->mediaGroup->content)) . "', '" . serialize($thumbnails) . "')";
     mysql_query($query) or die($query . "<br />" . mysql_error());
     echo $counter . "<br />";
     $counter++;
     unset($videoEntry);
 }

 // See whether we have another set of results
 try {
   $newVideoFeed = $videoFeed->getNextFeed();
   unset($videoFeed);
 } catch (Zend_Gdata_App_Exception $e) {
   echo $e->getMessage() . "<br />\n";
   if($e->getMessage() == "No link to next set of results found.") {
        return;
   } else {
        printEntireFeed($newVideoFeed, $counter);
   }
 }

 if ($newVideoFeed) {
   echo "-- next set of results --<br />\n";
   printEntireFeed($newVideoFeed, $counter);
 }
}


Als iemand weet hoe ik dat kan optimaliseren, hoor ik het graag. :)
Zou je misschien eerst niet een beetje leren over ZEND enzo (dat gebruik je?). Je hoeft niet iedere keer opnieuw te connecten met je database. Verder heb je ook geen foutafhandeling op je database (nee, 'or die' is geen foutafhandeling).
Als prolog fan vind ik recursie prachtig, maar ik zou het niet gebruiken in PHP: grote kans dat hij variabelen pas vrij geeft aan het eind van een functie, en dat is in pure recursie pas aan het eind het geval. (prolog en andere talen die ervoor gemaakt zijn optimaliseren dat automatisch)

Dus gewoon een while lus. En escape alles! Ook dat wat uit Google's API komt. Niet ervan uit gaan dat het wel veilig is.
<?php
// buiten de functie gehaald om er niet voor te zorden dat hij iedere keer
// er nog een verbinding bij maakt.
mysql_connect("", "", "");
mysql_select_db("");

function escape_date($date)
{
$time = strtotime($date);
return date('Y-m-d H:i:s', $time);
}

function escape_bool($bool)
{
// Geen idee hoe jij bools in je database opslaat
return $bool ? 'yes' : 'no';
}

function import_feed($videoFeed)
{
$videos_imported = 0;

foreach($videoFeed as $videoEntry)
{
$videoThumbnails = $videoEntry->getVideoThumbnails();
foreach($videoThumbnails as $videoThumbnail) {
$thumbnails[] = $videoThumbnail['url'];
}

$query = "
INSERT INTO videos (
video_id,
title,
added,
updated,
private,
description,
tags,
category,
viewcount,
rating,
watch_page_url,
flash_url,
mobile_rtsp_url,
thumbnails
) VALUES (
'" . mysql_real_escape_string($videoEntry->getVideoId()) ."',
'" . mysql_real_escape_string($videoEntry->getVideoTitle()) . "',
'" . escape_date($videoEntry->getPublished()) . "',
'" . escape_date($videoEntry->getUpdated()) . "',
'" . escape_bool($videoEntry->isVideoPrivate()) . "',
'" . mysql_real_escape_string($videoEntry->getVideoDescription()) . "',
'" . mysql_real_escape_string(implode(", ", $videoEntry->getVideoTags())) . "', -- is dit een goed idee?
'" . mysql_real_escape_string($videoEntry->getVideoCategory()) . "',
" . intval($videoEntry->getVideoViewCount()) . ",
'" . mysql_real_escape_string(serialize($videoEntry->getVideoRatingInfo())) . "',
'" . mysql_real_escape_string($videoEntry->getVideoWatchPageUrl()) . "',
'" . mysql_real_escape_string($videoEntry->getFlashPlayerUrl()) . "',
'" . mysql_real_escape_string(serialize($videoEntry->mediaGroup->content)) . "',
'" . mysql_real_escape_string(serialize($thumbnails)) . "'
)";

if (!mysql_query($query))
{
echo mysql_error() . '<br><br><pre>' . $query . '</pre>';
continue; // probeer volgende video
}

++$videos_imported;
}

return $videos_imported;
}

function import_entire_feed($video_feed)
{
$imported_videos = 0;

while ($video_feed)
{
$imported_videos += import_feed($video_feed);
// geeft NULL terug als er geen volgende feed is zegt de handleiding
// en dan stopt de WHILE lus.
$video_feed = $video_feed->getNextFeed();
}

return $imported_videos;
}

$imported_videos = import_entire_feed($feed);
printf('Imported %d videos', $imported_videos);
?>
Als eerste, bedankt! :D Het werkt perfect!

Dit is inderdaad een veel slimmere manier, veel van geleerd.

Maar wat bedoel je met: "is dit een goed idee?"?

Reageren