Search code examples
phpfilefopenfile-manager

Problem in reading files with php fopen and in making file manager


I am trying to make a file manager with php , so when I open it in browser it would give a list of the current directory and the file would be clickable using the anchor tag in html (which I have done so far) , and when the file is clicked , it would open it in the text mode and shows whatever the source code inside the file is.

I am facing two problems which I couldn't figure out

Problem #1:

The first problem is that I want my file manager to read any source code weather its an image or pdf , just like the tinyfilemanager that I found here this master piece can read any file, even if you open an image with a notepad and insert some php code at the very end of the file it will read render that too, so here's my source code:

<?php
function list_all_files($directory){
//opening the dir
    if($handle=opendir($directory.'/')){
        echo "looking inside '$directory'"."<br>";
    }

    while($file=readdir($handle)){
        //listing all the directories without ".." (dots)
        if($file!='.'&&$file!='..') {

            echo '<a href="Read.php?dir='.$directory.'&read='.$directory.'/'.$file.'">'.$file.'</a><br>';
        } //if ends here
    } //while loop endds here
} //list_all_files ends here


function read_file($file)
{
    $handle = fopen($file, "r");
    if ($handle) {
        while (($line = fgets($handle)) !== false) {
            echo($line);
        }
        fclose($handle);
    } else {
        echo "error opening the file";
    }
}


//main function
if(!isset($_GET['dir'])) {
    $dir='images';
}else{
    $dir=$_GET['dir'];
}

list_all_files($dir);

if(isset($_GET['read'])){
    $file1 = $_GET['read'];
    read_file($file1);
}

?>

the above program I made can also read files code but when I click on any PHP file that contains an html code, it just displays it rather than giving its source code in text mode, image below:

its Rendering and displaying html

and not only this, if I put some php code at the very end of the image file using a notepad it wouldn't display it. check this:

php code in the image file

output of the php code

I did a lot of research on why my code isn't working while the tinyFilemanager is perfect with any of the above mention cases , and I found that the whenever I execute the page file via browser it by default uses this

header("Content-Type: text/html");

so If I wanted to do what I wanted , then I would have to use this:

header("Content-Type: text/x-php");

which covers both of the above cases, but leads to the 2nd problem.

Problem #2:

<?php
function list_all_files($directory){
//opening the dir
if($handle=opendir($directory.'/')){
echo "looking inside '$directory'"."<br>";
}

while($file=readdir($handle)){
    //listing all the directories without ".." (dots)
    if($file!='.'&&$file!='..') {

    echo '<a href="Read.php?dir='.$directory.'&read='.$directory.'/'.$file.'">'.$file.'</a><br>';
            } //if ends here
        } //while loop endds here
} //list_all_files ends here


function read_file($file)
{
    $handle = fopen($file, "r");
    if ($handle) {
        while (($line = fgets($handle)) !== false) {
            echo($line);
        }
        fclose($handle);
    } else {
       echo "error opening the file";
    }
}


//main function
if(!isset($_GET['dir'])) {
    $dir=getcwd();
}else{
    $dir=$_GET['dir'];
}

//listing all the directories and files in text/html format so that our anchor tag would be available.
ob_start();
header('Content-Type: text/html; charset=UTF-8');
list_all_files($dir);
ob_end_flush();



if(isset($_GET['read'])){
//changing the header to text/php-x so that the php code in any jpg file can be viewed clearly
    ob_clean();
    header('Content-Type: text/x-php; charset=UTF-8');
    ob_start();
    $file1 = $_GET['read'];
    read_file($file1);
    ob_end_flush();
}

?>

The above codes works perfectly fine, but there is this one problem. since its content-type is not text/html anymore, it wouldn't display the html content on the web page. which is good but bad at the same time because then I wouldn't get the list of directory in the anchor tag form, because I thought ob_start and ob_end_flush(). if I use these two, it would just solve the problem by creating a buffer for each of the function separately and executes it. so when it executes it the above function would be render with the content-type text/html and would show the directory listing with anchor tag, and the 2nd would just be in text/x-php which would solve the above two cases, but I was soooooo wrong.


Solution

  • With the grace and help of God , and suggestion from kikoSoftware in the Comments , the Problem is solved, there's a function name show_source(); ,which takes two arguement , the 2nd argument however is optional , hence we don't need to do filing or send a content-type response with the header() function , we can just use that function , source codes are below.

    <?php
    function list_all_files($directory){
    //opening the dir
        if($handle=opendir($directory.'/')){
            echo "looking inside '$directory'"."<br>";
        }
    
        while($file=readdir($handle)){
            //listing all the directories without ".." (dots)
            if($file!='.'&&$file!='..') {
    
                echo '<a href="Read.php?dir='.$directory.'&read='.$directory.'/'.$file.'">'.$file.'</a><br>';
            } //if ends here
        } //while loop endds here
    } //list_all_files ends here
    
    
    function read_file($file)
    {
        $handle = fopen($file, "r");
        if ($handle) {
            while (($line = fgets($handle)) !== false) {
                echo($line);
            }
            fclose($handle);
        } else {
            echo "error opening the file";
        }
    }
    
    
    //main function
    if(!isset($_GET['dir'])) {
        $dir=getcwd();
    }else{
        $dir=$_GET['dir'];
    }
    
    //listing all the directories and files in text/html format so that our anchor tag would be available.
    list_all_files($dir);
    
    
    
    
    if(isset($_GET['read'])){
    //changing the header to text/php-x so that the php code in any jpg file can be viewed clearly
    
        $file1 = $_GET['read'];
        show_source($file1);
    }
    
    ?>
    

    the image

    appreciate ya guys for helping out ♥