Jump to content

Recommended Posts

I'm seeking to change a download counter script:
http://www.phpkode.com/source/s/dscript-php-file-download-counter/dscript-php-file-download-counter/Includes/functions.php so that it sorts by descending date order of filename as seen by the server instead of sorting in descending alphanumeric order of filename as now.

The script counts downloads for files stored on a server, saves the download counts in a log file, then using an array built from the log file, outputs the download count for each file to a web page.

This is the function I believe needs to change

    // Function to read the log file, and return an array as (filename =>        downloads)
    function read_log()
    {
    global $path;
    // Declare Array for holding data read from log file
    $name = array(); // array for file name
    $count = array(); // array for file count

    $file = @file("$path/Includes/log");
    if(empty($file))
    {
    return null;
    }
		
    // Read the entire contents of the log file into the arrays 
    $file = fopen("$path/Includes/log","r");
    while ($data = fscanf($file,"%[ -~]\t%d\n")) 
    {
    list ($temp1, $temp2) = $data;	
    array_push($name,$temp1);
    array_push($count,$temp2);
    }
    fclose($file);
    // $file_list contains data read from the log file as an array (filename => count)
    $file_list=@array_combine($name,$count); 
    ksort($file_list); // Sorting it in alphabetical order of key
    return $file_list;
    }



The log file syntax is file name then a TAB then download count (0 or higher).

New files are added frequently which the script has to count. I need the latest added file to be at the top of the web page but I now need to change the file names of new files which causes them not to come to the top of the list if sorted as now.

I looked at these

http://stackoverflow.com/questions/16733128/sort-array-by-date-in-descending-order-by-date-in-php

http://stackoverflow.com/questions/6401714/php-order-array-by-date

https://stackoverflow.com/questions/3302900/how-to-sort-output-from-several-log-files-by-date

but I don't get a specific enough idea of what I must change in the script above the lines where ksort is invoked.
 

** Edit ** 

I've just had a reread of your question, what data is stored in each log file? Is there a timestamp for each log file or is a new logfile created for each log entry?

 

The following code will need to be adjusted after the above is answered...

    // Function to read the log file, and return an array as (filename =>        downloads)
    function read_log()
    {
        global $path;
        // Declare Array for holding data read from log file
        $name = array(); // array for file name
        $count = array(); // array for file count
        $file_list = array();
        $logPath = "$path/Includes/log";
        $file = fopen($logPath,"r");
        $file = @file($logPath);
        if(empty($file))
        {
        return null;
        }
    
        // Read the entire contents of the log file into the arrays 
        while ($data = fscanf($file,"%[ -~]\t%d\n")) 
        {
            list ($name, $count) = $data;
            $file_list[] = array('name'=>$name,
                                 'count'=>$count,
                                 'modifiedTime'=>filemtime("$logPath/$name"));
        }
        fclose($file);
        // $file_list contains data read from the log file as an array (filename => count)
        
        usort($file_list,'compareFileModifiedTimes');
        return $file_list;
    }
    
    function compareFileModifiedTimes($array1,$array2)
    {
        return strtotime($array1['modifiedTime']) > strtotime($array2['modifiedTime']);
    }

It's using the PHP usort method and I've restructured a bit of your code to make it more readable.. (i.e. removing the two arrays (name/count) and just using one from the start).

I've not tested it yet though ensure you turn on error_reporting if you experience any errors.

Edited by joel24

Hi Joel24 - many thanks for your reply.

 

There is only a single log file.

 

When a new file for download is added to the download location, the script adds a new line for that file at the bottom of the log.

 

Each time any file is downloaded, the log is updated with the new count for that file.

 

Each line in the log has the form

 

<file name>TAB<download count>

 

** Edit ** 

I've just had a reread of your question, what data is stored in each log file? Is there a timestamp for each log file or is a new logfile created for each log entry?

 

The following code will need to be adjusted after the above is answered...

    // Function to read the log file, and return an array as (filename =>        downloads)
    function read_log()
    {
        global $path;
        // Declare Array for holding data read from log file
        $name = array(); // array for file name
        $count = array(); // array for file count
        $file_list = array();
        $logPath = "$path/Includes/log";
        $file = fopen($logPath,"r");
        $file = @file($logPath);
        if(empty($file))
        {
        return null;
        }
    
        // Read the entire contents of the log file into the arrays 
        while ($data = fscanf($file,"%[ -~]\t%d\n")) 
        {
            list ($name, $count) = $data;
            $file_list[] = array('name'=>$name,
                                 'count'=>$count,
                                 'modifiedTime'=>filemtime("$logPath/$name"));
        }
        fclose($file);
        // $file_list contains data read from the log file as an array (filename => count)
        
        usort($file_list,'compareFileModifiedTimes');
        return $file_list;
    }
    
    function compareFileModifiedTimes($array1,$array2)
    {
        return strtotime($array1['modifiedTime']) > strtotime($array2['modifiedTime']);
    }

