0

I've been trying to create a code to allow an user to upload a csv file and define how many lines does he want his new files to be splitted, So i ask to the user the lines per file and to upload the csv file all this by a simple html form.

Actually the file uploads properly and I convert it to an array so I can process it then to split it in several files, for what I have the next code:

First I open my uploaded file and count the rows it has, so I divide this value by the lines the user specified to has in each file, and of course I guarantee this result gets stores as INT and close the file

    $fp = file($personalizado);
    $archivos= intval((count($fp)/$filas)+1);
    fclose($csv_file);

Then I open again the file and process it into an array

    $csv_file=fopen($personalizado,"r");
    while(!feof($csv_file))
    {
        $rows[] = fgetcsv($csv_file, 1000, ';');
    }
    fclose($csv_file);

Later I start the process to read the array and print it in several CSV files

    $z=1; //This will be a number part of the new csv name
    $r=1; //this will count how many lines I've runned
    $file="temp/split ".$z." de ".$archivos.".csv"; //first splitted csv file


    for($i=1;$i<=count($rows);$i++)
    {
        /*This IF resets the $r counter and increase $z to +1, so I start a new file once
          I've runned the total of lines defined by the user*/
        if($r==$filas) 
        {
            $file="temp/split ".$z." de ".$archivos.".csv";
            $z++;
            $r=1;
        }
        $escribe=fopen($file,"w");
        fputcsv($escribe, $rows);
        $r++;
    }
} //this key comes from an upper IF
array_map('fclose', get_resources('stream'));

So for any reason once I move from the form to the php to get my CSV files, it gets stucked and never move to the php file, but the first file gets created but without any info. I've done some other tests where I get all my files but only with 1 random line in each of them. if works for you, this is the full php code:

ob_start();
ini_set('display_errors', '1');
ini_set('display_startup_errors', '1');
error_reporting(E_ALL);
if(isset($_POST['carga']))
{
    $filas=$_POST["filas"];
    //VALIDACION Y CARGA DE ARCHIVO CSV
    $directorio_carga="temp/";
    $personalizado=$directorio_carga."archivo_base.csv";
    if(is_dir($directorio_carga)===false)
    {
        mkdir($directorio_carga,0777,true);
    }   
    $archivo=$directorio_carga.basename($_FILES["archivo_usuario"]["name"]);
    $cargaok=1;
    $escsv=strtolower(pathinfo($archivo,PATHINFO_EXTENSION));
    $formato_valido=array('application/vnd.ms-excel','text/plain','text/csv','text/tsv');
    $nombre_archivo=basename($_FILES["archivo_usuario"]["name"]); 

    if(in_array($_FILES["archivo_usuario"]["type"],$formato_valido))
    {
        $cargaok=1;
    }
    else
    {
        echo "El formato de archivo no es valido ";
        $cargaok=0;
    }
    if($_FILES["archivo_usuario"]["size"]>50000000)
    {
        echo "Archivo demasiado grande, tama&ntilde;o m&aacute;ximo 50MB";
        $cargaok=0;
    }
    if($cargaok==0)
    {
        echo "el archivo no pudo cargarse";
    }
    else
    {
        if(move_uploaded_file($_FILES['archivo_usuario']['tmp_name'],$archivo))
        {
            rename("$archivo","$personalizado");            
            echo "El archivo ".$personalizado." ha sido cargado correctamente \n";
        }
    }
    $fp = file($personalizado);
    $archivos= intval((count($fp)/$filas)+1);
    fclose($csv_file);

    $csv_file=fopen($personalizado,"r");
    while(!feof($csv_file))
    {
        $rows[] = fgetcsv($csv_file, 1000, ';');
    }
    fclose($csv_file);

    $z=1;
    $r=1;
    $file="temp/split ".$z." de ".$archivos.".csv";

    for($i=1;$i<=count($rows);$i++)
    {
        if($r==$filas)
        {
            $z++;
            $file="temp/split ".$z." de ".$archivos.".csv";
            $r=1;
        }
        //echo $i." - ".$file." - ".$rows[$i][0]."- ".$rows[$i][1]."<br>";
        $escribe=fopen($file,"w");
        fputcsv($escribe, $rows);
        $r++;
    }
}
array_map('fclose', get_resources('stream'));
ob_end_flush();

Here is the code fixed and working, thanks to @Barmar for his advice

