user3273401
user3273401

Reputation: 45

PHP is not properly processing first row in a CSV file

Compare the CSV file of two, in the case of the same identifier, I want to make the calculation at a certain formula. And Always, I can't get The first row result.

My code (test.php)

<html>
<head>
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD XTHML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <link rel="stylesheet" type="text/css" href="it_test_check_uesr_list_table.css" /></head>
<body>
<?php 
    $data = fopen("rate.csv", "r");
    /*  rate.csv

        code,codename,data,.......
        3668,A, 3325,+50(+1.53%),410518,A
        3765,B, 606,+1(+0.17%),698118,B
        7832,C, 2557,+10(+0.39%),567654,C
        6460,D, 2048,-11(-0.53%),545238,D
    */
    $baserate = fopen("baserate.csv", "r");
    /*  baserate.csv

        code,data
        7832,2312
        3765,734
        3668,3025
        6460,2682
    */
    if($baserate){
        while ($baserate_line = fgets($baserate)) 
        {
            list($temp_code,$temp_data) = explode(",", rtrim($baserate_line));
            $base_rate[] = (object)array('code' => $temp_code,
            'data' =>  mb_convert_encoding($temp_data, "UTF-8", "auto"));
        }
    }
    if($data){
        while ($line = fgets($data)) 
        {
            list($temp_code,$temp_codename,$temp_data,$temp_comparison_previous_day,$temp_market_capitalization,$temp_market) = explode(",", rtrim($line));
            for($i = 0; $i< count($base_rate); $i++) 
            {
                if($temp_code == $base_rate[$i]->code)
                {   
                    //What I want (temp_data_index)
                    $temp_data_index = number_format($temp_data / $base_rate[$i]->data * 100,2); 
                }
            }
            $company[] = (object)array('code' => $temp_code,
            'codename' =>  mb_convert_encoding($temp_codename, "UTF-8", "auto"),
            'data' => mb_convert_encoding($temp_data, "UTF-8", "auto"),
            'comparison_previous_day' => mb_convert_encoding($temp_comparison_previous_day, "UTF-8", "auto"),
            'market_capitalization' => mb_convert_encoding($temp_market_capitalization, "UTF-8", "auto"),
            'market' => mb_convert_encoding($temp_market, "UTF-8", "auto"),
            'data_index' => mb_convert_encoding($temp_data_index, "UTF-8", "auto"));
        }
    }
    // A(The first row ) Always don't work
    for($i = 0; $i< count($company); $i++) 
    {
        echo $company[$i]->codename." - ".$company[$i]->data_index."<br>";
    }
    ?>
</body>
</html>

Result is

A - 
B - 82.56
C - 82.56
D - 76.36

'A'(The first row in csv file) Doesn't work for loop.(There is same code, I checked var_dump) What's my problem?

Upvotes: 0

Views: 161

Answers (1)

redreinard
redreinard

Reputation: 2044

OK, I'll take a swing, but first, let's clean up your code. it's hard to follow, has some horrible programming practices and for this example had a lot of stuff not relevant. So here is what i did:

  • remove the html, there's no reason for it in this context
  • php knows how to parse csv. much safer than exploding
  • calling a variable "data" should be a crime. it's a file descriptor pointing to a file of rates. that's hard to remember if it's called data. and then you also call a column in the rates file data and one in the baserate file also data - to make things extra clear i suppose. I renamed the first one, and left the others because i don't know what it represents, but holy confucious batman.
  • group related things together. open a file, load the data. then open the next file and load it's data. then process. doing all this at the same time makes it hard to follow in an example
  • don't use array's as objects unless you really really need to. it makes your code hard to read.
  • don't worry about encoding in an example. sure, have it in your production code, but in this example it just again makes it hard to follow your code - it's not relevant to your question
  • instead of looping through all baserates each time to find the one you want, index the array of them by what you're looking for
  • at least one of your csv files (rate.csv) has spaces as the beginning of some columns ("data" column), so to be safe you should trim each field, not just each row

// load rates
$fd_rates = fopen("rate.csv", "r");
if (!$fd_rates) die("Unable to open rate.csv");
$rates = array();
while (($rate_row = fgetcsv($fd_rates)) !== FALSE) {
    // key by code, turn into associative array
    $rates[ trim($rate_row[0]) ] = array(
        'code' => trim($rate_row[0]),
        'codename' => trim($rate_row[1]),
        'data' => trim($rate_row[2]),
        'comparison_previous_day' => trim($rate_row[3]),
        'market_capitalization' => trim($rate_row[4]),
        'market' => trim($rate_row[5]),
    );
}
fclose($fd_rates);
/*  rate.csv / $rates

    code,codename,data,....... // this line not in file
    3668,A, 3325,+50(+1.53%),410518,A
    3765,B, 606,+1(+0.17%),698118,B
    7832,C, 2557,+10(+0.39%),567654,C
    6460,D, 2048,-11(-0.53%),545238,D
*/

// load baserates
$fd_baserates = fopen("baserate.csv", "r");
if (!$fd_baserates) die("Unable to open baserate.csv");
$baserates = array();
while (($baserate_row = fgetcsv($fd_baserates)) !== FALSE) {
    // code => data
    $baserates[ trim($baserate_row[0]) ] = trim($baserate_row[1]);
}
fclose($fd_baserates);
/*  baserate.csv

    code,data // this line not in file
    7832,2312
    3765,734
    3668,3025
    6460,2682
*/

// calculate
foreach ($rates as $code => $rate) {
    if (isset($baserates[$code])) {
        $rates[$code]['data_index'] = number_format($rate['data'] / $baserates[$code] * 100, 2);
    } else {
        $rates[$code]['data_index'] = 'no baserate found';
    }
}

// display
foreach ($rates as $code => $rate) {
    echo "{$rate['codename']} - {$rate['data_index']}\n";
}

And then I just ran the code... and it works. I'm not going to bother trying to find the specific bug in your code, but honestly, in my opionion, it's due to bad programming practices. Name your variables. Simplify. Good luck!

$ php index.php 
A - 109.92
B - 82.56
C - 110.60
D - 76.36

$ php -v
PHP 5.5.9-1ubuntu4.4 (cli) (built: Sep  4 2014 06:56:34) 
Copyright (c) 1997-2014 The PHP Group
Zend Engine v2.5.0, Copyright (c) 1998-2014 Zend Technologies
    with Zend OPcache v7.0.3, Copyright (c) 1999-2014, by Zend Technologies

Upvotes: 1

Related Questions