我怎样才能使这个csv读取PHP代码更有效率

时间:2013-12-07 13:11:53

标签: php html csv performance fgetcsv

好的,所以我有以下代码读取一个csv文件,而不是以HTML表的形式输出结果:

$fhdrop = fopen("ac.csv", "r");

while (!feof($fhdrop) ) {

$at[] = fgetcsv($fhdrop, 1024);

}

$fhdrop2 = fopen("rc.csv", "r");

while (!feof($fhdrop2) ) {

$at2[] = fgetcsv($fhdrop2, 1024);
}
?>

<table border=1>
<tr>
<td>a</td>
<td>b</td>
<td>c</td>
<td>d</td>
<tr>
<td><?php echo $at[0][0] ?></td>
<td><?php echo $at[0][1] ?></td>
<td><?php echo number_format($at[0][1]*$at2[0][1],2) ?></td>
<td><?php echo number_format($at[0][1]*$at2[1][1],2) ?></td>
</tr>
<tr>
<td><?php echo $at[1][0] ?></td>
<td><?php echo $at[1][1] ?></td>
<td><?php echo number_format($at[1][1]*$at2[0][1],2) ?></td>
<td><?php echo number_format($at[1][1]*$at2[1][1],2) ?></td>
</tr>
<tr>
<td><?php echo $at[2][0] ?></td>
<td><?php echo $at[2][1] ?></td>
<td><?php echo number_format($at[2][1]*$at2[0][1],2) ?></td>
<td><?php echo number_format($at[2][1]*$at2[1][1],2) ?></td>
</tr>
<tr>
<td><?php echo $at[3][0] ?></td>
<td><?php echo $at[3][1] ?></td>
<td><?php echo number_format($at[3][1]*$at2[0][1],2) ?></td>
<td><?php echo number_format($at[3][1]*$at2[1][1],2) ?></td>

Wag1 pplz !!!这个帐户现在是我的!          

ac.csv的内容是:

a, 5,
b, 10,
c, 24,
d, 21

rc.csv的内容是:

not, 1.87,
notatall, 1.78

正如您可以从原始代码中猜到的那样,在第二列中我需要乘法。所以例如在第二行,第三列我需要5 * 1.87和5 * 1.78。所以基本上是* not和a * notatall。

我的代码效率不高,如何才能提高效率?我希望所有这些(不知何故)进入一个循环。它需要有完全相同的结果,由于它的复杂性和它有2d阵列的事实,我还没有能够做到这一点!

3 个答案:

答案 0 :(得分:1)

<?php
$fhdrop = fopen("ac.csv", "r");
while (!feof($fhdrop) ) {
    $at[] = fgetcsv($fhdrop, 1024);
}

$fhdrop2 = fopen("rc.csv", "r");
while (!feof($fhdrop2) ) {
    $at2[] = fgetcsv($fhdrop2, 1024);
}
?>

<table border=1>
    <tr>
        <td>a</td>
        <td>b</td>
        <td>c</td>
        <td>d</td>
    </tr>

    <?php 
    for ($i = 0; $i < sizeof($at); $i++){
    ?>
    <tr>
        <td><?php echo $at[$i][0] ?></td>
        <td><?php echo $at[$i][1] ?></td>
        <td><?php echo number_format($at[$i][1]*$at2[$i][1],2) ?></td>
        <td><?php echo number_format($at[$i][1]*$at2[$i][1],2) ?></td>
    </tr>
    <?php
    }
    ?>
</table>

注意:我假设$ at(ac.csv)和$ at2(rc.csv)具有相同的长度。

答案 1 :(得分:1)

我唯一的建议就是这个

<table>
<tr>
    <td>a</td>
    <td>b</td>
    <td>c</td>
    <td>d</td>
</tr>

<?php

$fhdrop2 = fopen("rc.csv", "r");
while (!feof($fhdrop2) ) { 
    $at2[] = fgetcsv($fhdrop2, 1024);
}

$fhdrop = fopen("ac.csv", "r");
while (!feof($fhdrop) ){
    $at = fgetcsv($fhdrop, 1024);
?>

    <tr>
        <td><?php echo $at[0]; ?></td>
        <td><?php echo $at[1]; ?></td>
        <td><?php echo number_format($at[1]*$at2[0][1],2); ?></td>
        <td><?php echo number_format($at[1]*$at2[1][1],2); ?></td>
    </tr>

<?php
}

