0

I have a web form to upload pictures from the users. Then I am creating an iOS app to show the pictures loaded from the users. But the app is not loading the pictures if the file name contains spaces or special characters (like á, é, í, ó, ú, ñ, etc.), most of the users are from Spain...

This is the code I am using:

<?php if ((isset($_POST["enviado"])) && ($_POST["enviado"] == "form1")) {
    $randomString = substr(str_shuffle("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), 0, 1) . substr(str_shuffle("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), 0, 10);

echo $randomString;
    $nombre_archivo = $_FILES['userfile']['name']; 
    move_uploaded_file($_FILES['userfile']['tmp_name'], "logos/".$randomString.$nombre_archivo);

    ?>

I am using the random function to avoid repeated file names.

How could I change the file name given by the user and that may contain spaces and/or special characters, in a way that can be perfectly loaded in the iOS app?

mvasco
  • 4,965
  • 7
  • 59
  • 120
  • 1
    Rename the files after you upload them to a timestamp or random string of characters and you will forever avoid this problem. If you can't rename them, use utf-8 in your form and database. I'm not an objective-c dev, but see if you can convert to utf-8 in your iOS app and read that. – timgavin Feb 24 '14 at 05:20
  • 2
    if the app is not loading pictures, maybe the problem is with the code in your app and not the web form? – Michael Dautermann Feb 24 '14 at 05:20
  • @MichaelDautermann, may be you are right, but I don't have any problem showing the images from file names that don't include spaces or special characters. – mvasco Feb 24 '14 at 05:23
  • @Tim, you are right, but I guess that the easiest solution may be to rename all files prior to upload them to the server. – mvasco Feb 24 '14 at 05:25
  • 1
    [Transliteration](http://stackoverflow.com/questions/3542717/how-to-transliterate-accented-characters-into-plain-ascii-characters) is something i would do on such filenames –  Feb 24 '14 at 05:27
  • 1
    @mvasco you can easily rename them after upload, and *that's* the place to do it because *you* get to control the filenames. :) – timgavin Feb 24 '14 at 05:34
  • @Tim, how could I rename the file after upload from my code? – mvasco Feb 24 '14 at 05:49
  • @mvascosee my answer below. hope it helps! – timgavin Feb 24 '14 at 06:22

3 Answers3

1

Here is what you need to do. 1) generate a unique id based filename string. 2) Rename the file with newly generated filename.

<?php
    rename("/tmp/tmp_file.txt", "/home/user/login/docs/my_file.txt");
?>
user3227262
  • 563
  • 1
  • 6
  • 16
1

If you actually wanted to keep the user-entered string as part of the file name, you could do something like this which transliterates UTF-8 characters to their ASCII equivalent (if possible) and then removes any non ASCII and invalid characters:

function get_file_name($string) {
    // Transliterate non-ascii characters to ascii
    $str = trim(strtolower($string));
    $str = iconv('UTF-8', 'ASCII//TRANSLIT', $str);

    // Do other search and replace
    $searches = array(' ', '&', '/');
    $replaces = array('-', 'and', '-');
    $str = str_replace($searches, $replaces, $str);

    // Make sure we don't have more than one dash together because that's ugly
    $str = preg_replace("/(-{2,})/", "-", $str );

    // Remove all invalid characters
    $str = preg_replace("/[^A-Za-z0-9-]/", "", $str );

    // Done!
    return $str;
}

You could try combining this together with the unique ID for the file so if two users upload a file with the same file name they don't clash.

Mike
  • 23,542
  • 14
  • 76
  • 87
1

rename the file after upload. this is an answer to OP's question in comments

// get the uploaded file's temp filename
$tmp_filename = $_FILES['userfile']['tmp_name'];

// get the file's extension
$path = $_FILES['userfile']['name'];
$ext = pathinfo($path, PATHINFO_EXTENSION);

// rename the uploaded file with a timestamp, insert the destination directory and add the extension
$new_filename = 'logos/'.date('Ymdhms').'.'.$ext;

// put the renamed file in the destination directory
move_uploaded_file($tmp_filename, $new_filename);

Edit: new answer per OP's question

<?php
     if((isset($_POST["enviado"])) && ($_POST["enviado"] == "form1")) {
        // get the uploaded file's temp filename
        $tmp_filename = $_FILES['userfile']['tmp_name'];

        // get the file's extension
        $path = $_FILES['userfile']['name'];
        $ext = pathinfo($path, PATHINFO_EXTENSION);

        // rename the uploaded with a timestamp file, add the extension and assign the directory
        $new_filename = 'logos/'.date('Ymdhms').'.'.$ext;

        // put the renamed file in the destination directory
        move_uploaded_file($tmp_filename, $new_filename);
    }
timgavin
  • 4,972
  • 4
  • 36
  • 48
  • Thank you, but where in my code should I put yours? I have tried in different ways but the timestamp is not taken as the file name. Would you mind showing me how to update my code to include your proposal? – mvasco Feb 24 '14 at 06:40
  • @mvasco put it where you currently have your `move_uploaded_file()` function. This pretty much replaces everything else. I've updated my answer. Since you haven't posted any additional code, this is my best guess as to where you should put it. – timgavin Feb 24 '14 at 07:03