Questions example I found at php.net

I’d like to understand the script at:PHP: fgetcsv - Manual

what does “!== FALSE” mean in the context of:
if (($handle = fopen(“$source_file”, “r”)) !== FALSE) { }

what does “as &$column” mean in the context of:
foreach ($columns as &$column) {}

and would someone please explain the bottom half of this script starting with “$insert_query_prefix”

<?php
function csv_file_to_mysql_table($source_file, $target_table, $max_line_length=10000) {
    if (($handle = fopen("$source_file", "r")) !== FALSE) {
        $columns = fgetcsv($handle, $max_line_length, ",");
        foreach ($columns as &$column) {
            $column = str_replace(".","",$column);
        }
        $insert_query_prefix = "INSERT INTO $target_table (".join(",",$columns).")\
VALUES";
        while (($data = fgetcsv($handle, $max_line_length, ",")) !== FALSE) {
            while (count($data)<count($columns))
                array_push($data, NULL);
            $query = "$insert_query_prefix (".join(",",quote_all_array($data)).");";
            mysql_query($query);
        }
        fclose($handle);
    }
}
?> 

!== is Type-Specific Not Equals.

!== FALSE means ‘Is not a boolean False’. This is different from != because if it was != False and your function returned 0 legitimately, you would mistakenly get a true-condition…

(Not False is hard to explain in english terms.)

Type-Sensitivity Example:


$a = false;
$b = 0;

if($a === false) {
  echo "A is TS false";
}
if($b === false) {
  echo "B is TS false";
}
if($a == false) {
  echo "A is NTS false";
}
if($b == false) {
  echo "B is NTS false";
}

Outputs:


A is TS false
A is NTS false
B is NTS false

Note the TS B didnt execute.

as &$column means ‘assign by reference $column’

So normally when you do a FOREACH, you give a variable (in this case column) which acts as a temporary holder of the value for each array value in turn. the & makes this a by-reference, which means that when you edit $column, you’re editing it’s value in the array.

As for the bottom half of your function, what that does is reads each line out of the CSV file, null-pads it to fit the headers, and gathers them to mass-insert them.

This function, it should be noted, expects your CSV to have quotes around the non-numeric strings. If they arnt there, you’ll get errors

So, in this case, !== FALSE is a check to make sure there’s data in $source_file. Right?

It’s used as an EOF (End Of File) check - if [FPHP]fgetcsv[/FPHP] tries to read a line from a file it’s already reached the end of, it will return FALSE.

fgetcsv will also return FALSE if there’s an error for any reason, but in this case it’s main purpose is for EOF.

I’m following you.

Next, &$column, turns the column into the key that will be accessed. Right?

If so, is the a reference available for using & that way?

okay it’s a question of scope.

Try this:


$array = array(0,1,2);
print_r($array);
echo "<br>";

foreach($array AS $value) {
  $value = $value + 1;
  echo $value;
}

echo "<br>After first Foreach:";
print_r($array);
echo "<br>";

foreach($array AS &$value) {
   $value = $value + 1;
  echo $value;
}

echo "<br>After Foreach 2:";
print_r($array);

So, “&” allows the script to detect the EOF?

& tells the engine “I’m passing by reference.”

By reference means that instead of storing a local copy of the data for use in the loop, it instead points to the original copy of the value.

Look at my example. In the first foreach, I’m not passing by reference. So it creates a local copy of each value from the array, adds 1 to that local copy, and prints it out - doesnt modify the original array at all, as you can see by the After Foreach 1 statement.

When it gets to the second foreach, I pass by reference. Now when i modify the value, i’m modifying the value in the original array, so when i leave the loop, those changes stick.

OK. PHP: Passing by Reference - Manual

But why do you thing they used pass by reference? Is it the need to perform the str_replace() ?

The “&” - reference - means you’re working with the actual variable instead of a “copy” (in memory) of it.

It can be a little tricky because if your code is wrong somewhere it messes up the “real” value. An alternative is to work with the values and pass them to new variables and then work with those. But as long as you’re careful (checks and error and exception handling) you should be OK.

It doesn’t have anything to do with EOF here, its just another part of the code.

