这样应该更高效
我尝试重写此位。原始版本无法保存,但我尝试保持其功能相同。
$csv = file_get_contents();
$lines = explode(PHP_EOL, $csv);
$array = array();
foreach ($lines as $line) {
$array[] = str_getcsv($line);
}
for ($i=1; $i < count($array); $i++) {
if($array[$i][0] == '') {
$ad1 = 'Null';
} else {
$ad1 = $array[$i][0];
}
if($array[$i][1] == '') {
$ad2 = 'Null';
} else {
$ad2 = $array[$i][1];
}
$content = "Address 1: ".$ad1." Address 2: ".$ad2."</br>";
$post = array(
'post_title' => $ad1,
'post_content' => $content,
'post_status' => 'publish',
'post_author' => 1
);
wp_insert_post($post);
}
但是没有任何数据可以查看,并且不知道脚本的顶部与这些有什么关系,这是我能做的最好的事情。还有一些我只是拒绝使用的嵌套级别。
$handle = fopen('https://data.medicare.gov/api/views/mj5m-pzi6/rows.csv', 'r');
while(!feof($handle)){
$line = fgetcsv($handle);
/*
the original has this $array[$i][0], $array[$i][1] we don't have the
$i level so this is just the first/second columns
{condition} ? true : false - these are ternary statements which are
just a way of doing a shorthand if condition.
*/
$ad1 = ($line[0] == '') ? 'Null' : $line[0];
$ad2 = ($line[1] == '') ? 'Null' : $line[1];
/*
you might want to add this check in, continue will skip to the next
iteration, the if checks if both ad1 and ad2 are 'Null` so these look
to me to be empty rows, so just un-comment that to skip them
*/
//if($ad1 == 'Null' && $ad2 == 'Null') continue;
$content = "Address 1: ".$ad1." Address 2: ".$ad2."</br>";
//short hand array syntax PHPv5.4+
$post = [
'post_title' => $ad1,
'post_content' => $content,
'post_status' => 'publish',
'post_author' => 1
];
wp_insert_post($post);
}
这没什么大不了的,因为我花了大约 10 分钟。希望它对你有用,我无法测试它。您可能会注意到它比原版短得多。
HyYa 我就像一个代码忍者,他们是半排骨。
这里的关键,是原始打开整个文件到内存中。然后它把它分解成一个巨大的数组,然后它不是一次而是迭代两次。然后它会进行插入。
我的版本,分别拉出每一行,检查它,插入,从内存中转储它。这在内存管理上显然要好得多。此版本不应耗尽内存。
也就是说,您可能仍然没有时间。你可以添加这样的东西。
while(!feof($handle)){
set_time_limit(60); //1 minutes per iteration
当然你可以只设置set_time_limit(0);或无限时间。
但是,Apache 的超时很可能会让你失望,因为我认为 WP-Cron 实际上并不使用 CRON。或者换句话说,不在命令行 (CLI) 上运行。但我喜欢根据迭代给它一个限制,然后它不是无限的。从本质上讲,只要此迭代时间少于 1 分钟,就不会超时。但正如我所说,我认为这不是“真正的” Cron 工作。它更像是一个在 wordpress 中运行的调度程序,因此您仍然与 Apache 服务器绑定。
可能有一种方法可以将它与真正的 Cron Job 联系起来,但现在我在漫无边际,此时它并不重要(我不是 Wordpress 的大用户)
最后几件事
1
这看起来像一个远程文件https://,如果你先保存它然后去查看它,你可能会得到更好的性能。但除非你有网络问题,否则我不会担心,因为那样你就在做双重职责。但是,如果您在逐行阅读时遇到问题,而不是我建议的那样,请使用 stream_copy_to_stream 之类的东西在不插入数据库的情况下更快地将其写入磁盘,然后在保存后再次查看它,然后使用 unlink 删除文件
$remote = fopen('https://...', 'r');
$local = fopen('localfile.css', 'w+'); //write/read mode
stream_copy_to_stream($remote, $local);
fclose($remote);
rewind($local); //rewind file pointer to start
...other code..
这样你在开始之前就可以在本地拥有整个文件,但是应该清楚我为什么说它是双重职责。
2
我不确定这与 CSV 部分有什么关系,它似乎是一个单独的交易。
$args = array(
'numberposts' => -1,
'post_status' => 'any'
);
$ids = get_posts($args);
foreach($ids as $id) {
wp_delete_post($id->ID, true);
}
最好让脚本专注于一项任务,这样更容易维护。也许这是其中的一部分?我只是没有看到任何将其绑定到 CSV 部分的变量,并且顶部缺少一些代码。所以我只是忽略了它并专注于 CSV 部分。
3
仅当您输出内容以进行下载时才需要此标头。这告诉浏览器它是什么时间的内容,如果你没有通过输出它给浏览器,那么它充其量是不必要的,最坏的情况是如果你在发送标头后尝试做某些事情会导致错误。就像重定向一样,但我没有看到在这个用例中发生这种情况。
header("Content-type: text/csv");
夏天
不要听我用错误的语气说的话,人们倾向于对我这样做。在批评代码时,我非常直率。每个人都必须学习,而我确实在一个可以读取 10 兆字节的 CSV 文件的地方工作。我们做过的最大的是 1500 万行,我们通常会读取大约 100 万行的文件。
我们使用 SPLFileObject 作为 CSV 阅读器的基础,它非常酷,但为此设置可能有点矫枉过正。在任何情况下,这可能是读取 CSV 的最有效方式,而且不会让您发疯。
如果您对它的工作原理有任何疑问,请随时询问。
更新
你真的应该用真正的 CRON 来运行它
What is the Real CRON
这是一个有点高级的话题,而 wordpress 并没有让它变得更容易。我可以就此写一篇完整的其他帖子。但它从 CLI 命令行界面运行 PHP,绕过了在 Apache 下运行的一些限制(如时间限制)。
让 WP 以这种方式运行有点小技巧,但我整理了一些我在谷歌上搜索的东西,其中一些来自个人知识。
在 webroot 之外(public_html 之外)运行 wordpress 在 CLI 中,将假定它位于名为 /home/website/cron 的文件夹中,该文件夹是 webroot /home/website/public_html 的兄弟
<?php
//make sure error reporting is on
error_reporting(-1);
ini_set('display_errors', 1);
$webreoot = realpath('../public_html').'/';
//setup global $_SERVER variables to emulate Apache environment
$_SERVER = array(
"HTTP_HOST" => "http://example.com",
"SERVER_NAME" => "http://example.com",
"REQUEST_URI" => "/",
"REQUEST_METHOD" => "GET",
"SERVER_ADDR" => 'xxx.xxx.xxx.xxx'
);
//turn off theme support
define('WP_USE_THEMES', false);
//require the WP bootstrap
require_once $webreoot.'wp-load.php';
//wordpress should in theory be loaded where you can use the wp_ functions.
希望对您有所帮助。