It's using the PHP usort method and I've restructured a bit of your code to make it more readable.. (i.e. removing the two arrays (name/count) and just using one from the start).

I've not tested it yet though ensure you turn on error_reporting if you experience any errors.

In that case, you won't be able to see the timestamp for each filename download count... though you can easily order it if they're added in chronological order.

    // Function to read the log file, and return an array as (filename =>        downloads)
    function read_log()
    {
        global $path;
        // Declare Array for holding data read from log file
        $name = array(); // array for file name
        $count = array(); // array for file count
        $file_list = array();
        $logPath = "$path/Includes/log";
        $file = fopen($logPath,"r");
        $file = @file($logPath);
        if(empty($file))
        {
        return null;
        }
    
        // Read the entire contents of the log file into the arrays 
        while ($data = fscanf($file,"%[ -~]\t%d\n")) 
        {
            list ($name, $count) = $data;
            $file_list[] = array('name'=>$name,
                                 'count'=>$count,
                                 'modifiedTime'=>filemtime("$logPath/$name"));
        }
        fclose($file);
        // $file_list contains data read from the log file as an array (filename => count)
        
        krsort($file_list); //we need to reverse the array as the log items are added in chronological order (first to last), could use array_reverse here also.
        return $file_list;
    }

** Edit ** 

I've just had a reread of your question, what data is stored in each log file? Is there a timestamp for each log file or is a new logfile created for each log entry?

 

The following code will need to be adjusted after the above is answered...

    // Function to read the log file, and return an array as (filename =>        downloads)
    function read_log()
    {
        global $path;
        // Declare Array for holding data read from log file
        $name = array(); // array for file name
        $count = array(); // array for file count
        $file_list = array();
        $logPath = "$path/Includes/log";
        $file = fopen($logPath,"r");
        $file = @file($logPath);
        if(empty($file))
        {
        return null;
        }
    
        // Read the entire contents of the log file into the arrays 
        while ($data = fscanf($file,"%[ -~]\t%d\n")) 
        {
            list ($name, $count) = $data;
            $file_list[] = array('name'=>$name,
                                 'count'=>$count,
                                 'modifiedTime'=>filemtime("$logPath/$name"));
        }
        fclose($file);
        // $file_list contains data read from the log file as an array (filename => count)
        
        usort($file_list,'compareFileModifiedTimes');
        return $file_list;
    }
    
    function compareFileModifiedTimes($array1,$array2)
    {
        return strtotime($array1['modifiedTime']) > strtotime($array2['modifiedTime']);
    }

It's using the PHP usort method and I've restructured a bit of your code to make it more readable.. (i.e. removing the two arrays (name/count) and just using one from the start).

I've not tested it yet though ensure you turn on error_reporting if you experience any errors.

Hello

 

Many thanks again for your help and explanation.

 

It's not yet working with your krsort code below. All the download counts are reset to 0 and there is no descending by date sort.

 

There are some other script files which I did not mention before as I thought only the snippet I posted was relevant.

 

If you have time to look at it I made a demo page here http://gaclrecords.org.uk/scripts/  where you can see and download the relevant files. "functions.php" has your modified snippet inserted and as you can see does not count when you refresh the page.

 

"functionsold.php" is the code which works when renamed to "functions.php" - except it only does descending alphanumeric sort on on the file name.

 

The objective is to have the "r92502_0628.txt" file at the top of the list as it has a later time stamp than the "r92503_0627.txt" file.

 

 

