Question

J'ai un script php qui étapes dans un dossier contenant des fichiers délimités par des tabulations, les analyse ligne par ligne et l'insertion des données dans une base de données MySQL. Je ne peux pas utiliser LOAD TABLE en raison des restrictions de sécurité sur mon serveur et je n'ai pas accès aux fichiers de configuration. Le script fonctionne très bien l'analyse syntaxique 1 ou 2 petits fichiers mais quand lorsque vous travaillez avec plusieurs fichiers volumineux j'obtiens une erreur 500. Il ne semble pas y avoir de journaux d'erreur contenant des messages relatifs à l'erreur, au moins pas que mon hébergeur me donne accès. Voici le code, je suis aussi ouvert aux suggestions pour d'autres moyens de faire ce que je dois faire. En fin de compte, je veux que ce script pour déclencher toutes les 30 minutes environ, insérer de nouvelles données et la suppression des fichiers lorsque vous avez terminé.

EDIT: Une fois les modifications Phil suggéré, le script échoue encore, mais j'ai maintenant le message suivant dans mon journal d'erreur « mod_fcgid: Délai de lecture de données en 120 secondes », ressemble le script est le timing sur, toute idée où je peut modifier le paramètre de délai d'attente?

$folder = opendir($dir);
    while (($file = readdir($folder)) !== false) {
        $filepath = $dir . "/" . $file;

        //If it is a file and ends in txt, parse it and insert the records into the db
        if (is_file($filepath) && substr($filepath, strlen($filepath) - 3) == "txt") {
            uploadDataToDB($filepath, $connection);
        }
    }

function uploadDataToDB($filepath, $connection) {
    ini_set('display_errors', 'On');
    error_reporting(E_ALL);
    ini_set('max_execution_time', 300);

    $insertString = "INSERT INTO dirty_products values(";

    $count = 1;

    $file = @fopen($filepath, "r");

    while (($line = fgets($file)) !== false) {
        $values = "";
        $valueArray = explode("\t", $line);
        foreach ($valueArray as $value) {
            //Escape single quotes
            $value = str_replace("'", "\'", $value);
            if ($values != "")
                $values = $values . ",'" . $value . "'";
            else
                $values = "'" . $value . "'";
        }

        mysql_query($insertString . $values . ")", $connection);
        $count++;
    }

    fclose($file);

    echo "Count: " . $count . "</p>";
}
Était-ce utile?

La solution

La première chose que je ferais est d'utiliser les commandes préparées (en utilisant AOP).

En utilisant la fonction mysql_query(), vous créez une nouvelle déclaration pour chaque insert et vous pouvez dépasser la limite autorisée.

Si vous utilisez une déclaration préparée, une seule déclaration est créé et compilé sur le serveur de base de données.

Exemple

function uploadDataToDB($filepath, $connection) {
    ini_set('display_errors', 'On');
    error_reporting(E_ALL);
    ini_set('max_execution_time', 300);

    $db = new PDO(/* DB connection parameters */);
    $stmt = $db->prepare('INSERT INTO dirty_products VALUES (
                         ?, ?, ?, ?, ?, ?)');
    // match number of placeholders to number of TSV fields

    $count = 1;

    $file = @fopen($filepath, "r");

    while (($line = fgets($file)) !== false) {
        $valueArray = explode("\t", $line);
        $stmt->execute($valueArray);
        $count++;
    }

    fclose($file);
    $db = null;

    echo "Count: " . $count . "</p>";
}

Étant donné que vous voulez exécuter ce script sur un calendrier, il faut éviter le serveur web entièrement et exécutez le script via la CLI en utilisant cron ou quel que soit le service planification de votre hôte fournit. Cela vous aidera à éviter tout délai d'attente configuré dans le serveur Web.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top