0

I am trying to create a CSV Checker which inserts the checked data into a Database and any unsuccessful data added to a .txt file. I am trying to used regular expressions to validate the data I am inserting, the while loop without any validation works and inserts fine but as soon as regular expressions are used it does not work.

<?php
    include_once('connection.php');
    error_reporting(E_ALL);
    date_default_timezone_set('Europe/London');
    $date = date('d/m/y h:i:s a', time());
    $filetxt = "./errors.txt";
    $errors = array();
    $var1 = 5;
    $var2 = 1000;
    $var3 = 10;
    $sql = '';

    if(isset($_POST["Import"]))
    {
        echo $filename=$_FILES["file"]["tmp_name"]; 
        if($_FILES["file"]["size"] > 0)
        {
            $file = fopen($filename, "r");
            while(($emapData = fgetcsv($file, 10000, ",")) !==FALSE)
            {
                if(isset($_GET['strProductCode']))
                {
                    $emapData[0] =  $conn->real_escape_string(trim($_POST['strProductCode']));

                    if (!preg_match("^[a-zA-Z0-9]+$^", $_POST['strProductCode']))
                    {
                        $errors['strProductCode'];
                    }
                }
                if(isset($_GET['strProductName']))
                {
                    $emapData[1] =  $conn->real_escape_string(trim($_GET['strProductName']));
                    if (!preg_match("^[a-zA-Z0-9]+$^", $_POST['strProductName']))
                    {
                        $errors['strProductName'];
                    }
                }
                if(isset($_GET['strProductDesc']))
                {
                    $emapData[2] =  $conn->real_escape_string(trim($_GET['strProductDesc']));
                    if (!preg_match("^[a-zA-Z0-9]+$^", $_POST['strProductDesc']))
                    {
                        $errors['strProductDesc'];
                    }
                }
                if(isset($_GET['intStock']))
                {           
                    if (!preg_match("^[0-9]", $_POST['intStock']))
                    {
                        $errors['intStock'];
                    }
                }
                if(isset($_GET['intPrice']))
                {
                    if (!preg_match("[0-9]", $_POST['intPrice']))
                    {
                        $errors['intPrice'];
                    }
                }
                if(isset($_GET['dtmDiscontinued'])){
                    if($emapData[6] == preg_match("[a-zA-Z]", $_POST['dtmDiscontinued']))
                    {

                        $emapData[6] = $date;
                        echo $date;
                    }else{
                            $emapData[6] = Null;
                        }
                }
                if(count($errors > 0))
                {
                    // errors 
                    $write = "$emapData[0], $emapData[1], $emapData[2], $emapData[3], $emapData[4], $emapData[5], $emapData[6]\r\n";     
                    file_put_contents($filetxt , $write , FILE_APPEND);

                }else{
                    // insert into Database
                        $sql = "INSERT INTO tblproductdata(strProductCode, strProductName, strProductDesc, intStock, intPrice, dtmAdded, dtmDiscontinued) VALUES('$emapData[0]','$emapData[1]','$emapData[2]','$emapData[3]','$emapData[4]','$date','$emapData[6]')";
                    $res=$conn->query($sql);
                    }

            }
            fclose($file);
            echo "CSV File has successfully been Imported";
            echo "<br>";
            echo "Any errors within the CVS Database are reported here.";
            echo "<br>";
            $fh = fopen($filetxt, 'r');
            $theData = fread($fh, filesize($filetxt));
            fclose($fh);
            echo $theData;

        }else{
            echo "Invalid File: Please Upload a Valid CSV File";    
        }
            header("Location: index.php");
    }
?>

My knowledge of PHP is not great but this is my best attempt. Any help would be greatly appreciated.

2
  • Please define "does not work" more closely. At first glance, I see that you often dereference values from the $errors array, but do not use these values (like $errors['intPrice'];). Are these statements maybe meant to be assignments (like $errors['intPrice'] = TRUE; )? Commented Jul 5, 2015 at 21:26
  • Well what I mean by "does not work" is the code does not execute any of the if(isset($_GET['xxxxxxx'])) which in turn does not add any data to the database and only pushes any data processed by the while loop into the .txt which is meant to store lines from the CSV file which do not meet the validation requirements. Commented Jul 5, 2015 at 21:37

1 Answer 1

1

There are several issues in your code. Let's start with the regular expressions and your error checking:

  1. Some of your expressions are invalid. Note that each expression needs a delimiting character at the beginng and ending of the expression. In some of your expressions (like ^[0-9]) these delimiters are missing. Please also note that using ^ as a delimiter for a regular expression is not a good choice, because the ^ character also has a special meaning in regular expressions.

    This should actually cause PHP Warnings. I see that you have error_reporting enabled; you should also have a look at your display_errors setting.

  2. As mentioned in my comment, you do not assign any values to the $errors array. The statement $errors['strProductName'] in itself does not change the array; this means that $errors will always be empty. You probably mean to do something like:

    $errors['strProductName'] = TRUE;
    
  3. You're actually checking count($errors > 0) where you should be checking count($errors > 0). count($errors > 0) translates to either count(TRUE) or count(FALSE) which both equal 1.

Some other notes:

  1. Some times, you check for $_GET['strProductCode'], but then use $_POST['strProductCode'].
  2. You do not reset the $errors array for each iteration. That means that for each line that you read, the $errors variable will still contain the errors from the previous iteration. As a result, the first invalid line will cause all following lines to be recognized as invalid, too.
  3. You register an error when one of the parameters is of an invalid format, but not when one of them is not set at all (i.e. when isset($_POST[...]) is FALSE). Each of them should probably be sth. like this:

    if (isset($_POST['strProductCode'])) {
        $emapData[0] = $conn->real_escape_string(trim($_POST['strProductCode']));
        if (!preg_match("^[a-zA-Z0-9]+$^", $_POST['strProductCode'])) {
            $errors['strProductCode'] = TRUE;
        }
    } else {
        $errors['strProductCode'] = TRUE;
    }
    
Sign up to request clarification or add additional context in comments.

4 Comments

Okay so which would be a better choice of delimiter? would / be a better and acceptable one? I have already amended my code for 2 & 5. They are straight forward. As to 4. Is it a case of choose either $_GET or $_POST? or is the statement for the whole of the if(isset($_GET['strProductCode'])) invalid?
You can use any character as a delimiter; if you use that character inside the expression, you'll have to escape it, though. / seems to be used in most documentation, and it's usually a good choice. Concerning $_GET or $_POST: This depends on how your form is submitted. If it's submitted using a POST request, use $_POST, otherwise use $_GET.
Okay I've taken on board what you have said and it does not come up with any errors now, however the code is still not executing unless I change the if(isset($_POST['strProductCode'])) to if(!isset($_POST['strProductCode'])) and then I get error message saying " Undefined index: strProductCode in C:\wamp\www\x-import\index.php on line 31" etc.. Is the strProductCode and the other columns supposed to be predefined at the top?
Yes, that's probably because you're only triggering an error when a parameter is set and of invalid format, but not when a parameter is not set at all. I've updated my answer accordingly to address this point.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.