The PHP docs are good IMHO but they often use examples to demonstrate the particular thing they’re dealing with and depend on you either understanding or following up on other portions of the example.

Off Topic:

My one-finger typing too slow again :wink:

Why is always a dangerous question to ask :stuck_out_tongue:

The simple answer is 'because they wanted to change them in the original array so they could then join() (aka impode()) them later without issues.

Could they have done it without the Pass By Reference? Sure.


foreach($array AS $key => $value) {
  $array[$key] = $value + 1;
}

works just as well. They could also have array_map’d it, or…or… (How many ways are there to skin a cat)

OK.

So, how do I define $target_table when I call the function if I need to send data from a file called test.csv to a table called pic in the emily MYSQL database?

csv_file_to_mysql_table(test.csv, ???, $max_line_length=10000)

Also, please confirm that I don’t need a parameter for $max_line_length?

the =10000 tells you that that parameter is optional - if left off, it will be filled with 10000 by default.

so lets see…
First of all, strings need quote marks around them, so that test.csv needs to be a “test.csv” instead…

So, how do I define $target_table when I call the function if I need to send data from a file called test.csv to a table called pic in the emily MYSQL database?

Well, lets see.


function csv_file_to_mysql_table([COLOR="RoyalBlue"]$source_file[/COLOR], [COLOR="SeaGreen"]$target_table[/COLOR], $max_line_length=10000) { 

So, how do I define $target_table when I call the function if I need to send data from a file called test.csv to a table called pic in the emily MYSQL database?

So you tell me. How should you call the function to do what you want it to?

(The database used is defined when you do your database connection, and doesnt apply to this function)

Yeah that’s not a standard function, so i dont know what it’s supposed to do… does your CSV file already have quote marks around strings? If so, just strip that function off and put $data there. If not, we’ll have to write a quote_all_data function real quicklike.

I added this to the bottom of the script:
include “connect_to_mysql.php”;
csv_file_to_mysql_table(“test2.csv”,“pic”);

and got this message:
Fatal error: Call to undefined function quote_all_array() in C:\wamp\www\acrobat7f.php on line 12

edit:
column names matches first record of test2.csv

test2.csv:
“ref”,“pic”
“1”,“LAMS-DR6313-110609-110606-39.90-95.94-JPG.jpg”
"2,“LAMS-DR61039-110609-120609-80.99-52.64.PNG.png”
"3,“LAMS-HE08074-110609-120609-69.99-45.49-JPG.jpg”


<?php
function csv_file_to_mysql_table($source_file, $target_table, $max_line_length=10000) {
    if (($handle = fopen("$source_file", "r")) !== FALSE) {
        $columns = fgetcsv($handle, $max_line_length, ",");
        foreach ($columns as &$column) {
            $column = str_replace(".","",$column);
        }
        $insert_query_prefix = "INSERT INTO $target_table (".join(",",$columns).")\
VALUES";
        while (($data = fgetcsv($handle, $max_line_length, ",")) !== FALSE) {
            while (count($data)<count($columns))
                array_push($data, NULL);
            $query = "$insert_query_prefix (".join(",",quote_all_array($data)).");";
            mysql_query($query);
        }
        fclose($handle);
    }
} 
include "connect_to_mysql.php";
csv_file_to_mysql_table("test2.csv","pic");

What do you mean “put $data there”

FYI, test2.csv:
“ref”,“pic”
“1”,“LAMS-DR6313-110609-110606-39.90-95.94-JPG.jpg”
"2,“LAMS-DR61039-110609-120609-80.99-52.64.PNG.png”
"3,“LAMS-HE08074-110609-120609-69.99-45.49-JPG.jpg”

hmm. So you’ve got 2 fields in your table - ref and pic, and both of them are VARCHAR typed?

$query = "$insert_query_prefix (".join(",",quote_all_array($data)).");";

becomes

$query = "$insert_query_prefix (".join(",",$data).");";

Yes, they are VARCHAR typed.

I made the change, but nothing happened. no errors either

Try adding…
echo mysql_error();

after

        $query = "$insert_query_prefix (".join(",",quote_all_array($data)).");";
        mysql_query($query);

I’m wondering if fgetcsv is stripping the quotation marks.