我现在有一个Wordpress网站,里面有大约300k页面,还有一个内存为1GB的服务器。不幸的是,所有生成站点地图的插件都无法再处理它。我已经尝试了3种使用PHP(XMLWriter,SimpleXMLElement和DOMDocument)编写XML的不同方法,它们最终都会在大约30k页(xml节点)上加盖。
您认为我能做些什么来完成这项工作?在最糟糕的情况下,我考虑过设置多个cron作业,这些作业每天运行一次,每隔十分钟运行一次并继续打开/附加到文件中,只是添加到块中,但这显然不是最佳解决方案。我找到了一些声称可以在我的循环中清除内存的片段,但它也没有做到这一点。以下是该代码段的示例:
$xml = '<?xml version="1.0" encoding="UTF-8"?><urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">';
for ($i = 0 ; $i< 20; $i++) {
$query = mysql_query(sprintf("SELECT ID, post_date FROM wp_posts WHERE post_status='publish' LIMIT %s,%s", $i*10000, 10000));
while ($row = mysql_fetch_array($query)) {
$xml .= '<url>';
$xml .= '<loc>'.get_permalink($row['ID']).'</loc>';
$xml .= '<lastmod>'.$row['post_date'].'</lastmod>';
$xml .= '<changefreq>weekly</changefreq>';
$xml .= '<priority>0.6</priority>';
$xml .= '</url>';
}
}
$xml .= '</urlset>';
$sxe = new SimpleXMLElement($xml);
$sxe->asXML("sitemap.xml");
答案 0 :(得分:3)
为什么要一次抓取所有记录?
尝试每个请求获得10000行。并在每次迭代后清理内存。
如果您在cli模式下运行,旧版本的php不会释放内存,因此您可以尝试分叉http://php.net/manual/en/function.pcntl-fork.php
怎么做:
sprintf
就可以了。LIMIT ($i*10000) 10000
代码示例:
for ($i = 0 ; $i< 5 $i++) {
...
$sth = $dbh->prepare('SELECT * FROM table_name LIMIT ? ?');
$sth->execute(array($i*10000, 10000));
...
}
另一个代码示例:
<?php
$fileHandle = fopen("sitemap.xml", "w");
fwrite($fileHandle,
'<?xml version="1.0" encoding="UTF-8"?>' .
'<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"' .
' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ' .
' xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9' .
' http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">'
);
for ($i = 0 ; $i< 20; $i++) {
$query = mysql_query(sprintf("SELECT ID, post_date FROM wp_posts WHERE post_status='publish' LIMIT %s,%s", $i*10000, 10000));
$xml = '';
while ($row = mysql_fetch_array($query)) {
$xml .= '<url>'.
'<loc>'.get_permalink($row['ID']).'</loc>' .
'<lastmod>'.$row['post_date'].'</lastmod>' .
'<changefreq>weekly</changefreq>' .
'<priority>0.6</priority>' .
'</url>';
}
fwrite($fileHandle, $xml);
}
fwrite($fileHandle, '</urlset>');
fclose($fileHandle);
echo PHP_EOL . 'memory used: '. memory_get_peak_usage() . PHP_EOL;