2016-12-28 5 views
2

Diese Frage bezieht sich auf this one und ich zäh das Problem wurde behoben, aber überraschend ist nicht. Ich werde den gleichen Code schreiben wieder (Ich habe Kommentare und Teile des Codes entfernt, dies ist nur ein allgemeines Beispiel) nur für diesen Beitrag verständlich machen.Was könnte den Server zum Senden einer gültigen Antwort stoppen?

Derzeit ist dies der Code, den ich in einem Zend Framework 1-Controller haben:

public function uploadAction() 
{ 
    $this->_helper->viewRenderer->setNoRender(); 
    $data = $errors = $line_of_text = []; 

    if ($this->getRequest()->isPost()) { 
     $path = '/cronjobs/uploads/charge_type_details'; 

     if ([email protected]($path, 0777, true) && !is_dir($path)) { 
      $data['error'][] = "Not able to create subdirectory: <strong>{$path}</strong>"; 
      echo json_encode($data); 

      die(); 
     } 

     $di = new RecursiveDirectoryIterator($path, FilesystemIterator::SKIP_DOTS); 
     $ri = new RecursiveIteratorIterator($di, RecursiveIteratorIterator::CHILD_FIRST); 
     foreach ($ri as $file) { 
      $file->isDir() ? rmdir($file) : unlink($file); 
     } 

     $adapter = new Zend_File_Transfer_Adapter_Http(); 
     $adapter->setDestination($path); 
     $adapter->addValidator('Extension', false, ['extension' => 'csv', 'case' => true]); 
     $adapter->addValidator('MimeType', false, 'text/plain'); 
     $adapter->addValidator('Size', false, ['max' => ini_get('upload_max_filesize').'B']); 

     if ($adapter->isValid() === false) { 
      foreach ($adapter->getMessages() as $message) { 
       $data['error'][] = $message; 
      } 

      echo json_encode($data); 

      die(); 
     } 

     $file  = $adapter->getFileInfo()['file']; 
     $ext  = pathinfo($file['name'])['extension']; 
     $new_path = $file['tmp_name']; 

     $file_handle = fopen($new_path, 'r'); 

     while (($result = fgetcsv($file_handle)) !== false) { 
      if (array(null) !== $result) { // ignore blank lines 
       $line_of_text[] = $result; 
      } 
     } 

     $unique_rows = array_unique($line_of_text, SORT_REGULAR); 

     if (false === $this->isFileHeadersValid(
       array_map('strtolower', $unique_rows[0]), 
       [ 
        'country', 
        'charge_type', 
        'charge_type_code', 
        'business_sla_description', 
        'service_provider', 
        'sub_menu', 
        'charge_type_group', 
        'transaction_type', 
        'slc_code', 
        'coverage_code', 
        'standard_sla', 

       ] 
      ) 
     ) { 
      $data['error'][] = $this->translate->_('Required file headers are not present. Please check the file and try again.'); 
      echo json_encode($data); 

      die(); 
     } 

     unset($unique_rows[0]); 

     $data['error'] = $errors; 

     $data['file'] = array(
      'name'  => $file['name'], 
      'size'  => $adapter->getFileSize(), 
      'file_ext' => $ext 
     ); 
    } else { 
     $data['error'] = 'Invalid request.'; 
    } 

    echo json_encode($data); 

    die(); 
} 

Diese Funktion von Javascript als AJAX-Funktion wird aufgerufen:

$('#fileupload').show().fileupload({ 
    url: '/upload', 
    cache: false, 
    dataType: 'json', 
    done: function (e, data) { 
     if (data.result.error.length > 0) { 
      // process errors here 
     } else { 
      // do something here 
     } 
    } 
}) 

Ich lade eine Datei mit etwa 1,5 MB Größe und etwa 9000 Zeilen (es ist eine CSV-Datei).

Sobald ich diese Datei hochlade, scheint alles zu funktionieren und dies bedeutet, dass die Codeausführung auf der PHP-Seite bis zum letzten echo json_encode($data); ohne "errors" geht. Ich wusste das, weil ich Xdebug verwende, um den Code auf der IDE zu debuggen.

Aus irgendeinem Grund die Antwort nicht zurück zum Browser und ich am Ende mit der folgenden Nachricht: "Fehler beim Laden der Antwort" und ich bin nicht in der Lage, die Antwort richtig zu verarbeiten.

enter image description here

enter image description here

enter image description here

ich das Ergebnis von json_encode($data), indem sie einem var und alles Zuordnung scheint nach dieser Ausgabe (die Dateinamen auf die Bilder und diese in Ordnung zu sein geprüft haben Beispiel sind unterschiedlich, aber dies ist nur für die gezeigte Funktionalität):

{ 
    "error": [], 
    "file": { 
    "name": "test1.csv", 
    "size": "1.24kB", 
    "file_path": "/data/tmp/php/uploads/phpSh2tZt", 
    "file_ext": "csv", 
    "delimiter": "", 
    "worksheets": [] 
    } 
} 

Ich habe den Vorgang in Chrome und Firefox überprüft und es gibt keine Status auf die Antwort gesendet, wie Sie auf den Bildern oben sehen können. Warum? Ich weiß nicht, was ich noch tun soll, um das Problem zu beheben, ich weiß nicht, woher der Fehler kommt (es ist nicht von PHP-Code, weil wie gesagt alles auf Code-Ebene funktioniert und Protokolle so geschrieben haben) und ich bin es feststecken an diesem Punkt, kann mir irgendwer irgendwelche Ideen oder Hinweise dazu geben?

