How to avoid file names with spaces and/or special characters - php

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?

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);
}

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");
?>

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.

Related

PHP: How to explode string

I have a variable that stores the location of a temp file:
$file = 'C:\xampp\htdocs\temp\filename.tmp';
How can I explode all this to get filename (without the path and extension)?
Thanks.
Is not the best code but if you confident that this path will be similar and just file name will be different you can use this code:
$str = 'C:\xampp\htdocs\temp\filename.tmp';
$arrayExplode = explode("\\", $str);
$file = $arrayExplode[count($arrayExplode)-1];
$filename = explode('.', $file);
$filename = $filename[0];
echo $filename;
Advice: Watch out on the path contain "n" like the first letter after the backslash. It could destroy your array.
You should use the basename function, it's meant specifically for that.

rename file name using path info extension with dot

i need new name of file name using pathinfo($url, PATHINFO_EXTENSION);
this my code
$name = "name.txt";
$f = fopen($name, 'r');
$nwname = fgets($f);
fclose($f);
$newfname = $destination_folder .$nwname. pathinfo($url, PATHINFO_EXTENSION);
output:
1 jpeg
how to make output nospace and write (.) dot before jpeg like this
output:
1.jpeg
thank
Solved in comments, here's write up.
The . is used for concatenation. So $variable.$variable puts the values of the two variables together. $variable.'.'.$variable would add a period between the 2 variables. The trim function should be used to remove leading and trailing whitespaces from a variable.
Functional demo: https://eval.in/520038
References:
http://php.net/manual/en/function.trim.php
http://php.net/manual/en/language.operators.string.php
I think you need to concatenate strings like below :
$newfname = $destination_folder .$nwname.'.'. pathinfo($url, PATHINFO_EXTENSION);

get filename with pure extension

