ExpressionEngine CMS
Open, Free, Amazing

Thread

This is an archived forum and the content is probably no longer relevant, but is provided here for posterity.

The active forums are here.

CI developers challenge: improve this code

June 30, 2008 9:04am

Subscribe [6]
  • #1 / Jun 30, 2008 9:04am

    xwero

    4145 posts

    I just read the blog post and i though CI developers could come up with a better coded function.

    /**
     * Converts a string to a valid UNIX filename.
    
     * @param       $string         The filename to be
    
     * @return      $string         The filename converted
    
     */
    
     function convert_to_filename ($string) {
    
          // Replace spaces with underscores and makes the string lowercase
    
          $string = str_replace (" ", "_", $string);
    
          $string = str_replace ("..", ".", $string);
    
          $string = strtolower ($string);
    
          // Match any character that is not in our whitelist
    
          preg_match_all ("/[^0-9^a-z^_^.]/”, $string, $matches);
    
          // Loop through the matches with foreach
    
          foreach ($matches[0] as $value) {
    
               $string = str_replace($value, "", $string);
    
          }
    
          return $string;
    
    }

    Show your skills people 😊

  • #2 / Jun 30, 2008 9:26am

    Seppo

    483 posts

    <?php
    /**
     * Converts a string to a valid UNIX filename.
     * @param       $string         The filename to be
     * @return      $string         The filename converted
     */
    function convert_to_filename ($string) {
          // Replace spaces with underscores and makes the string lowercase
          $string = str_replace(" ", "_", $string);
          $string = preg_replace("/\.+/", ".", $string);
          $string = strtolower($string);
          $string = preg_replace("/[^\d^[:alpha:]^_^.]/", '', $string);
    
          return $string;
    }
    ?>

    Do u like this one? I’m not sure what the str_replace(’..’, ‘.’, $string) meant, but I think the idea was the one I put here…

  • #3 / Jun 30, 2008 9:30am

    xwero

    4145 posts

    Looks nice Seppo. Who can make Seppo’s code better 😊 Or has another way?

  • #4 / Jun 30, 2008 9:32am

    Armchair Samurai

    244 posts

    Meh… I suspect this will be torn to shreds by more talented people than myself momentarily.

    function convert_to_filename($string)
    {
        return preg_replace('/[^\da-z_.]/', '', strtolower(str_replace(array(' ', '..'), array('_', '.'), $string)));
    }
  • #5 / Jun 30, 2008 9:36am

    xwero

    4145 posts

    Nice one liner Armchair Samurai, i think there is little room for improvement.

  • #6 / Jun 30, 2008 9:43am

    xwero

    4145 posts

    Not as good as above code, but i want to demonstrate the use of array_flip and strtr

    function convert_to_filename($string)
    {
       $string = strtolower($string);
       $replace1 = array(' '=>'_','..'=>'.');
       preg_match_all ("/[^0-9^a-z^_^\.]/", $string, $matches);
       $replace2 = array_flip($matches); // makes keys unique as a bonus
       foreach($replace2 as $key=>$value){ $replace2[$key] = '';}
       return strtr($string,array_merge($replace1,$replace2));
    }
  • #7 / Jun 30, 2008 12:09pm

    Pascal Kriete

    2589 posts

    Building on the strtr idea a bit.  Putting a ^ at the beginning of a character class negates all characters in that group, you don’t need it more than once.

    function convert_to_filename($string)
    {
        $string = strtolower($string);
        $string = strtr($string, array(' ' => '_', '..' => '.'));
        return preg_replace('/[^\w.]/', '', $string);
    }
  • #8 / Jun 30, 2008 3:31pm

    Alex.

    29 posts

    Building on the strtr idea a bit.  Putting a ^ at the beginning of a character class negates all characters in that group, you don’t need it more than once.

    function convert_to_filename($string)
    {
        $string = strtolower($string);
        $string = strtr($string, array(' ' => '_', '..' => '.'));
        return preg_replace('/[^\w.]/', '', $string);
    }

    Doesn’t that regexperession remove underscores and dots too? :S

  • #9 / Jun 30, 2008 3:35pm

    Pascal Kriete

    2589 posts

    Nope, [\w] is [A-Za-z0-9_] and a dot in a character group is a regular dot.  The ^ at the front means that all of those should not be replaced.

  • #10 / Jun 30, 2008 3:37pm

    Alex.

    29 posts

    Nope, [\w] is [A-Za-z0-9_] and a dot in a character group is a regular dot.  The ^ at the front means that all of those should not be replaced.

    Ah, the website I checked didn’t say that.  Thanks for the explanation!

  • #11 / Jun 30, 2008 4:30pm

    mironcho

    119 posts

    I would do it this way:

    function convert_to_filename($string, $lower = true)
    {
        // names containing upper and lower case are valid UNIX names,
        // so this is optional (enabled by default)
        if (true === $lower)
        {
            $string = strtolower($string);
        }
    
        $paterns = array('/\.{2,}/', '/\s+/', '/[^\w_\.]/');
        $replacements = array('.', '_', '');
    
        return preg_replace($paterns, $replacements, $string);
    }

    Anyway, valid UNIX name is any name that contains characters different from ‘/’...

  • #12 / Jul 01, 2008 4:02pm

    Michael Wales

    2070 posts

    Heh, funny I saw this…

    Today I was browsing around the Battlestar Galactica site where they have a social network/game. It’s basically Facebook/MySpace except everyone is on one of two teams (humans vs. cylons). There are then core tasks each week that teams receive scores on based on participation (normalized, for differing population levels between the two teams).

    Anyways, I was thinking how much fun it would be to have a social network where coders join a team (PHP, Python, Ruby, etc.) and are then issued a weekly challenge - similar to this. Participation in the challenge would then determine which language was the “winner” that week.

  • #13 / Jul 01, 2008 5:33pm

    Jamie Rumbelow

    546 posts

    @Michael Nice Idea!

  • #14 / Jul 01, 2008 10:49pm

    Randy Casburn

    997 posts

    $xReference = tempnam(”/fileStore”);
    ———

    Problem solved.

    ———
    Not the original intent? Right. I just got to the pragmatic part of “whatayagonnadowithit”.  This gem can save many hassles like this since it relieves all of us from dealing with platform specific issues.  Rather than spending timing writing and rewriting (I love how many times DRY shows up in these forums) stuff like this, why not rely on the PHP core?

    Dump the user’s reference in your favorite storage mechanism (Flat ini file, XML, DB, etc.), use the tmp file name as the file name. Cross reference them. Instant cross platform that works on MAC, Linux, PC, etc.

    But then what would we blog about 😉

    [edited: changed instance to instant]

  • #15 / Jul 02, 2008 4:20am

    xwero

    4145 posts

    What you are saying makes a lot of sense. Why bother with a filename that almost looks like the original filename.

    But when you upload a file it becomes another thing. To use tempnam for uploads you have to
    - tempnam(’/dir’)
    - file_get_contents($_FILES[‘file’][‘tmpname’])
    - file_put_contents(tempnam)
    - unlink($_FILES[‘file’][‘tempname’])

    While you can do
    - user_function_for_file_name()
    - move_uploaded_file()

    I think the reading and writing of a file, especially when it’s a large one will slow down your app more than a function to create a unique name because that is what you are after in the first place, creating no collision filenames.

    I also ask myself, not having worked with tempnam yet, what is the extension of the created file?

.(JavaScript must be enabled to view this email address)

ExpressionEngine News!

#eecms, #events, #releases