0

I'm working on file import feature from an Excel file. During the import, I'm using PhpSpreadSheet library to convert this file to CSV format. Next, my function extractData() will loop csv file, detect specific headers, combine data corresponding to them, and insert them into database.

My configuration on these machines :

  • Dev Machine :

    1. Debian 9
    2. PHP 7.3.2
  • Local Machine :
    1. Debian 8
    2. PHP 7.3.2

My algorithm is working well on my local machine, but when I'm testing it on my development machine, it sends me back these errors :

PHP Warning: array_combine() expects parameter 2 to be array, null given

PHP Warning: array_intersect_key(): Expected parameter 1 to be an array, null given

Is PHP more stable on Debian 8 and not enough on Debian 9 ?

How can I fix this problem?

Example of CSV :

enter image description here

const PATTERNS = [
        'fullName' => '/^(?:noms?\/pré?e?noms?)/ui',
        'lastName' => '/^(?:votre nom|nom)/ui',
        'firstName' => '/^(?:votre prénom|prénom|prénoms)/ui',
        'zipcode' => '/^(?:secteur|commune|zone|ville hbt|Dans quelle zone géographique habitez-vous \?)/ui',
        'birthday' => '/^(?:votre date de naissance|Date de naissance|En quelle année êtes-vous née?)/ui',
        'gender' => '/^(?:votre sexe|sexe)/ui',
        'contact' => '/^(?:contact tel\/mail|contacts?)/ui',
        'postalAddress' => '/^(?:adresse|zone hbt|secteur d\'habitation)/ui',
        'phoneNumber' => '/^(?:votre numéro de téléphone|Téléphone|n° de téléphone|contact tel|tel)/ui',
        'employment' => "/^(?:votre profession|votre métier|profession|métier|dans quel(?:\(s\))? secteur(?:\(s\))? d'activité exercez-vous cette activité \?|secteur d'activité)/ui",
        'email' => '/^(?:votre adresse e-mail|votre adresse mail|votre mail|votre email|e-mail|mail)/ui',
        'ratings' => '/^(?:appréciation)/ui',
        'comments' => '/^(?:commentaires?|remarque)/ui',
    ];

function extractData($file, $cnx)
{
    $headers = [];
    $state = 0;
    $flag = true;

    if(($handle = fopen($file, 'r')) !== FALSE) 
    {
        foreach (fgetcsv($handle, 1000, ";") as $key => $header) 
        {
            foreach (PATTERNS as $symbol => $pattern) 
            {
                if (!in_array($symbol, $headers) && preg_match($pattern, $header)) 
                {
                    $headers[$key] = $symbol;
                    break;
                }
            }
        }
        // Loop file from lign 2 to more
        while ($line = fgetcsv($handle, 1000, ";")) 
        {
            $line = array_combine($headers, array_intersect_key($line, $headers));
            if($line['lastName'] === "" || $line['firstName'] === "")
            {
                continue;
            }

            if($line['fullName'] !== NULL)
            {
                $formatNames = formatNames($line['fullName']);
                $line['lastName'] = $formatNames[0];
                $line['firstName'] = $formatNames[1];
            }

            if($line['contact'] !== NULL)
            {
                $formatContact = formatContact($line['contact']);
                $line['phoneNumber'] = $formatContact[0];
                $line['email'] = $formatContact[1];
            }

            $lastName = $line['lastName'] !== NULL ? $line['lastName'] : "";
            $firstName = $line['firstName'] !== NULL ? $line['firstName'] : "";
            $formatZipcode = translateZipcode($line['zipcode']);
            $zipcode = $formatZipcode !== NULL ? $formatZipcode : "";
            $birthday = $line['birthday'] !== NULL ? $line['birthday'] : "";
            $gender = $line['gender'] !== NULL ? $line['gender'] : "";
            $postalAddress = $line['postalAddress'] !== NULL ? $line['postalAddress'] : "";
            $formatPhoneNumber = formatPhoneNumber($line['phoneNumber']);
            if($line['contact'] !== NULL)
            {
                $phoneNumber = $line['phoneNumber'] !== NULL ? $line['phoneNumber'] : "";
            }
            else
            {
                $phoneNumber = $formatPhoneNumber !== NULL ? $formatPhoneNumber : "";
            }
            $availableDays = $line['availableDays'] !== NULL ? $line['availableDays'] : "";
            $employment = $line['employment'] !== NULL ? $line['employment'] : "";
            $transportMeans = $line['transportMeans'] !== NULL ? $line['transportMeans'] : "";
            $candidacyType = $line['candidacyType'] !== NULL ? $line['candidacyType'] : "";
            $email = $line['email'] !== NULL ? $line['email'] : "";

            $query = $cnx->prepare('INSERT INTO candidacies (lastName, firstName, zipcode, birthday, gender, postalAddress, phoneNumber, availableDays, employment, transportMeans, candidacyType, email, candidacies_UserId, candidacy_CreatedAt, state) VALUES (:lastName, :firstName, :zipcode, :birthday, :gender, :postalAddress, :phoneNumber, :availableDays, :employment, :transportMeans, :candidacyType, :email, :candidacies_UserId, NOW(), :state)'); 
            $query->bindValue(':lastName', $lastName, PDO::PARAM_STR);
            $query->bindValue(':firstName', $firstName, PDO::PARAM_STR);
            $query->bindValue(':zipcode', $zipcode, PDO::PARAM_STR);
            $query->bindValue(':birthday', $birthday, PDO::PARAM_STR);
            $query->bindValue(':gender', $gender, PDO::PARAM_STR);
            $query->bindValue(':postalAddress', $postalAddress, PDO::PARAM_STR);
            $query->bindValue(':phoneNumber', $phoneNumber, PDO::PARAM_STR);
            $query->bindValue(':availableDays', $availableDays, PDO::PARAM_STR);
            $query->bindValue(':employment', $employment, PDO::PARAM_STR);
            $query->bindValue(':transportMeans', $transportMeans, PDO::PARAM_STR);
            $query->bindValue(':candidacyType', $candidacyType, PDO::PARAM_STR);
            $query->bindValue(':email', $email, PDO::PARAM_STR);
            $query->bindValue(':candidacies_UserId', $_SESSION['user']->userId, PDO::PARAM_INT);
            $query->bindValue(':state', "In progress", PDO::PARAM_STR);

            if($query->execute())
            {
                $state = 1;
            }

            $query = $cnx->prepare('SELECT MAX(candidacyId) AS id FROM candidacies');
            $query->execute();

            $getCandidacyId = $query->fetch(PDO::FETCH_OBJ);

            if($line['comments'] !== NULL)
            {
                $comments = $line['comments'];
                if($comments === "")
                {
                    continue;
                }

                $query = $cnx->prepare('INSERT INTO comments (comments, comment_CreatedAt, comments_UserId, comments_CandidaciesId) VALUES (:comments, NOW(), :comments_UserId, :comments_CandidaciesId)');
                $query->bindValue(':comments', $comments, PDO::PARAM_STR);
                $query->bindValue(':comments_UserId', $_SESSION['user']->userId, PDO::PARAM_INT);
                $query->bindValue(':comments_CandidaciesId', $getCandidacyId->id, PDO::PARAM_INT);

                if($query->execute())
                {
                    $state = 1;
                }
            }

            $query = $cnx->prepare('SELECT MAX(commentsId) AS id FROM comments');
            $query->execute();

            $getCommentId = $query->fetch(PDO::FETCH_OBJ);

            if($line['ratings'] !== NULL)
            {  
                $ratings = formatRatings($line['ratings']);

                if($ratings === "")
                {
                    continue;
                }

                $query = $cnx->prepare('INSERT INTO ratings (ratings, rating_CreatedAt, ratings_UserId, ratings_CandidacyId, ratings_CommentId) VALUES (:ratings, NOW(), :ratings_UserId, :ratings_CandidacyId, :ratings_CommentId)');
                $query->bindValue(':ratings', $ratings, PDO::PARAM_INT);
                $query->bindValue(':ratings_UserId', $_SESSION['user']->userId, PDO::PARAM_INT);
                $query->bindValue(':ratings_CandidacyId', $getCandidacyId->id, PDO::PARAM_INT);
                $query->bindValue(':ratings_CommentId', $getCommentId->id, PDO::PARAM_INT);

                if($query->execute())
                {
                    $state = 1;
                }
            }
        }
        fclose($handle);

        return $state;
    }
}


