0

I am trying to pull data out of a foreach loop but I'm running into a strange phenomenon that I haven't encountered yet.

The first row of the CSV looks like this:

Part Number,Description,List Price

Then Data so on and so forth.

What I have:

ini_set('auto_detect_line_endings', TRUE);
if (($openItems = fopen($uploadFile, 'r')) !== FALSE) {
   foreach (fgetcsv($openItems) as $key => $value) {
        $value = preg_replace('/\h+/', '', strtolower($value));
        echo $value;
        echo ' = ' . $key . " ";
        switch ($value) {
            case "partnumber":
                $pn = $key;
                break;
            case "description":
                $des = $key;
                break;
            case "listprice":
                $lp = $key;
                break;
        }
    }
    print_r("\npn: " . $pn . " des: " . $des . " lp: " . $lp);
}

Print:

partnumber = 0 description = 1 listprice = 2 
pn:  des: 1 lp: 2

As you can see the first column is falsey so it is not assigned the proper value.

Alternative Print:

test = 0 partnumber = 1 description = 2 listprice = 3 
pn: 1 des: 2 lp: 3

I also tried an exercise after $key was echoed that checked:

if($value == 0) {
    echo " I'm 0 ";
}

Print:

partnumber = 0  I'm 0. description = 1  I'm 0. listprice = 2  I'm 0. 
pn:  des: 1 lp: 2

But if you check for numeracy it comes back false:

if(is_numeric($value)) {
    echo " I'm a number. ";
}

Print is unchanged:

partnumber = 0 description = 1 listprice = 2 
pn:  des: 1 lp: 2

That means it is 0 in a NULL or falsey sense right?

if(!$value) {
    echo " I'm False or Null. ";
}

But Print is unchanged:

partnumber = 0 description = 1 listprice = 2 
pn:  des: 1 lp: 2

Type check:

echo "I'm of Type ". gettype($value) . ". ";

returns:

partnumber = 0 I'm of Type string. description = 1 I'm of Type string. listprice = 2 I'm of Type string. 

Side Note:

case "partnumber":
    $pn = $key;
    break;

is never accessed

case "partnumber":
    $pn = $key;
    echo "I Worked!";
    break;

This returns with out any result.

Any, Suggestions?

This Scinario is thanks to @azjezz

$csv = [];
ini_set('auto_detect_line_endings', TRUE);
if (($openItems = fopen($uploadFile, 'r')) !== FALSE) {
    foreach (fgetcsv($openItems) as $key => $value) {
        $value = preg_replace('/\h+/', '', strtolower($value));
        $csv[$value] = (Int) $key;
        echo $value;
        echo ' = ' . $key . " ";
        switch ($csv[$value]) {
            case "partnumber":
                $pn = $key;
                break;
            case "description":
                $des = $key;
                break;
            case "listprice":
                $lp = $key;
                break;
        }
    }
    print_r("\npn: " . $pn . " des: " . $des . " lp: " . $lp);
}

Results in:

partnumber = 0 description = 1 listprice = 2 
pn: 0 des:  lp: 

Another weird scinario:

    switch ((int) $value) {
        case "partnumber":
            $pn = $key;
            break;
        case "description":
            $des = $key;
            break;
        case "listprice":
            $lp = $key;
            break;
    }

Returns:

partnumber = 0 description = 1 listprice = 2 
pn: 2 des:  lp: 
  • what is the format for partnumber in csv ? – Krish Dec 06 '17 at 21:01
  • I'm confused with your code there. You are assigning each to their index location, and not their actual value? Please add a few more rows of the csv file. – IncredibleHat Dec 06 '17 at 21:01
  • @Krish it's in a csv file so my assumption is that partnumber is plain text – OverBakedToast Dec 06 '17 at 21:02
  • @Randall Yes because in this manner I can assign the values to each column as that column no matter how many columns there are or what order they are in. That way if the CSV was like List Price,Description,Part Number. Then I would still be able to identify and assign the value accordingly to a database or file or where ever I'm storing or manipulating it. – OverBakedToast Dec 06 '17 at 21:07
  • 1
    Ok, I think I follow. This first grab is JUST processing the first csv row from the file, to setup what indexes are what. And thus, you are finding an odd problem where $key simply doesnt transfer into $pn. Hmm. curious one... – IncredibleHat Dec 06 '17 at 21:10
  • 1
    When you did this test `if($value == 0) { echo " I'm 0 "; }` ... is because this: https://stackoverflow.com/questions/6843030/why-does-php-consider-0-to-be-equal-to-a-string ... Also since `if(is_numeric($value))` came back correct (those strings are not numbers), and `if(!$value)` also came back correct ... $value is indeed containing those strings you expect. – IncredibleHat Dec 06 '17 at 21:28
  • And this is wrong: `$csv[$value] = (Int) $key;` with the `switch ($csv[$value])`. You are trying to match to the VALUE, not the KEY, which `$csv[$value]` contains the key. If that makes any sense :) – IncredibleHat Dec 06 '17 at 21:31
  • @Randall It's always the first column that doesn't work because the index is 0 for some reason that breaks it. – OverBakedToast Dec 06 '17 at 21:48

1 Answers1

1

Convert all values to integer then use $csv array.

$csv = [];
foreach (fgetcsv($openItems) as $key => $value) {
  $csv[$value] = (Int) $key;
}

var_dump($csv);

Note that == and === are not the same!

<?php 

$a = 0;
$b = "0";

// == is the Equal Comparison Operator
//if $a is equal to $b after type juggling.
if($a == $b) {
  echo "YES ITS TRUE";
}

// === is the Identical Comparison Operator
//  if $a is equal to $b, and they are of the same type. 
if($a === $b) {
  echo "Is it ?";
} else {
  echo "well its not";
}

you can read more about comparison operators here : http://php.net/manual/en/language.operators.comparison.php

azjezz
  • 3,827
  • 1
  • 14
  • 35
  • That returns this array(3) { [0]=> int(0) [1]=> int(0) [2]=> int(0) } – OverBakedToast Dec 06 '17 at 21:10
  • Does a switch compare data types in a === way? – OverBakedToast Dec 06 '17 at 21:12
  • fixed it. it shall return something similar to ['partnumber' = 0,'description' => 1 ,'listprice' => 2] now – azjezz Dec 06 '17 at 21:13
  • @OverBakedToast no , switch is similar to if($something == $something_else) – azjezz Dec 06 '17 at 21:15
  • Yeah it returned array(3) { ["partnumber"]=> int(0) ["description"]=> int(1) ["listprice"]=> int(2) } But I don't understand why it doesn't work with the switch still. Thanks for coming up with a solution though!!! That just means knowing why the switch doesn't work is extra credit ;) – OverBakedToast Dec 06 '17 at 21:15
  • I edited my code to work with your solution and I got a unique result I'll post in the question momentarily so you can look at it one moment – OverBakedToast Dec 06 '17 at 21:22
  • your answer did help me get further but I still haven't derived to a working conclusion. Thank you. – OverBakedToast Dec 06 '17 at 21:47
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/160655/discussion-between-overbakedtoast-and-azjezz). – OverBakedToast Dec 06 '17 at 21:54