我的Wordpress查询有问题。
我想做什么:
我有包含产品数据(名称,价格,库存,sku等)的CSV文件 而且我想导入此文件,但是当我尝试通过SKU获取产品ID时,查询对我的服务器而言太高了,但是我在做一些愚蠢的主意:在foreach中,我试图获取所有product_id。 / p>
可以在不终止服务器的情况下拆分wp查询吗? 我正在尝试睡觉,但这没有结果...
我的代码在这里:
public function new_import_stock_prices(){
global $wpdb;
global $post;
if ( !function_exists( 'wc_get_product_id_by_sku' ) ) {
require_once '/includes/wc-product-functions.php';
}
echo '<h1>Import stanów magazynowych i cen z pliku CSV </h1>';
echo '<h4>Plik pobierany jest z netis/products.csv</h4>';
$fn = 'https://e-xxxxx.pl/xxx/products.csv';
$file_array = file($fn);
echo '<table>';
echo '<tr>';
echo '<td>LP</td>';
echo '<td>Nazwa</td>';
echo '<td>SKU</td>';
echo '<td>Stan magazynowy</td>';
echo '<td>Cena</td>';
echo '<td>Product ID</td>';
$i = 1;
if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ) ) ) {
foreach ($file_array as $line_number =>&$line)
{
if ($line_number > 0 && $line_number % 10 == 0) {
$row2=explode('|',$line);
$sku = $row2[1];
// get the product ID from the SKU
$product_id = $wpdb->get_var( $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE meta_key='_sku' AND meta_value='%s' LIMIT 1", $sku ) );
// Get an instance of the WC_Product object
$product = new WC_Product( $product_id );
//Get product stock quantity and stock status
$stock_quantity = $product->get_stock_quantity();
$stock_status = $product->get_stock_status();
echo '<tr>';
echo '<td>'.$i.'</td>';
echo '<td>'.$row2[0].'</td>';
echo '<td>'.$row2[1].'</td>';
echo '<td>'.$row2[5].'</td>';
echo '<td>'.$row2[2].'</td>';
echo '<td>'.$product_id.'</td>';
echo '</tr>';
$i = $i +1;
sleep(10);
}
}
}
echo '</table>';
}
顺便说一句。我的wp_postmeta表中有约90万条记录:O
答案 0 :(得分:0)
我想导入该文件
我看不到任何导入代码,我看不到显示代码。假设导入是指显示:
可能发生的事情是其中几件事之一。
file($fn)
使用打开文件并逐行读取文件的文件功能,例如fgetcsv
唯一真正的解决方案(假设是导入,您的意思是显示)是分页数据。
现在,即使在文件中,您也可以分页数据,但是我建议您使用SQLFileObject而不是过程文件函数。也就是说,您可以使用过程样式进行分页,但可以按字节偏移量而不是页码进行分页。
虽然我无法对整个寻呼系统进行编码,但我可以给您一些提示:
例如
//hard to tell how many lines in the file
$fn = 'https://e-xxxxx.pl/xxx/products.csv';
$f = fopen($fn, 'r');
fseek($f, $_GET['offset']); //seek to a byte offset
$i=0;
while(!feof($f) && ($row=fgetcsv($f)) && null !== $row[0]){
if($i==10)
$offset = ftell($f); //get byte offset
++$i;
}
ftell
和fseek
允许您获取或移动文件指针(以字节为单位)。因此,您可以从可以在url中传递的预定义偏移量开始读取...等等。
您可以使用SplFileObject做相同的事情,但要好一些。
try {
$fn = 'https://e-xxxxx.pl/xxx/products.csv';
$csv = new SplFileObject($fn, 'r');
} catch (RuntimeException $e ) {
printf("Error openning csv: %s\n", $e->getMessage());
}
$csv->seek($_GET['line']); //seek to a predefined line
while(!$csv->eof() && ($row = $csv->fgetcsv()) && null !== $row[0]) {
if(($csv->key()-$_GET['line'])==10)
$line = $csv->key(); //get line offset
++$i;
}
SPL的主要优点是您可以使用行号,使用起来更容易。
您还可以像这样获取文件中的总行数
$csv->seek(PHP_INT_MAX);
$total = $csv->key();
$csv->rewind(); //or $csv->seek($_GET['line'])
这基本上是在寻求INT PHP可以处理的最大范围,但是由于文件的长度是固定的,因此将指针放在文件的末尾,然后使用key
得到行号。然后我们简单地倒回我们要读取的位置。
我提到了总行数,因为在分页中很高兴能够显示出来。
另一个选项(显示)
除了分页之外,输出页面时也无需缓冲。
// Turn off output buffering
ini_set('output_buffering', 'off');
// Turn off PHP output compression
ini_set('zlib.output_compression', false);
//Flush (send) the output buffer and turn off output buffering
//ob_end_flush();
while (ob_get_level()) ob_end_flush();
// Implicitly flush the buffer(s)
ini_set('implicit_flush', true);
ob_implicit_flush(true);
使用上面显示的一种方法将其组合起来,一次一次读取文件的每一行,您也许最终可以读取所有数据。
保存
为保存数据,您可能需要将其分成几批,在这里可以使用分页进行相同的操作(使用offset或line)。这样您一次只能导入几千行。我也建议不要输出数据,因为您可以给浏览器更多的缓冲,然后它才能处理并锁定它。但是,如果分页数据,则可以将其分成足够小的块,以使浏览器可以处理它。
您甚至可以使用连续的AJAX调用来自动执行此操作。基本上,您将在后端调用代码以保存一定数量的行(x)。服务器将响应,然后您将再次要求增加(x)行,保存并重复。
我要显示所有产品ID,以检查其是否正确。下一步是更改库存,价格和节省产品
从数据输入的角度来看,用excel之类的工具进行这项工作会更容易,没有人愿意编辑网页上的数千行,然后使会话超时或类似的操作。
希望有帮助。