Jump to content

function to pass special character filenames to urls


Recommended Posts

I am trying to modify the code from this source http://www.networkedmediatank.com/showthread.php?tid=54009

to play my mp3 files remotely.


Some albums and mp3 filenames contain special characters.  I would like to learn how to fix the code rather than

simply rename my files.  I made some changes to replace the special characters with the hex codes.


The problem is that the function uses is_file and is_dir to display the filenames and directories but these return false

for names with special characters.


What logical test can I use to distinguish files and directories to display all of the contents correctly?  Or do I use this

http://php.net/manual/en/class.normalizer.php to allow is_file to work on special characters?

function showContent($path){
   if ($handle = opendir($path)){
       while (false !== ($file = readdir($handle)))
                   if ($file=='.' || $file=='..' || valid_extension($file))
                          // echo "hidden<br>";
                           } else {

                                $old = array(" ", "'", "&", ":" );
                                $new = array("%20","%27","%26","%3A");

                                $fName =  htmlspecialchars($file, ENT_HTML401);
                                $file = $path."/".$file;
                                $file =  htmlspecialchars($file, ENT_HTML401);
                                $fileurl = str_replace($old, $new, $file);

               if(is_file($file)) {

                   echo "<li class='music' data-icon='false'><a class='musicfile' href='#' data-src='".$_ENV['domain'].$fileurl."'><h3>".$fName."</h3>"
                       ."<p class='size ui-li-aside'> ".format_size(filesize($file))."</p></a></li>";
               } elseif (is_dir($file)) {
                   echo "<li class='folder'><a href='".$_SERVER['SCRIPT_NAME']."?path=".$file."'>";
                                   if (file_exists($file."/".$_ENV['coverart'])) {
                                                $folderart = $_ENV['domain'].$fileurl."/".$_ENV['coverart'];
                                                echo "<img src='$folderart'>";
                                        } else {
                                                echo "<img src='images/jewelcase_empty.png'>";
                                        echo "<h3>$fName</h3></a></li>";




Link to comment
Share on other sites

My first project is to get it to list all of the music files and directories.  Right now I am stuck trying to substitute is_file

with some construct that will display all the files.  I know that $file handles the filenames correctly because I can echo



I can probably switch to urlencode as you suggest but I believe that won't fix my immediate challenge.

Link to comment
Share on other sites

How about you provide some example file names that are failing. How have you verified that it is the is_file() function that is not reading them right? You are modifying the file name before using is_file() so I don't know why you would expect it to work.


Also, no need for an is_file() check and then an else if(is_dir()). The objects returned by readdir() are either files or directories. There is no third option (well, except FALSE, which the code already handles)

Edited by Psycho
Link to comment
Share on other sites

Looks like there is a known issue with reading multi-byte characters in file names: https://bugs.php.net/bug.php?id=64327&edit=1



If the special characters are only in the file names (and not the folder names). Then do a check to see if the object is a folder. If not, assume it is a file. Here is a clean-up of your previous code.



function showContent($path)
    if ($handle = opendir($path))
        while (false !== ($file = readdir($handle)))
            if ($file!='.' && $file!='..' && !valid_extension($file))
                $fileHTML =  htmlspecialchars($file);
                $filePath = $path . DIRECTORY_SEPARATOR . $file;
                $fileURL = urlencode($filePath);

                    $fileSize = format_size(filesize($filePath));
                    echo "<li class='music' data-icon='false'>\n";
                    echo "<a class='musicfile' href='#' data-src='{$_ENV['domain']}{$fileURL}'><h3>{$fileHTML}</h3>\n";
                    echo "<p class='size ui-li-aside'>{$fileSize}</p></a></li>\n\n";
                    $coverArt = $filePath . DIRECTORY_SEPARATOR . $_ENV['coverart'];
                    $imgSrc = (file_exists($coverArt)) ? $_ENV['domain'] . $coverArt : 'images/jewelcase_empty.png';

                    echo "<li class='folder'><a href='{$_SERVER['SCRIPT_NAME']}?path={$fileURL}'>";
                    echo "<img src='{$imgSrc}'>";
                    echo "<h3>{$fileHTML}</h3></a></li>";
Link to comment
Share on other sites

Very nice. Thank you.  I swapped in your cleaned up function and now the page lists all albums and song titles

For example it lists: 





I can see links for albums and music files but now the HTML5 player embeded on the page won't play and shows an error message:


Error loading: "http://guruplug.%2Fmusic%2FBillie+Holiday%2FKen+Burns+Jazz%3A+Definitive+Billie+Holiday%2F15+-+Good+Morning%2C+Heartache.mp3"



In this section of code I point $_ENV['basepath'] to the symlink that points to the folder with the mp3 files

 14 // The base path of the files you wish to browse
 15 $_ENV['basepath'] = './music';
 16 // File extension you want to hide from the list
 17 $_ENV['hidden_files'] = array ("\\/", "php", "css", "htaccess", "sub", "srt", "idx", "smi", "js", "DS_Store", "jpg", "gif", "nmj", "jsp", "txt");
 18 // File name of album cover art
 19 $_ENV['coverart'] = 'cover.jpg';
 20 // File name of album review text
 21 $_ENV['review'] = 'review.txt';

If I use anything else but ./music there is no listing of music filenames.


However, now the html5 player seems to want a . in front of the %2F seperator.

135 <body>
136 <?php
137 setlocale(LC_ALL, 'en_US.UTF8');
139 if (isset($_GET['path'])){
140         $actpath = $_GET['path'];
141 } else {
142 $actpath = $_ENV['basepath'];
143 }
144 ?>
145 <div data-role="page">
146   <div data-role="header">
147     <!--Breadcrumb -->
148     <div id="breadcrumb">
149       <?php
150         if ( $actpath != $_ENV['basepath']){
151                 $crumb = explode("/",str_replace($_ENV['basepath'],"",$actpath));
152         echo "<span><a href='" .$_SERVER['PHP_SELF']."?path=".$_ENV['basepath']."'>Home</a></span>";
153         $newpath = '';
154         foreach($crumb as $index => $value) {
155         $newpath .= $value;
156         // is not last item //
157         if($index < count($crumb)-1)
158             echo "<a href='" .$_SERVER['PHP_SELF']."?path=".$_ENV['basepath']. $newpath ."'>$value</a>";
159         // it is last item //
160         else
161             echo $value;
162         $newpath .= '/';
163                  }}
164                 ?>
165     </div>

Link to comment
Share on other sites

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.

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.