سؤال

لديّ برنامج نصي PHP يخطو عبر مجلد يحتوي على ملفات محددة ، وتوحل خطها سطراً وإدخال البيانات في قاعدة بيانات MySQL. لا يمكنني استخدام جدول التحميل بسبب قيود الأمان على الخادم الخاص بي ولا يمكنني الوصول إلى ملفات التكوين. يعمل البرنامج النصي بشكل جيد في تحليل 1 أو ملفين أصغر ولكن عند العمل مع العديد من الملفات الكبيرة ، أحصل على خطأ 500. لا يبدو أن هناك أي سجلات أخطاء تحتوي على رسائل تتعلق بالخطأ ، على الأقل لا يوجد مزود الاستضافة الخاص بي يتيح لي الوصول إليه. فيما يلي الرمز ، أنا منفتح أيضًا على اقتراحات لطرق بديلة للقيام بما يجب علي فعله. في النهاية ، أريد أن يطلق هذا البرنامج النصي كل 30 دقيقة أو نحو ذلك ، وإدراج بيانات جديدة وحذف الملفات عند الانتهاء.

تحرير: بعد إجراء التغييرات التي اقترحها Phil ، لا يزال البرنامج النصي يفشل ، لكن لدي الآن الرسالة التالية في سجل الأخطاء الخاص بي "mod_fcgid: اقرأ مهلة البيانات في 120 ثانية" ، يبدو أن البرنامج النصي هو توقيت ، أي فكرة حيث يمكنني تغيير إعداد المهلة؟

$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>";
}
هل كانت مفيدة؟

المحلول

أول شيء سأفعله هو استخدام العبارات المعدة (باستخدام PDO).

باستخدام mysql_query() وظيفة ، أنت تقوم بإنشاء بيان جديد لكل إدراج وقد تتجاوز الحد المسموح به.

إذا كنت تستخدم عبارة معد ، يتم إنشاء عبارة واحدة فقط وتجميعها على خادم قاعدة البيانات.

مثال

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>";
}

بالنظر إلى أنك تريد تشغيل هذا البرنامج النصي على جدول زمني ، سأتجنب خادم الويب بالكامل وتشغيل البرنامج النصي عبر CLI باستخدام CRON أو أي خدمة جدولة يوفرها مضيفك. سيساعدك ذلك على تجنب أي مهلة تم تكوينها في خادم الويب.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top