Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people, just like you, are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
Solved

Sort a Directory Listing by Part of Filename in PHP

Posted on 2004-09-05
30
378 Views
Last Modified: 2012-06-22
Dear Experts,

I want to use PHP to sort and display a directory listing of files based on part of the filename.

The file names contain 3  fields, SupplierName, InvNo & InvDate which are delimited by an underscore  eg SmithPartners_123_25-06-04.jpg.    I have attached some code which splits the name into the fields and displays them.

What I also want to do is have a combo box that lets the user sort the results by either SupplierName, InvNo or InvDate.

I am new to PHP so please keep the code well commented and as simple as possible.    Don't worry about formatting.
 
Thanks,


Lee.

<?php

//***Get the directory of files.
$handle=opendir('c:\\inetpub\wwwroot\reports\\Documents\SupplierInvoices');
while ($FileName = readdir($handle)){

//***Split them into field names using "_" delimiter
   $SplitFileName = explode("_", $FileName);      
   $SupplierName = $SplitFileName[0];
   $InvNo = $SplitFileName[1];
   $InvDate = $SplitFileName[2];

//***Display them
   echo $SupplierName, "   ", $InvNo, "    ", $InvDate, "<BR>";
}
closedir($handle);

?>
0
Comment
Question by:lnwright
  • 15
  • 9
  • 3
  • +1
30 Comments
 
LVL 55

Assisted Solution

by:Jaime Olivares
Jaime Olivares earned 25 total points
ID: 11986110
Asumming you have the entire listing in an array (which you uses to fill the combobox), you can create your own specialized sorting function. Since it is easier, I will show you an example with bubble sort:

function SortArrayByPortion($array, $from, $length)
{
    $again = true;

    while ($again) {
        $again = false;
        for ($i=0; $i<count($array)-1; $i++) {
             if (substr($array[i], $from, $length)>substr($array[i+1], $from, $length)) {
                  $temp = $array[i];
                  $array[i] = $array[$i+1];
                  $array[i+1] = $temp;
                  $again = true;
             }
        }
    }
    return $array;
}

Now you can sort by a specific substring.
0
 

Author Comment

by:lnwright
ID: 11986181
Thanks Jamie,

A sort function looks like a good solution.    I just want to clarify though.     The combo box only contains a list of the methods to sort be eg it would only contain 3 items "Sort By Supplier Name", " Sort by InvNo" and "Sort by Date".   I want to display the results on the page rather than in a combo box.    

Also I was kind of hoping for an entire solution that I could just cut and paste into my page.

Regards,


Lee.
0
 
LVL 55

Expert Comment

by:Jaime Olivares
ID: 11986256
Not tried but I think it works (unless any typo). Please try and advice:

<?php

function SortArrayByColumn($array, $column)
{
    $again = true;

    while ($again) {
        $again = false;
        for ($i=0; $i<count($array)-1; $i++) {
             if ($array[$i][$column] > $array[$i+1][$column]) {
                  $temp = $array[$i];
                  $array[$i] = $array[$i+1];
                  $array[$i+1] = $temp;
                  $again = true;
             }
        }
    }
    return $array;
}

$array = array();

$handle=opendir('c:\\inetpub\wwwroot\reports\\Documents\SupplierInvoices');
while ($FileName = readdir($handle)) {
   $array[] = explode("_", $FileName);
}
closedir($handle);

if (unset(POST['order'])) {
     $order = 0;
} else
     $order = (int)POST['order'];

echo ('<form name="frmOrder" method="post" action="">');
echo ("<SELECT NAME=\"CodTurno\">");
echo ("<OPTION VALUE=\"0\">Sort By Supplier Name</OPTION>\n");
echo ("<OPTION VALUE=\"1\">Sort by InvNo</OPTION>\n");
echo ("<OPTION VALUE=\"2\">Sort by Date</OPTION>\n");
echo ('</SELECT>&nbsp;&nbsp;<INPUT TYPE=SUBMIT NAME="SUBMIT" VALUE="Change"></form>\n');

$array = SortArrayByColumn($array, $order);

for ($i=0; $i<count($array);$i++) {
      echo $array[$i][0], "   ", $array[$i][1], "    ", $array[$i][2], "<BR>";
}
?>
0
Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

 
LVL 3

Expert Comment

by:kaitou
ID: 11986279
Something like this seems to be what you are looking for:


if ($handle = opendir($dir)) {
    while (false !== ($file = readdir($handle))) {
        if ($file != "." && $file != "..") {
      $file_names[] = $file;
      preg_match( "#(.+?)_(.+?)_(.+?).(.+?)$#is", $file, $parts );
      $SupplierName[] = $parts[1];
      $InvNo[] = $parts[2];
      $InvDate[] = $parts[3];
        }
    }
    closedir($handle);
}
if ($sortBy == "SupplierName") {
//To sort by SupplierName:
array_multisort($SupplierName, $file_names);
} elseif ($sortBy == "InvNo") {
//To sort by InvNo:
array_multisort($InvNo, $file_names);
} elseif ($sortBy == "InvDate") {
//To sort by InvDate:
array_multisort($InvDate, $file_names);
}

foreach ($file_names as $key => $value) {
echo "<img src=$file_names><br>";
}

0
 

Author Comment

by:lnwright
ID: 11986324
Thanks Jaime,

I get this error.

Parse error: parse error, unexpected T_UNSET in C:\Inetpub\wwwroot\reports\GetDirectory1.php on line 29
0
 
LVL 55

Expert Comment

by:Jaime Olivares
ID: 11986333
Sorry,

This line:
     if (unset(POST['order'])) {
Should be:
     if (!isset(POST['order'])) {
0
 

Author Comment

by:lnwright
ID: 11986369
Jaime,

Parse error: parse error, unexpected T_STRING, expecting T_VARIABLE or '$' in C:\Inetpub\wwwroot\reports\GetDirectory1.php on line 29
0
 
LVL 15

Assisted Solution

by:JakobA
JakobA earned 25 total points
ID: 11987040
user defined sorting is nice.

The idea is that you make a function to compare two items (and return -1, 0 or 1 depending on which is biggest)
then you can call php's usort function with your unsorted array and the functionname as parameters.
se description here: http://dk.php.net/manual/en/function.usort.php

below I make 3 functions for the 3 different kinds of sorting you want:

function compare_supplier( $a, $b ) {   // a and b are the strings from 2 arraycells to be compared
    a_supplier = explode( "_", $a )[0];
    b_supplier = explode( "_", $b )[0];
    if ( a_supplier > b_supplier ) return -1;    // -1 if b is 'bigger'
    if ( a_supplier == b_supplier ) return 0;    // 0 if equal
    return 1                                     // 1 if b is 'smaller'
}

function compare_number( $a, $b ) {
    a_number = (int)explode( "_", $a )[1];       // cast to integer so we awoid string comparison ( "10" < "8" )
    b_number = (int)explode( "_", $b )[1];
    if ( a_number > b_number ) return -1;    // -1 if b is 'bigger'
    if ( a_number == b_number ) return 0;    // 0 if equal
    return 1                                     // 1 if b is 'smaller'
}

function compare_time( $a, $b ) {
    $a_time = explode( "_", $a )[2];
    $a_time = implode( "_", array_reverse( explode( "-", $a_time ) ) );  // turns dd-mm-yy into yy-mm-dd.
    $b_time = explode( "_", $b )[2];
    $b_time = implode( "_", array_reverse( explode( "-", $b_time ) ) );
    if ( $a_time > $b_time ) return -1;    // -1 if b is 'bigger'
    if ( $a_time == $b_time ) return 0;    // 0 if equal
    return 1                                     // 1 if b is 'smaller'
}


echo "<br>Sorted by supplier:<br>";
usort( $your_array, "compare_supplier" );
foreach ( $your_array as $cell ) echo $cell ."<br>";

echo "<br>Sorted by number:<br>";
usort( $your_array, "compare_number" );
foreach ( $your_array as $cell ) echo $cell ."<br>";

echo "<br>Sorted by time:<br>";
usort( $your_array, "compare_time" );
foreach ( $your_array as $cell ) echo $cell ."<br>";


regards JakobA
0
 

Author Comment

by:lnwright
ID: 11987143
Thanks Experts,

There is some good stuff here but I need a complete solution including the combo box (if that is generated from code).  Something that I can just paste into my code window and that will run.    Jaime's solution seems the closest to that so far but as mentioned there is a bug.  

Regards,



Lee.
0
 
LVL 3

Expert Comment

by:kaitou
ID: 11987338
<?php
if (!($action)) {
echo "Select sort type:
<form action=$PHP_SELF method=POST>
<input type=hidden name=action value=do_sort>
<select name=sortBy>
<option value=SupplierName>by SupplierName</option>
<option value=InvNo>by InvNo</option>
<option value=InvDate>by InvDate</option>
</select>
<input type=submit value=Go></form>";
} elseif ($action == "do_sort") {


if ($handle = opendir($dir)) {
    while (false !== ($file = readdir($handle))) {
        if ($file != "." && $file != "..") {
     $file_names[] = $file;
     preg_match( "#(.+?)_(.+?)_(.+?).(.+?)$#is", $file, $parts );
     $SupplierName[] = $parts[1];
     $InvNo[] = $parts[2];
     $InvDate[] = $parts[3];
        }
    }
    closedir($handle);
}
if ($sortBy == "SupplierName") {
//To sort by SupplierName:
array_multisort($SupplierName, $file_names);
} elseif ($sortBy == "InvNo") {
//To sort by InvNo:
array_multisort($InvNo, $file_names);
} elseif ($sortBy == "InvDate") {
//To sort by InvDate:
array_multisort($InvDate, $file_names);
}

foreach ($file_names as $key => $value) {
echo "<a href=$value>$value</a><br>";
}
}
?>
0
 
LVL 3

Expert Comment

by:kaitou
ID: 11987340
oh, set $dir to whatever the folder in question is.
0
 

Author Comment

by:lnwright
ID: 11987363
Thanks kaitou,

It will be about 3 hours before I can test this out but looks good.

Regards,


Lee.
0
 

Author Comment

by:lnwright
ID: 11988178
kaitou,

I gave it a try.   The combo box displays ok but when you click "go" it just says page not found.  No further error details.    

Lee.
0
 
LVL 3

Expert Comment

by:kaitou
ID: 11990160
change $PHP_SELF to what you named the script.
0
 

Author Comment

by:lnwright
ID: 11991968
Thanks Kaitou,

I changed it to this:

<form action="GetDirectory2.php" method=POST>

but now I get this error:

Parse error: parse error, unexpected T_STRING, expecting ',' or ';' in C:\Inetpub\wwwroot\reports\GetDirectory2.php on line 4

Please advise.
0
 
LVL 15

Expert Comment

by:JakobA
ID: 11992782
Notice when you get an error that the errorline ends with a line number.
It would help if you showed us what that line looks like (plus the one in front of it at that is often where the error is). In this case that would be line 3 and 4 of your file GetDirectory2.php
0
 

Author Comment

by:lnwright
ID: 11992806
JakobA,

Here is the source, there are no spaces above.

 <?php
if (!($action)) {
echo "Select sort type:
<form action="GetDirectory2.php", method=POST>
<input type=hidden name=action value=do_sort>
<select name=sortBy>
<option value=SupplierName>by SupplierName</option>
<option value=InvNo>by InvNo</option>
<option value=InvDate>by InvDate</option>
</select>
<input type=submit value=Go></form>";
} elseif ($action == "do_sort") {


$dir = "c:\\inetpub\wwwroot\reports\\Documents\SupplierInvoices";
if ($handle = opendir($dir)) {
    while (false !== ($file = readdir($handle))) {
        if ($file != "." && $file != "..") {
     $file_names[] = $file;
     preg_match( "#(.+?)_(.+?)_(.+?).(.+?)$#is", $file, $parts );
     $SupplierName[] = $parts[1];
     $InvNo[] = $parts[2];
     $InvDate[] = $parts[3];
        }
    }
    closedir($handle);
}
if ($sortBy == "SupplierName") {
//To sort by SupplierName:
array_multisort($SupplierName, $file_names);
} elseif ($sortBy == "InvNo") {
//To sort by InvNo:
array_multisort($InvNo, $file_names);
} elseif ($sortBy == "InvDate") {
//To sort by InvDate:
array_multisort($InvDate, $file_names);
}

foreach ($file_names as $key => $value) {
echo "<a href=$value>$value</a><br>";
}
}
?>
0
 
LVL 15

Expert Comment

by:JakobA
ID: 11992927
Ther error is in the string handeling. strings have quotes around them, and inside the string tha same kind of quotes may not be used.  you have "-s around the string (starting on line 3 and ending on line 11); but inside the string you also use "-s in the html attribute: action="GetDirectory2.php"  and that confuses php.
Use single quotes inside the string:
  <form action='GetDirectory2.php', method=POST>
0
 

Author Comment

by:lnwright
ID: 11993912
Thanks JakobA,

That fixes the error message but nothing happens when you click on the go button.

Regards,



Lee.
0
 
LVL 3

Expert Comment

by:kaitou
ID: 11993984
Try:  

 <?php
if (!($_POST[action])) {
echo "Select sort type:
<form action='GetDirectory2.php' method=POST>
<input type=hidden name=action value=do_sort>
<select name=sortBy>
<option value=SupplierName>by SupplierName</option>
<option value=InvNo>by InvNo</option>
<option value=InvDate>by InvDate</option>
</select>
<input type=submit value=Go></form>";
} elseif ($_POST[action] == "do_sort") {


$dir = "/";
if ($handle = opendir($dir)) {
    while (false !== ($file = readdir($handle))) {
        if ($file != "." && $file != "..") {
     $file_names[] = $file;
     preg_match( "#(.+?)_(.+?)_(.+?).(.+?)$#is", $file, $parts );
     $SupplierName[] = $parts[1];
     $InvNo[] = $parts[2];
     $InvDate[] = $parts[3];
        }
    }
    closedir($handle);
}
if ($_POST[sortBy] == "SupplierName") {
//To sort by SupplierName:
array_multisort($SupplierName, $file_names);
} elseif ($_POST[sortBy] == "InvNo") {
//To sort by InvNo:
array_multisort($InvNo, $file_names);
} elseif ($_POST[sortBy] == "InvDate") {
//To sort by InvDate:
array_multisort($InvDate, $file_names);
}

foreach ($file_names as $key => $value) {
echo "<a href=$value>$value</a><br>";
}
}
?>
0
 

Author Comment

by:lnwright
ID: 11994034
This gives me a directory of the root of the c drive and no combo box
0
 
LVL 3

Accepted Solution

by:
kaitou earned 450 total points
ID: 11994192
change
$dir = "/";
back to the folder you were using.
0
 

Author Comment

by:lnwright
ID: 11996052
Thanks to all who posted..   This was a difficult question.   Kaitou finally had a solution that worked for me.      Just one question.  How do I stop the combo box from dissapearing when the results display?
0
 
LVL 3

Expert Comment

by:kaitou
ID: 11996528
put a copy of  

echo "Select sort type:
<form action='GetDirectory2.php' method=POST>
<input type=hidden name=action value=do_sort>
<select name=sortBy>
<option value=SupplierName>by SupplierName</option>
<option value=InvNo>by InvNo</option>
<option value=InvDate>by InvDate</option>
</select>
<input type=submit value=Go></form>";

under

} elseif ($_POST[action] == "do_sort") {
0
 

Author Comment

by:lnwright
ID: 12011086
Points already awarded, but how do I stop the combo box from disappearing when the results appear.     I want it to stay at the top of the page.

Thanks,


Lee.
0
 
LVL 3

Expert Comment

by:kaitou
ID: 12011425
just edit the code to what i said in my previous comment.
0
 

Author Comment

by:lnwright
ID: 12011635
kaitou ,

Sorry I didn't notice your post above.    It works fine.   Thankyou.

Lee
0
 

Author Comment

by:lnwright
ID: 12011709
Actually I just noticed a problem.     It now doesn't actually sort and the chosen sort method changes back to "Supplier Invoices"

Please advise.

Thanks,


Lee.
0
 
LVL 3

Expert Comment

by:kaitou
ID: 12011824
it should still do the sort as before, but the drop down box would show the default choices, there is no code there to get it to switch to the selected one.
0
 

Author Comment

by:lnwright
ID: 12011939
OK Thanks
0

Featured Post

Networking for the Cloud Era

Join Microsoft and Riverbed for a discussion and demonstration of enhancements to SteelConnect:
-One-click orchestration and cloud connectivity in Azure environments
-Tight integration of SD-WAN and WAN optimization capabilities
-Scalability and resiliency equal to a data center

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Author Note: Since this E-E article was originally written, years ago, formal testing has come into common use in the world of PHP.  PHPUnit (http://en.wikipedia.org/wiki/PHPUnit) and similar technologies have enjoyed wide adoption, making it possib…
Part of the Global Positioning System A geocode (https://developers.google.com/maps/documentation/geocoding/) is the major subset of a GPS coordinate (http://en.wikipedia.org/wiki/Global_Positioning_System), the other parts being the altitude and t…
Learn how to match and substitute tagged data using PHP regular expressions. Demonstrated on Windows 7, but also applies to other operating systems. Demonstrated technique applies to PHP (all versions) and Firefox, but very similar techniques will w…
The viewer will learn how to create a basic form using some HTML5 and PHP for later processing. Set up your basic HTML file. Open your form tag and set the method and action attributes.: (CODE) Set up your first few inputs one for the name and …

840 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question