I'm coding a script to get image from a site. All is good, but then I notice there are some sites which have images in format like this:
http://site-name/images/dude-i-m-batman.jpg?1414151413
http://site-name/images/dude-i-m-batman.jpg?w=300
right now I'm dealing with it by doing
$file = substr($media,0, strrpos($image, '.') + 4);
I'm just wondering whether it's a good practice or there's a better way.
I've tried pathinfo and a couple other methods, but all return extension with the query string.
Thanks
Parse the URL with parse_url, retrieve the path part:
$datum = parse_url($url);
$parts = pathinfo($datum['path']);
$ext = $parts['extension'];
You may also use getImageInfo($full_url), if fopen_wrappers allow it, and retrieve image info such as width, height, and most importantly, mime_type.
This because you will find several files without extension or with the wrong one, put there to trick browsers into downloading as image and trusting that the browser will recognize the image format nonetheless (been there, done that :-( )
I'm unsure whether you mean you want the extension or (judging from your current code) the full path (minus any query string).
Here's both:
$file = "http://site-name/images/dude-i-m-batman.jpg?1414151413";
preg_match('/^([^\?]+)(?:\?.*)?/', $file, $path_noQS);
preg_match('/(?<=\.)(\w{2,5})(?:\?.*)?/', $file, $extension);
echo $path_noQS[1]; //path, without QS
echo $extension[1]; //extension
Obviously what you do now has some shortcomings. One of them you already noticed your own:
Not all URLs end with the file-extension.
Not all file-extensions are of three letters (e.g. .jpeg)
So what you want is to get the path from a URL:
$imagePath = parse_url($imageUrl, PHP_URL_PATH);
And then you want to get the extension from that path:
$imageName = pathinfo($imagePath, PATHINFO_EXTENSION);
And done. You're not the first who needs that, so functions already exist for the job.
Your solution only works with 3 character extensions. If you know all the extensions will be 3 characters than yours is a perfectly viable solution. Otherwise:
$ext = pathinfo($filename, PATHINFO_EXTENSION);
This should definitely work if you have the correct file name
If for some reason that doesn't work, you can use this:
$ext = end(explode('.', $filename));
$ext = substr(strrchr($filename, '.'), 1);
$ext = substr($filename, strrpos($filename, '.') + 1);
$ext = preg_replace('/^.*\.([^.]+)$/D', '$1', $filename);
$exts = split("[/\\.]", $filename);
$n = count($exts)-1;
$ext = $exts[$n];
may be something like this
$parsedUrl = parse_url('http://site-name/images/dude-i-m-batman.jpg?1414151413');
$parsedFileInfo = pathinfo($parsedUrl['path']);
echo $parsedFileInfo['extension'];
http://codepad.org/KXZwKCjs
$u = 'http://site-name/images/dude-i-m-batman.zip.jpg?1414151413?1234';
$u = explode('?', $u, 2 ); // ignore everything after the first question mark
$ext = end(explode('.',$u[0])); // last 'extension'

How to transfer set of text from file to file using two identifiers using PHP?

This code below can migrate the two variables from one file into the other.
<?php
$file = 'somefile.txt';
// Open the file to get existing content
$current = fopen($file,'a');
// Append a new person to the file
$firstname .= "aiden\n";
$secondname .= "dawn\n";
$currentContent = file_get_contents($file);
// Write the contents back to the file
$fileFound = 'people.txt';
$newFile = fopen($fileFound,'a');
//if $current and $nextcurrent is found in the somefile.txt it will transfer the content to people.txt
if (strpos($currentContent,$firstname) !== 0)
{
if (strpos($currentContent,$secondname) !== 0)
{
fwrite($newFile, $currentContent."\n");
} // endif
}// endif
?>
The next problem is, how am i able to migrate the texts from identifier one up to identifiers two?
I guess I'll have to use substr or a strrpos string here.
Help Please :)
I'm having a hard time understanding the problem but looks like you're trying to include anything between 'aiden' and 'dawn' from a file and write the result into a new file.
Give a shot for this one
$firstIdentifier = 'aiden';
$secondIdentifier = 'dawn';
$currentContent = str_replace("\n", "", file_get_contents('sourcefile.txt'));
$pattern = '/('.$firstIdentifier.')(.+?)('.$secondIdentifier.')/';
//get all text between the two identifiers, and include the identifiers in the match result
preg_match_all($pattern, $currentContent , $matches);
//stick them together with space delimiter
$contentOfNewFile = implode(" ",$matches[0]);
//save to a new file
$newFile = fopen('destinationFile.txt','a');
fwrite($newFile, $contentOfNewFile);
You don't need fopen when you are using file_get_contents
Instead of using a delimiter I'd suggest you just serialize your variables
In file 1:
file_put_contents('somefile.txt',serialize(array($firstname,$lastname)));
In file 2:
list($firstname,$lastname) = unserialize(file_get_contents('somefile.txt'))

System cannot find the path specified rename file

I am trying to rename a file but I get this error.
$newFile = "$surname _$firstname _$dob";
$string = str_replace(' ', '', $newFile);
rename($filename, "$string.pdf");
This code produces this error
Warning: rename(0001_D_A.pdf,Mccoy_Edward_11/22/2016.pdf): The system cannot find the path specified. (code: 3) in C:\xampp\htdocs\script.php on line 7
However if I change the code to use a normal string without a variable it will rename the file without any error.
$newFile = "$surname _$firstname _$dob";
$string = str_replace(' ', '', $newFile);
rename($filename, "helloworld");
The output from $string is -
Mccoy_Edward_11/22/2016
The / in the date are invalid for file names and are interpreted as directory separators by the function.
Use - instead to separate the date parts i.e. mm-dd-yyyy
$newFile = "{$surname}_{$firstname}_{$dob}";
$string = str_replace('/', '-', $newFile);
rename($filename, "$string.pdf");
That's because the slashes are invalid characters in a windows file name (they act as directory separators on unix-like systems). You have to replace them with something valid, e.g. underscores:
$string = str_replace('/', '_', $newFile);

Categories