In that case, you won't be able to see the timestamp for each filename download count... though you can easily order it if they're added in chronological order.

    // Function to read the log file, and return an array as (filename =>        downloads)
    function read_log()
    {
        global $path;
        // Declare Array for holding data read from log file
        $name = array(); // array for file name
        $count = array(); // array for file count
        $file_list = array();
        $logPath = "$path/Includes/log";
        $file = fopen($logPath,"r");
        $file = @file($logPath);
        if(empty($file))
        {
        return null;
        }
    
        // Read the entire contents of the log file into the arrays 
        while ($data = fscanf($file,"%[ -~]\t%d\n")) 
        {
            list ($name, $count) = $data;
            $file_list[] = array('name'=>$name,
                                 'count'=>$count,
                                 'modifiedTime'=>filemtime("$logPath/$name"));
        }
        fclose($file);
        // $file_list contains data read from the log file as an array (filename => count)
        
        krsort($file_list); //we need to reverse the array as the log items are added in chronological order (first to last), could use array_reverse here also.
        return $file_list;
    }

sorry - i had left my filemtime() code in there from the first example when I thought you were looking for the modified time also.

I've just tested this and it works on my local. Could you please test it out? and if it's not working do a var_dump of what it's returning.

    function read_log()
    {
        global $path;
        // Declare Array for holding data read from log file
        $name = array(); // array for file name
        $count = array(); // array for file count
        $file_list = array();
        $logPath = "$path/Includes/log";
        $file = fopen($logPath,"r");
        //i've removed your file() command here as fscanf requires a resource handle from fopen() and file() would return an array.
        if(!$file)
        {
        return null;
        }
    
        // Read the entire contents of the log file into the arrays 
        while ($data = fscanf($file,"%[ -~]\t%d\n")) 
        {
            list ($name, $count) = $data;
            $file_list[] = array('name'=>$name,
                                 'count'=>$count);
        }
        fclose($file);
        // $file_list contains data read from the log file as an array (filename => count)
        
        krsort($file_list); //we need to reverse the array as the log items are added in chronological order (first to last), could use array_reverse here also.
        return $file_list;
    }

Hi and thanks again

 

I see no change with the below.

 

I am wondering where your files are.

 

I have download.php and index.php in the same folder as the 2 "r" text files. Your functions.php, log and TalkPHP_Timer.class.php are inside an "Includes" folder. Perhaps you need

to download the php files you don't have from the link and replicate that structure, if you have not already?

 

I had a look at http://php.net/manual/en/function.var-dump.php but was not too sure what command

you wanted me to run from which directory. Various commands are suggested in the comments. I'll do that when you let me know.

 

 

sorry - i had left my filemtime() code in there from the first example when I thought you were looking for the modified time also.

I've just tested this and it works on my local. Could you please test it out? and if it's not working do a var_dump of what it's returning.

    function read_log()
    {
        global $path;
        // Declare Array for holding data read from log file
        $name = array(); // array for file name
        $count = array(); // array for file count
        $file_list = array();
        $logPath = "$path/Includes/log";
        $file = fopen($logPath,"r");
        //i've removed your file() command here as fscanf requires a resource handle from fopen() and file() would return an array.
        if(!$file)
        {
        return null;
        }
    
        // Read the entire contents of the log file into the arrays 
        while ($data = fscanf($file,"%[ -~]\t%d\n")) 
        {
            list ($name, $count) = $data;
            $file_list[] = array('name'=>$name,
                                 'count'=>$count);
        }
        fclose($file);
        // $file_list contains data read from the log file as an array (filename => count)
        
        krsort($file_list); //we need to reverse the array as the log items are added in chronological order (first to last), could use array_reverse here also.
        return $file_list;
    }
    function read_log()
    {
        global $path;
        // Declare Array for holding data read from log file
        $name = array(); // array for file name
        $count = array(); // array for file count
        $file_list = array();
        $logPath = "$path/Includes/log";
        $file = fopen($logPath,"r");
        //i've removed your file() command here as fscanf requires a resource handle from fopen() and file() would return an array.
        if(!$file)
        {
exit("COULD NOT FIND FILE AT $logPath - currently in " . getcwd());
        return null;
        }
    
        // Read the entire contents of the log file into the arrays 
        while ($data = fscanf($file,"%[ -~]\t%d\n")) 
        {
            list ($name, $count) = $data;
            $file_list[] = array('name'=>$name,
                                 'count'=>$count);
        }
        fclose($file);
        // $file_list contains data read from the log file as an array (filename => count)
        
        krsort($file_list); //we need to reverse the array as the log items are added in chronological order (first to last), could use array_reverse here also.

exit("returning <pre>".print_r($file_list,true));

        return $file_list;
    }

hmmm, might be a path issue.

could you try the above - it should exit and show some text. Please copy / paste that text in a reply so I can see it.

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.