if(extractData($loadedSheetName.'.csv', $cnx) === 1)
{
     $_SESSION['flash']['uploadFile'] = "<div class='alert alert-success'>Success !</div>";
     header('Location: ../listCandidacies.php');
}
else
{
     $_SESSION['flash']['uploadFile'] = "<div class='alert alert-danger'>Error !</div>";
     exit(0);
}
Maestro
  • 865
  • 1
  • 7
  • 24
  • Can you give a sample of the CSV file, your code seems to do a lot and the context of seeing the input file would help. – Nigel Ren Jun 14 '19 at 06:48
  • @NigelRen yeah sure, I'll edit my question ! – Maestro Jun 14 '19 at 06:53
  • Your code needs proper error checking. For instance: You get the headers from the first line of the CSV file, but you never check that you actually have some headers before you proceed. – KIKO Software Jun 14 '19 at 06:54
  • 1
    Your development machine has error reporting turned on, hence why you get the warnings. You could probably ignore them, or turn error reporting off, but it would be better to fix the cause of these problems. The cause appears to be data not existing in the expected format. – Jeemusu Jun 14 '19 at 06:55
  • Oh so before looping into csv lines, I need to check if my headers array is not empty, right? @KIKOSoftware – Maestro Jun 14 '19 at 07:04
  • Yes, that's the idea. Your code relies on external input (the Excel file), which can be unpredictable, so you should always check you get what you expect. If not, show a nice error message like: "Could not find any recognizable headers on the first line of the Excel file". But I think that Jeemusu found the reason why you saw warnings on one machine and not on the other. – KIKO Software Jun 14 '19 at 07:08
  • The problem seems to be on this line: `$line = array_combine($headers, array_intersect_key($line, $headers));`. The headers from CSV you posted and the available options in the $PATTERNS don't seem to have any commonality? Is this code you have copied from somewhere? – Jeemusu Jun 14 '19 at 07:08
  • @Jeemusu, yeah exactly, it's this line causing these errors unfortunately. This code was merged with my git branch, but I developped it by myself – Maestro Jun 14 '19 at 07:15
  • The error says parameter one (`$line`) is null. Do you possibly have an empty line in or at the end of your csv? – Jeemusu Jun 14 '19 at 07:18
  • When i do a print_r($line), I get this: multiple 1 – Maestro Jun 14 '19 at 07:20
  • if you `print_r($headers) ;` does it return the correct data? The problem seems to be with reading the CSV after line 1. I don't really see a problem with your code, so it would point to the CSV file being badly formatted. Can you try opening the CSV file in excel/open office, or another application and check that data looks correct? Make sure there is no empty rows or extra whitespace. – Jeemusu Jun 14 '19 at 07:23
  • Result of print_r($headers): multiple array corresponding to my PATTERNS array Array ( [0] => lastName [1] => firstName [2] => gender [3] => zipcode [5] => phoneNumber [6] => email [20] => ratings [21] => comments ) – Maestro Jun 14 '19 at 07:25
  • I tested your code locally and it works fine with a standard comma delimited CSV. – Jeemusu Jun 14 '19 at 07:36
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/194928/discussion-between-maestro-and-jeemusu). – Maestro Jun 14 '19 at 07:38

0 Answers0