Meine Umgebung läuft in Docker, wenn das hilft.

Die PHP-Konfiguration ist wie folgt:

memory_limit = 2048M 
post_max_size = 128M 
upload_max_filesize = 128M 
date.timezone = UTC 
max_execution_time = 120 
short_open_tag=On 
serialize_precision=100 
session.gc_maxlifetime=7200 
session.entropy_length=0 

PS: Wenn Sie jede Art von Informationen benötigen lassen Sie mich wissen und ich werde es zum OP hinzufügen

UPDATE

Ich habe gerade herausgefunden, wo das Problem liegt und ich bin neugierig auf das "Warum". Mit dem folgenden Stück Code:

Macht den vollständigen Code zu fehlschlägt, indem Sie die Antwort nicht auf den Browser erhalten.Das Verschieben der Validierung weg macht den Code richtig funktioniert:

$adapter = new Zend_File_Transfer_Adapter_Http(); 
$adapter->setDestination($path); 

Was könnte falsch sein da? Ich vermisse etwas hier?

UPDATE 2

Dies ist derzeit, wie der Code wie folgt aussieht:

.... 
$adapter = new Zend_File_Transfer_Adapter_Http(); 
$adapter->setDestination($path); 
$adapter->addValidator('Extension', false, ['extension' => 'csv', 'case' => true]); 
$adapter->addValidator('MimeType', false, ['text/plain', 'text/csv']); 
$adapter->addValidator('Size', false, ['max' => $this->SizeToBytes(ini_get('upload_max_filesize'))]); 

if ($adapter->receive() === false || $adapter->isValid() === false) { 
    foreach ($adapter->getMessages() as $message) { 
     $data['error'][] = $message; 
    } 

    echo json_encode($data); 

    return true; 
} 
.... 
private function SizeToBytes($val) 
{ 
    $val = trim($val); 
    $last = strtolower($val[strlen($val) - 1]); 
    switch ($last) { 
     case 'g': 
      $val *= 1024; 
     case 'm': 
      $val *= 1024; 
     case 'k': 
      $val *= 1024; 
    } 

    return $val; 
} 

Dies entweder nicht funktioniert. Der einzige Weg, ich habe diese zur Arbeit war bewegend zu „Vanille“ PHP wie folgt:

// Validate file mimetype 
if (!in_array($adapter->getMimeType(), ['text/plain', 'text/csv'])) { 
    $data['error'][] = $this->translate->_('File is not valid only CSV files are accepted!'); 
    echo json_encode($data); 

    return true; 
} 

// Validate file extension 
if ($ext !== 'csv') { 
    $data['error'][] = $this->translate->_('File extension is not valid only CSV files are accepted!'); 
    echo json_encode($data); 

    return true; 
} 

// Validate file size depending on php.ini upload_max_filesize configuration 
$max = $this->SizeToBytes(ini_get('upload_max_filesize')); 
if ($file['size'] > $max) { 
    $data['error'][] = $this->translate->_e('File size is not valid! The size should be less than: ').ini_get('upload_max_filesize').'B'; 
    echo json_encode($data); 

    return true; 
} 

diese Weise ist es wie ein Zauber funktioniert.

+0

Wenn Sie mit Xdebug können Sie nicht durch sie Schritt und sehen, an welchem ​​Punkt ist es in dem Validierungscode zu stoppen? – mickadoo

+0

@mickadoo ja, ich habe Xdebug aber Code läuft leicht bis zum Ende der Ausführung ohne Fehler, das ist ungerade – ReynierPM

+0

Hmm, aber Sie sagten, mit dem Prüfcode es scheitert. Funktioniert es 100% ohne den Validierungscode - erhalten Sie eine korrekte Antwort im Browser? – mickadoo

Antwort

0

Sie verwenden eine viel kleinere maximale Größe (128 Bytes), als Sie beabsichtigten.

Sie sollten Ihre ini definierte upload_max_filesize in den vollständigen ganzzahligen Wert (~ 128000000) konvertieren.

Zum Beispiel:

$adapter->addValidator('Size', false, ['max' => 128000000]); 
+0

Dies hat nicht funktioniert – ReynierPM

0

In Bezug auf die Status & die "Warum":

Ich denke, mit http_response_code(200) auf der Seite Verarbeitung Ajax Antwort helfen kann.

+0

Ich glaube nicht, dass dies eine gute Lösung ist, da die Anfrage tatsächlich fehlschlagen könnte – ReynierPM

0

Sollten Sie nicht irgendwo "$ adapter-> receive()" aufrufen?

https://framework.zend.com/manual/1.11/en/zend.file.transfer.introduction.html

$adapter = new Zend_File_Transfer_Adapter_Http(); 

$adapter->setDestination('C:\temp'); 

if (!$adapter->receive()) { 
    $messages = $adapter->getMessages(); 
    echo implode("\n", $messages); 
} 
+0

Überprüfen Sie für ** UPDATE 2 ** da ist deine Antwort ... Ich benutze '$ adapter-> receive() === false' ... – ReynierPM

Verwandte Themen