Memory Limit exceeded
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.
Quote:
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!
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.
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()
Gewijzigd op 15/06/2011 22:11:42 door Wouter Hardeman
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.
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
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);
}
}
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. :)
Gewijzigd op 15/06/2011 23:10:23 door Wouter Hardeman
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).
http://framework.zend.com/download/gdata
Verder is het geen openbaar script en hoeft de error niet afgehandeld te worden.
Nee, ik gebruik de Google Data APIs. Ik gebruik het framework verder niet. Verder is het geen openbaar script en hoeft de error niet afgehandeld te worden.
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.
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
<?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);
?>
// 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);
?>
Dit is inderdaad een veel slimmere manier, veel van geleerd.
Maar wat bedoel je met: "is dit een goed idee?"?
mysql one to many relation of [http://www.phphulp.nl/php/tutorial/overig/normaliseren/150/]Normaliseren[/url].
Als je de categorieën met komma's scheidt kan je er niet zo makkelijk op koppelen als dat je een koppeltabel gebruikt: