0

i have php code read all pdfs file from path name: pdf_folder/2020/ and send it to my database

i need modify the code to read 3 paths :

  1. pdf_folder/2020/
  2. pdf_folder/2021/
  3. pdf_folder/2022/

my code :

<?php
include('config.php');

        $extentions = array('pdf');

        $dir = new DirectoryIterator('pdf_folder/2020/');
        
       
        //SET Statues to Zero
        $sql5 = "UPDATE pdfs SET status=0";
        $query5 = mysqli_query($con,$sql5);

        foreach($dir as $fileinfo){

            if($fileinfo->isFile()){

                $extention = strtolower(pathinfo($fileinfo->getFilename(), PATHINFO_EXTENSION));

                if(in_array($extention,$extentions)){

                    $name = $fileinfo->getFilename();

                    $sql2 = "SELECT name FROM pdfs WHERE name = '$name' LIMIT 1";
                    $query2 = mysqli_query($con,$sql2);

                    if(mysqli_num_rows($query2) > 0){
                        while($row = mysqli_fetch_assoc($query2)){
                            $name2 =  $row["name"];
                            $sql3 = "UPDATE pdfs SET status=1 WHERE name = '$name2' ";
                            $query3 = mysqli_query($con,$sql3);
                        }
                    }else{
                        $sql4 = "INSERT INTO pdfs(name) VALUES('$name')";
                        $query4 = mysqli_query($con,$sql4);
                    }

                     echo'
                    <a href="/php/test/'.$fileinfo->getFilename().'"> '.$fileinfo->getFilename().'</a><br>
                     ';

                }

            }

        }

I try this code but not working:

<?php

$dirs = scandir('pdf_folder');
$folders_to_process = ['2021', '2022', '2020'];
foreach ($dirs as $folder) {
    if ($folder == '..' || $folder == '.' || !is_dir($folder) || !in_array($folder, $folders_to_process)) continue;

    $extentions = array('pdf');

    $dir = new DirectoryIterator($folder);
  • 3
    considering the code you have so far I'm surprised that you are stuck with an outer loop – Professor Abronsius Sep 02 '22 at 06:18
  • that mean ? please explian – Mosaab Ahmad Sep 02 '22 at 06:21
  • I'll recommend you to run collect the directories to an array, then loop through it. – zaghadon Sep 02 '22 at 06:21
  • 1
    _Side note:_ Read [how to prevent SQL injection in PHP](https://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php) by using prepared statements with bound parameters instead of injecting variables directly into your queries. It's not just about security. If your data contains, for example, a single quote `'`, your query will break. – M. Eriksson Sep 02 '22 at 06:21
  • @zaghadon I don't have enough PHP experience – Mosaab Ahmad Sep 02 '22 at 06:25
  • Where is `$dirfull` defined before you first use it in `foreach($dirfull as $fileinfo){`? – Professor Abronsius Sep 02 '22 at 06:27
  • @ProfessorAbronsius sorry by mistake $dir not $dirfull – Mosaab Ahmad Sep 02 '22 at 06:36
  • @MosaabAhmad I have written an answer that can help you out faster. while my answer can put you on quick, I do hope you'll try to understand how it was solved and become better with PHP. – zaghadon Sep 02 '22 at 06:49
  • 1
    @zaghadon using `scandir` and `DirectoryIterator` together is overkill. Simply use `DirectoryIterator` otherwise you are needlessly scanning directories more than necessary – Professor Abronsius Sep 02 '22 at 07:11
  • Right. I guess a simple loop on the $folder_to_process and concatenating it to the pdf_folder/ is a simpler approach. @ProfessorAbronsius – zaghadon Sep 02 '22 at 07:16
  • What Errors did you get when you tried the code? @MosaabAhmad – zaghadon Sep 02 '22 at 07:19
  • @MosaabAhmad You copied the answer and paste it, you didn't check to see that I reused your code which had its own error, because you're using the `$dirfull` variable which you didn't define anywhere. Change it to `$dir` and try again. Although as pointed out by @ProfessorAbronsius using `scandir()` and `DirectoryIterator` is an Overkill. – zaghadon Sep 02 '22 at 07:26

2 Answers2

1

You should be able to re-factor the code slightly to take advantage of Prepared Statements by creating the statements before you begin inspecting folders. The following uses an array of years to form the outer loop (mentioned) - and on each iteration of that loop the year changes so what was essentially your original code now operates on a different folder.

I have tested the following and it appears to work OK.

<?php

    include('config.php');
    
    # Folders for years of interest to scan
    $years=array(2020,2021,2022);
    
    # for the output
    $li=array();
    
    # Allowed file extensions
    $extensions = array('pdf');
    
    # The various SQL cmds used with placeholders where required for use within prepared statements
    $sql=(object)array(
        'status'    =>  'update `pdfs` set `status`=0',
        'select'    =>  'select `name` from `pdfs` where `name`=? limit 1',
        'update'    =>  'update `pdfs` set `status`=1 where `name` = `name`=?',
        'insert'    =>  'insert into `pdfs` ( `name` ) values ( ? )'
    );
    
    # The prepared statements
    $stmt=(object)array(
        'status'    =>  $con->prepare( $sql->status ),
        'select'    =>  $con->prepare( $sql->select ),
        'update'    =>  $con->prepare( $sql->update ),
        'insert'    =>  $con->prepare( $sql->insert )
    );
    
    # set all PDF status to zero & bind other statements to $name variable
    # in mySQLi this variable does not need exist at this stage, in PDO it does.
    $stmt->status->execute();
    $stmt->select->bind_param('s',$name);
    $stmt->update->bind_param('s',$name);
    $stmt->insert->bind_param('s',$name);
    
    
    
    # iterate through all the years and construct new folder path to scan
    foreach( $years as $year ){
        
        $dir=new DirectoryIterator( sprintf( '%s/pdf_folder/%s', __DIR__, $year ) );
        
        #iterate through the files found
        foreach( $dir as $info ){
            if( !$info->isDot() ){
                
                # is the file extension OK?
                $ext=strtolower( pathinfo( $info->getFilename(), PATHINFO_EXTENSION ) );
            
                if( in_array( $ext, $extensions ) ){
                    
                    # the $name variable is now populated for the SQL prepared statements to execute.
                    $name=$info->getFilename();
                    
                    $stmt->select->execute();
                    $stmt->select->store_result();
                    
                    if( $stmt->select->num_rows > 0 ){
                        $stmt->update->execute();
                    }else{
                        $stmt->insert->execute();
                    }
                    
                    $li[]=sprintf('<li><a href="/pdf_folder/%2$d/%1$s" target="_blank">%1$s</a></li>', $name, $year );
                }
            }
        }
    }
    
    # print the HTML list of hyperlinks
    printf('<ul>%s</ul>',implode(PHP_EOL,$li));
Professor Abronsius
  • 33,063
  • 5
  • 32
  • 46
0

You can use the scandir() function to collect the pdf_folder to an array, then loop through it and do your existing operation after checks.

For instance, this would help:

<?php

$dirs = scandir('pdf_folder');
$folders_to_process = ['2021', '2022', '2020'];
foreach ($dirs as $folder) {
    if ($folder == '..' || $folder == '.' || !is_dir($folder) || !in_array($folder, $folders_to_process)) continue;

    $extentions = array('pdf');

    $dir = new DirectoryIterator($folder);


    //SET Statues to Zero
    $sql5 = "UPDATE pdfs SET status=0";
    $query5 = mysqli_query($con, $sql5);

    foreach ($dir as $fileinfo) {

        if ($fileinfo->isFile()) {

            $extention = strtolower(pathinfo($fileinfo->getFilename(), PATHINFO_EXTENSION));

            if (in_array($extention, $extentions)) {

                $name = $fileinfo->getFilename();

                $sql2 = "SELECT name FROM pdfs WHERE name = '$name' LIMIT 1";
                $query2 = mysqli_query($con, $sql2);

                if (mysqli_num_rows($query2) > 0) {
                    while ($row = mysqli_fetch_assoc($query2)) {
                        $name2 =  $row["name"];
                        $sql3 = "UPDATE pdfs SET status=1 WHERE name = '$name2' ";
                        $query3 = mysqli_query($con, $sql3);
                    }
                } else {
                    $sql4 = "INSERT INTO pdfs(name) VALUES('$name')";
                    $query4 = mysqli_query($con, $sql4);
                }

                echo '
                    <a href="/php/test/' . $fileinfo->getFilename() . '"> ' . $fileinfo->getFilename() . '</a><br>
                     ';
            }
        }
    }
}
zaghadon
  • 613
  • 1
  • 7
  • 20