?>
</table>

这不应该优化速度,但它应该为更大的ac.csv文件节省一些内存,因为你不需要创建一个大数组。但我认为你不能在这里优化速度。我希望有人能提供更好的答案。

编辑#01 这是一个更灵活的循环

<tr>
    <td><?php echo $at[0] ?></td>
    <td><?php echo $at[1] ?></td>
    <?php for($i = 0; $i < sizeof($at2); $i++){ ?>
    <td><?php echo number_format($at[1]*$at2[$i][1],2) ?></td>
    <?php } ?>
</tr>

使用这个,你的rc.csv可以存储2个以上的值来相乘。不是速度或内存优化,但如果您尝试扩展功能/循环,则可以节省代码和时间。

编辑#02 我尝试了scrowler的方法,并且因为逻辑/标记分离而建议这个方法。副作用是更多地使用内存和略慢的脚本速度,但它并不重要(速度)。

希望这会有所帮助

答案 2 :(得分:0)

好的,我将从一些我认为非常重要的概念开始。

首先,您需要将CSV文件转换为某种结构化数据格式(一组拆分值将用于CSV)。我将使用PHP的str_getcsv()来实现此目的。这个函数应该在一个循环中调用,因为它接收一个字符串并将它拆分成一个数组。

其次,我坚信您应该在之前完成所有逻辑工作来输出数据。通过这种方式,您的输出代码可以保持清洁和轻松(您或其他人)。所以我要在输出之前做逻辑,只使用一个简单的输出数组。

所以我首先在数组中重新创建CSV文件:

$csv_file_1 = array(
    'a, 5,',
    'b, 10,',
    'c, 24,',
    'd, 21'
);

$csv_file_2 = array(
    'not, 1.87,',
    'notatall, 1.78'
);

在您的情况下,您希望将CSV文件读入数组,我建议最好的方法是使用PHP的file()函数。容易:

// read csv files into arrays
$csv_file_1 = file('your_first.csv');
$csv_file_2 = file('your_second.csv');

接下来,我想循环遍历第一个数组,从中获取两个变量,然后循环遍历其中的第二个数组并对第二个原始变量进行计算(我们将调用原始数据{{1} }和var1,以及第二个数组var2factor_name):

factor

现在,您有一个如下所示的数组:

foreach($csv_file_1 as $originals) {
    // get variables from each line
    list($var1, $var2) = str_getcsv($originals);
    // remove whitespace from second variable
    $var2 = trim($var2);
    $factors_output = array();
    // get multiplier variables
    foreach($csv_file_2 as $factors) {
        list($factor_name, $factor) = str_getcsv($factors);
        // do calculation, add to temporary array
        $factors_output[] = $var2 * $factor;
    }
    // array_merge the original vars with the multiplied vars
    $output[] = array_merge(array($var1, $var2), $factors_output);
}

这对您有好处,因为您现在拥有了您想要输出的结果的结构化数据,并且您拥有世界上有关如何处理该数据的所有自由。我将以你在问题中的方式输出它。数组上的foreach循环将仅输出标题行,然后第二次输出数据行。

Array
(
    [0] => Array
        (
            [0] => a
            [1] => 5
            [2] => 9.35
            [3] => 8.9
        )

    [1] => Array
        (
            [0] => b
            [1] => 10
            [2] => 18.7
            [3] => 17.8
        )

    [2] => Array
        (
            [0] => c
            [1] => 24
            [2] => 44.88
            [3] => 42.72
        )

    [3] => Array
        (
            [0] => d
            [1] => 21
            [2] => 39.27
            [3] => 37.38
        )

)

现在,你问过效率问题。当处理由PHP解析到内存(数组)的CSV文件时,总有可能你的CSV可能很大,并且可能很快咀嚼服务器的内存(可能导致它崩溃,在极端情况下重启等)。在你的情况下你可能不会遇到这种情况,但我不知道你的情况。因此,当你完成它们时,<table border="1"> <tr> <? foreach($output as $line) : ?> <td><?=$line[0]?></td> <? endforeach; ?> </tr> <? foreach($output as $line) : ?> <tr> <? foreach($line as $var) : ?> <td><?=$var?></td> <? endforeach; ?> </tr> <? endforeach; ?> </table> 变量总是一个好主意。

unset

Here's a demo of this example.

  

文档

  

进一步阅读