<?php
ob_start();
ini_set('display_errors', '1');
ini_set('display_startup_errors', '1');
error_reporting(E_ALL);
if(isset($_POST['carga']))
{
    $filas=$_POST["filas"];
    //VALIDACION Y CARGA DE ARCHIVO CSV
    $directorio_carga="temp/";
    $personalizado=$directorio_carga."archivo_base.csv";
    if(is_dir($directorio_carga)===false)
    {
        mkdir($directorio_carga,0777,true);
    }   
    $archivo=$directorio_carga.basename($_FILES["archivo_usuario"]["name"]);
    $cargaok=1;
    $escsv=strtolower(pathinfo($archivo,PATHINFO_EXTENSION));
    $formato_valido=array('application/vnd.ms-excel','text/plain','text/csv','text/tsv');
    $nombre_archivo=basename($_FILES["archivo_usuario"]["name"]); 

    if(in_array($_FILES["archivo_usuario"]["type"],$formato_valido))
    {
        $cargaok=1;
    }
    else
    {
        echo "El formato de archivo no es valido ";
        $cargaok=0;
    }
    if($_FILES["archivo_usuario"]["size"]>50000000)
    {
        echo "Archivo demasiado grande, tama&ntilde;o m&aacute;ximo 50MB";
        $cargaok=0;
    }
    if($cargaok==0)
    {
        echo "el archivo no pudo cargarse";
    }
    else
    {
        if(move_uploaded_file($_FILES['archivo_usuario']['tmp_name'],$archivo))
        {
            rename("$archivo","$personalizado");            
            echo "El archivo ".$personalizado." ha sido cargado correctamente \n";
        }
    }
    $fp = file($personalizado);
    $archivos= intval((count($fp)/$filas)+1);

    $csv_file=fopen($personalizado,"r");
    while(!feof($csv_file))
    {
        $rows[] = fgetcsv($csv_file, 1000, ';');
    }
    fclose($csv_file);

    $z=1;
    $r=1;
    $f=0;
    $file="temp/split ".$z." de ".$archivos.".csv";
    $escribe=fopen($file,"w");
    for($i=1;$i<count($rows);$i++)
    {
        if($r==$filas)
        {
            $z++;
            $file="temp/split ".$z." de ".$archivos.".csv";
            $r=1;
            $escribe=fopen($file,"w");
        }
        fputcsv($escribe, $rows[$i]);
        $r++;
    }
}
array_map('fclose', get_resources('stream'));
ob_end_flush();
?>

This little html will do the data required from user to make the code work (it has bootstrap classes)

        <form name="file" id="file" enctype="multipart/form-data" method="post" action="execute.php">
            <div class="row">
                <div class="col-sm-3"></div>
                <div class="col-sm-6">
                    <div class="card">
                        <div class="card-body" style="text-align:center;">
                            <h2>Segregador de archivos CSV</h2><br>
                            <input type="text" class="form-control" name="filas" placeholder="Especifica cantidad de filas por archivo" required=""><br><br>
                            <input type="file" class="form-control" name="archivo_usuario" required=""><br>
                            <input type="submit" value="Aceptar" name="carga" class="btn btn-success">
                        </div>                  
                    </div>
                </div> 
                <div class="col-sm-3"></div>   
            </div>
            </form>
  • [Why `while(!feof(file))` is always wrong](https://stackoverflow.com/questions/5431941/while-feof-file-is-always-wrong) – Barmar Oct 24 '22 at 23:28
  • `$escribe=fopen($file,"w");` You do this every time through the loop. Opening in `w` mode empties the file. You should only open the file each time the filename changes, not every time through the loop. – Barmar Oct 24 '22 at 23:31
  • 1
    CSV files can have line breaks inside of a field, so naively counting line breaks might not match the number of CSV rows – Chris Haas Oct 25 '22 at 02:58
  • Please trim your code to make it easier to find your problem. Follow these guidelines to create a [minimal reproducible example](https://stackoverflow.com/help/minimal-reproducible-example). – Community Oct 25 '22 at 14:45
  • Hi team, thanks all for your comments. Actually I had 2 mistakes to be fixed. 1. As @Barmar said, I needed to set my fputcsv inside my if so now it prevents to overwrite the first row 2. Also I had to add and index to my array $rows, so I used my $i variable from my for to read the array. Barmar, kindly post your comment as the right answer since this is what helped me to run my code. – adel azeroth Oct 27 '22 at 22:38

0 Answers0