php how to have links with spaces automatically add %20 [duplicate] - php

This question already has answers here:
Using PHP Replace SPACES in URLS with %20
(6 answers)
Closed 8 years ago.
i have this code that is listing all my mp3 links in the directory, but the audio player won't play any files that have spaces in the file names, if i remove the spaces, it works but i was wondering if i can some how have the script add %20 when there is a space in the file name and that way the audio player i am using can pickup on it
Thanks!
heres my code
<ul id="playlist">
<?php
$dirFiles = array();
// opens images folder
if ($handle = opendir('.')) {
while (false !== ($file = readdir($handle))) {
// strips files extensions
$crap = array(".jpg", ".jpeg", ".JPG", ".JPEG", ".png", ".PNG", ".gif", ".GIF", ".bmp", ".BMP", "_", "-", "error_log", ".php");
$newstring = str_replace($crap, " ", $file );
//asort($file, SORT_NUMERIC); - doesnt work :(
// hides folders, writes out ul of images and thumbnails from two folders
if ($file != "." && $file != ".." && $file != "index.php" && $file != ".DS_Store" && $file != "download.php" && $file != "error_log" && $file != "Thumbnails") {
$dirFiles[] = $file;
}
}
closedir($handle);
}
sort($dirFiles);
foreach($dirFiles as $file)
{
//echo "<li><img style=\"padding-right: 10px;vertical-align: middle;height: 60px;\" src=\"http://www.ggcc.tv/LogoNE.png\" />";
echo '<li><a href="'.$file.'">'.$file.'<br></li>';
}
?>
</ul>

try rawurlencode or other Url Functions
echo '<li><a href="'.rawurlencode($file).'">'.$file.'<br></li>';

Use str_replace to replace spaces with %20.
$fileURL = str_replace(' ', '%20', $file);
echo '<li><a href="'.$fileURL.'">'.$file.'<br></li>';

Alternatively one may modify the foreach loop as follows:
foreach($dirFiles as $file)
{
$url = join("%20",explode(' ',$file ) );
echo '<li><a href="'.$url.'">'.$file.'<br></li>';
}
The first statement encodes only spaces and assigns the result for later use by the HREF attribute of the <a> tag. rawurlencode is another option to achieve a similar result, but it may also encode more than just space characters which at times is good and other times may cause undesirable effects, such as encoding a character that is part of a domain name. str_replace is probably the sleeker solution since it requires only one function call instead of of the two shown in this snippet.
The TIMTOWDI aspect of PHP is particularly evident with this question. You may also do the following:
<?php
$from = ' ';
$to = '+';
foreach($dirFiles as $file)
{
$url = strtr( $file, $from, $to);
echo '<li><a href="'.$url.'">'.$file.'<br></li>';
}
With this solution, the replacement character for the space is the simple '+' (PHP's way of encoding spaces) and it uses strtr() which some think is faster than str_replace(). Any '+' characters will revert to spaces after the the browser automatically decodes the url.
see simple example here

Related

How to display images found in a directory and using name info in their filename

Lets say I have 4 jpg files in a directory that will only ever contain jpg files. The number of files may change, the naming convention will always be Name-file.jpg
Bob-file.jpg
Tom-file.jpg
Dave-file.jpg
Douglas-file.jpg
I am trying to come up with a php script that will look at the directory and display each image (as in viewing the picture, not just listing the filename) in the web browser and also add the persons name along side it so I can see who it is.
I have tried playing with arrays and loops but can't get anything remotely close (I'm new to PHP)
Thanks!!
You'll want something roughly along these lines. Using a directory iterator to get all the filenames and then using a regular expression to extract the name from the filename.
foreach ((new DirectoryIterator('./path/to/image/dir')) as $file) {
if (!$file->isDot() && preg_match('#^(.+)\-file\.jpg$#uD', $file->getFilename(), $details) === 1) {
printf('<div><img src="%s" alt="Picture of %s">%s</div>',
htmlentities( '/web/path/to/images/' . $details[0] ),
htmlentities( $details[1] ),
htmlentities( $details[1] )
);
}
}
<?php
$directory_to_read_from = './imgage_directory';
if ($handle = opendir($directory_to_read_from))
{
while (false !== ($entry = readdir($handle)))
{
if ($entry != "." && $entry != "..")
{
$name = explode('-', $entry);
echo '<h1>' . $name[0] . "</h1><img src='$directory_to_read_from/$entry' /><br>";
}
}
closedir($handle);
}
OUTPUT:

Listing directory contents with unusual characters file names

The following code is for listing every file and folder of a directory in alphabetical order, and it works perfectly ... almost.
<?php
$files = array();
$dir = opendir('.');
while(false != ($file = readdir($dir))) {
if(($file != ".")and ($file != "..") and ($file != "index.php")) {
$files[] = $file;
}
}
natsort($files);
foreach($files as $file) {
echo("<li><a href='$file'>$file</a>");
}
?>
The situation is that my files and folders have some strange characters in their names, like é, ï, être.htm, écouter.txt, etc. When I click on the links listed by the code above the links containing non Ascii characters lead to error 404 and the target is not opened, whereas the links with no strange characteres are fully operational.
Can you please tell me how to solve this?
Try this
echo("<li><a href='".url_encode($file)."'>$file</a>");
You said that spaces were a problem but url_encode would've made the space a %20 so I'm not sure why you have an issue
Solution:
`echo("<li><a href='".rawurlencode($file)."'>$file</a>");`
RFC 3986 - space replaced with %20
Found the solution myself and thanks to «Forbs».
When extracting or getting the URL path of a file ($file in the code above) I followed two steps: The use of urlencode($file) and str_replace("+", "%20", $url). The reason for this is that urlencode is perfect for changing unusual characters for the proper URL encoding, but this function also replaces the spaces in the URL path for a plus sign (+). Therefore, you need to use str_replace("+", "%20", $url) to replace every plus sign for the right URL encoding: %20.
So, here is the final PHP programming for listing the contents of a folder with unusual characters in file names (e.g. être.txt, écouter.php, canción.mp3).
DIRECTORY LISTING
<?php
$files = array();
$dir = opendir('.');
while(false != ($file = readdir($dir))) {
if(($file != ".") and ($file != "..") and ($file != "index.php"))
{
$files[] = $file;
}
}
natsort($files);
foreach($files as $file)
{
$url_1 = urlencode($file);
$url_2 = str_replace("+", "%20", $url_1);
echo "<li><a href='".$url_2."'>".$file."</a></li>";
}
?>
That's it. I hope it's of some use.

Rename files increasing as they upload - PHP

I need to give incresing number to files as the upload. I am usinf SFWUpload. I have this code:
mkdir("../../imagenes/".$codigo , 0777);
$i = 1;
$nombre = $codigo.'_'.$i.'.jpg';
move_uploaded_file($_FILES['Filedata']['tmp_name'], "../../imagenes/".$codigo."/".$nombre);
chmod("../../imagenes/".$codigo."/".$_FILES['Filedata']['name'], 0777);
The $codigo is the code, for example 101213, so i need the pictures to upload like 101213_1.jpg, 101213_2.jpg, 101213_3.jpg, and so on.
The problem is that SWFUpload runs the php ONCE per picture, so i can not use a foreach loop (I guess).
I need the script to check if the file exists and write the next. For example, if 101213_4.jpg exists, then write 101213_5.jpg.
Can you help me how can I do this.?? I am novice at php, and tried everything.! :(
Thanks in advance
Roberto
Here's a function I use:
function cleanup_name($name){ //accepts name and cleans it up.
$finalDir='/home/username/uploads';
# Go to all lower case for consistency
$name = strtolower($name);
//echo("Name is $name<br>");
$matches=split('\.',$name);
foreach ($matches as $key=>$value){
$exkey=$key;
$exvalue=$value; //if there is more than one period, this will find the actual extension.
//echo("Key $key|$exkey Value $value|$exvalue<br>");
}
if ($exkey<1){die('The file must have an extension.');}
$extension=".".$exvalue;
$loop=0;
while ($loop<($exkey)){
if ($loop<($exkey-1)){$matches[$loop]=".".$matches[$loop];} // this puts extra periods back into the string, but the borrowed code will replace them with underscores.
$stem.=$matches[$loop];
$loop++;
}
//echo("Stem is $stem<br>");
//echo("Extension is $extension<br>");
# Convert whitespace of any kind to single underscores
$stem = preg_replace('/\s+/', '_', $stem);
# Remove any remaining characters other than A-Z, a-z, 0-9 and _
$stem = preg_replace('/[^\w]/', '', $stem);
# Make sure the file extension has no odd characters
if (($extension != '') &&
(!preg_match('/^\.\w+$/', $extension)))
{
echo("odd characters in extension");
//die("Bad file extension");
return FALSE;
}
$safeExtensions = array(
'.zip',
'.psd',
'.pdf',
'.jpg',
'.jpeg',
'.gif',
'.rar',
'.gz',
'.ai',
'.eps',
'.bmp',
'.pub',
'.xls',
'.doc',
'.wpd',
'.rtf',
'.tiff',
'.tif',
'.pcx',
'.ttf',
'.png',
'.txt',
'.mp3',
'.avi',
'.mov',
'.wav'
);
if (!in_array($extension, $safeExtensions)) {
echo("Extension "$extension" not approved.");
//die("File extension not approved");
return FALSE;
}
# Search for a unique filename by adding a number to the
# stem (first we try without, of course)
$suffix = '';
while (file_exists($finalDir."/".$stem.$suffix.$extension)) {
if ($suffix == '') {
$suffix = '0';
} else {
$suffix++;
}
}
# Put the full name back together
$name = "$stem$suffix$extension";
return $name;
}
Pay special attention to the section with this: " while (file_exists..."
Well... you can try to get the current number of files on the folder and get $i from there:
mkdir("../../imagenes/".$codigo , 0777);
$i = count(glob("../../imagenes/".$codigo.'_*.jpg')) + 1;
$nombre = $codigo.'_'.$i.'.jpg';
move_uploaded_file($_FILES['Filedata']['tmp_name'], "../../imagenes/".$codigo."/".$nombre);
chmod("../../imagenes/".$codigo."/".$nombre, 0777);
Try that code...

How to remove extension from string (only real extension!)

I'm looking for a small function that allows me to remove the extension from a filename.
I've found many examples by googling, but they are bad, because they just remove part of the string with "." . They use dot for limiter and just cut string.
Look at these scripts,
$from = preg_replace('/\.[^.]+$/','',$from);
or
$from=substr($from, 0, (strlen ($from)) - (strlen (strrchr($filename,'.'))));
When we add the string like this:
This.is example of somestring
It will return only "This"...
The extension can have 3 or 4 characters, so we have to check if dot is on 4 or 5 position, and then remove it.
How can it be done?
http://php.net/manual/en/function.pathinfo.php
pathinfo — Returns information about a file path
$filename = pathinfo('filename.md.txt', PATHINFO_FILENAME); // returns 'filename.md'
Try this one:
$withoutExt = preg_replace('/\\.[^.\\s]{3,4}$/', '', $filename);
So, this matches a dot followed by three or four characters which are not a dot or a space. The "3 or 4" rule should probably be relaxed, since there are plenty of file extensions which are shorter or longer.
From the manual, pathinfo:
<?php
$path_parts = pathinfo('/www/htdocs/index.html');
echo $path_parts['dirname'], "\n";
echo $path_parts['basename'], "\n";
echo $path_parts['extension'], "\n";
echo $path_parts['filename'], "\n"; // Since PHP 5.2.0
?>
It doesn't have to be a complete path to operate properly. It will just as happily parse file.jpg as /path/to/my/file.jpg.
Use PHP basename()
(PHP 4, PHP 5)
var_dump(basename('test.php', '.php'));
Outputs: string(4) "test"
This is a rather easy solution and will work no matter how long the extension or how many dots or other characters are in the string.
$filename = "abc.def.jpg";
$newFileName = substr($filename, 0 , (strrpos($filename, ".")));
//$newFileName will now be abc.def
Basically this just looks for the last occurrence of . and then uses substring to retrieve all the characters up to that point.
It's similar to one of your googled examples but simpler, faster and easier than regular expressions and the other examples. Well imo anyway. Hope it helps someone.
Recommend use: pathinfo with PATHINFO_FILENAME
$filename = 'abc_123_filename.html';
$without_extension = pathinfo($filename, PATHINFO_FILENAME);
You could use what PHP has built in to assist...
$withoutExt = pathinfo($path, PATHINFO_DIRNAME) . '/' . pathinfo($path, PATHINFO_FILENAME);
Though if you are only dealing with a filename (.somefile.jpg), you will get...
./somefile
See it on CodePad.org
Or use a regex...
$withoutExt = preg_replace('/\.' . preg_quote(pathinfo($path, PATHINFO_EXTENSION), '/') . '$/', '', $path);
See it on CodePad.org
If you don't have a path, but just a filename, this will work and be much terser...
$withoutExt = pathinfo($path, PATHINFO_FILENAME);
See it on CodePad.org
Of course, these both just look for the last period (.).
The following code works well for me, and it's pretty short. It just breaks the file up into an array delimited by dots, deletes the last element (which is hypothetically the extension), and reforms the array with the dots again.
$filebroken = explode( '.', $filename);
$extension = array_pop($filebroken);
$fileTypeless = implode('.', $filebroken);
I found many examples on the Google but there are bad because just remove part of string with "."
Actually that is absolutely the correct thing to do. Go ahead and use that.
The file extension is everything after the last dot, and there is no requirement for a file extension to be any particular number of characters. Even talking only about Windows, it already comes with file extensions that don't fit 3-4 characters, such as eg. .manifest.
There are a few ways to do it, but i think one of the quicker ways is the following
// $filename has the file name you have under the picture
$temp = explode( '.', $filename );
$ext = array_pop( $temp );
$name = implode( '.', $temp );
Another solution is this. I havent tested it, but it looks like it should work for multiple periods in a filename
$name = substr($filename, 0, (strlen ($filename)) - (strlen (strrchr($filename,'.'))));
Also:
$info = pathinfo( $filename );
$name = $info['filename'];
$ext = $info['extension'];
// Or in PHP 5.4, i believe this should work
$name = pathinfo( $filename )[ 'filename' ];
In all of these, $name contains the filename without the extension
$image_name = "this-is.file.name.jpg";
$last_dot_index = strrpos($image_name, ".");
$without_extention = substr($image_name, 0, $last_dot_index);
Output:
this-is.file.name
As others mention, the idea of limiting extension to a certain number of characters is invalid. Going with the idea of array_pop, thinking of a delimited string as an array, this function has been useful to me...
function string_pop($string, $delimiter){
$a = explode($delimiter, $string);
array_pop($a);
return implode($delimiter, $a);
}
Usage:
$filename = "pic.of.my.house.jpeg";
$name = string_pop($filename, '.');
echo $name;
Outputs:
pic.of.my.house (note it leaves valid, non-extension "." characters alone)
In action:
http://sandbox.onlinephpfunctions.com/code/5d12a96ea548f696bd097e2986b22de7628314a0
This works when there is multiple parts to an extension and is both short and efficient:
function removeExt($path)
{
$basename = basename($path);
return strpos($basename, '.') === false ? $path : substr($path, 0, - strlen($basename) + strlen(explode('.', $basename)[0]));
}
echo removeExt('https://example.com/file.php');
// https://example.com/file
echo removeExt('https://example.com/file.tar.gz');
// https://example.com/file
echo removeExt('file.tar.gz');
// file
echo removeExt('file');
// file
You can set the length of the regular expression pattern by using the {x,y} operator. {3,4} would match if the preceeding pattern occurs 3 or 4 times.
But I don't think you really need it. What will you do with a file named "This.is"?
Landed on this page for looking for the fastest way to remove the extension from a number file names from a glob() result.
So I did some very rudimentary benchmark tests and found this was the quickest method. It was less than half the time of preg_replace():
$result = substr($fileName,0,-4);
Now I know that all of the files in my glob() have a .zip extension, so I could do this.
If the file extension is unknown with an unknown length, the following method will work and is still about 20% faster that preg_replace(). That is, so long as there is an extension.
$result = substr($fileName,0,strrpos($fileName,'.'));
The basic benchmark test code and the results:
$start = microtime(true);
$loop = 10000000;
$fileName = 'a.LONG-filename_forTest.zip';
$result;
// 1.82sec preg_replace() unknown ext
//do {
// $result = preg_replace('/\\.[^.\\s]{3,4}$/','',$fileName);
//} while(--$loop);
// 1.7sec preg_replace() known ext
//do {
// $result = preg_replace('/.zip$/','',$fileName);
//} while(--$loop);
// 4.57sec! - pathinfo
//do {
// $result = pathinfo($fileName,PATHINFO_FILENAME);
//} while(--$loop);
// 2.43sec explode and implode
//do {
// $result = implode('.',explode('.',$fileName,-1));
//} while(--$loop);
// 3.74sec basename, known ext
//do {
// $result = basename($fileName,'.zip');
//} while(--$loop);
// 1.45sec strpos unknown ext
//do {
// $result = substr($fileName,0,strrpos($fileName,'.'));
//} while(--$loop);
// 0.73sec strpos - known ext length
do {
$result = substr($fileName,0,-4);
} while(--$loop);
var_dump($fileName);
var_dump($result);
echo 'Time:['.(microtime(true) - $start).']';
exit;
Use this:
strstr('filename.ext','.',true);
//result filename
Try to use this one. it will surely remove the file extension.
$filename = "image.jpg";
$e = explode(".", $filename);
foreach($e as $key=>$d)
{
if($d!=end($e)
{
$new_d[]=$d;
}
}
echo implode("-",$new_t); // result would be just the 'image'
EDIT:
The smartest approach IMHO, it removes the last point and following text from a filename (aka the extension):
$name = basename($filename, '.' . end(explode('.', $filename)));
Cheers ;)

auto display filename in a directory and auto fill it as value

I want something (final) like this :
<?php
//named as config.php
$fn[0]["long"] = "file name"; $fn[0]["short"] = "file-name.txt";
$fn[1]["long"] = "file name 1"; $fn[1]["short"] = "file-name_1.txt";
?>
What that I want to?:
1. $fn[0], $fn[1], etc.., as auto increasing
2. "file-name.txt", "file-name_1.txt", etc.., as file name from a directory, i want it auto insert.
3. "file name", "file name 1", etc.., is auto split from "file-name.txt", "file-name_1.txt", etc..,
and config.php above needed in another file e.g.
<? //named as form.php
include "config.php";
for($tint = 0;isset($text_index[$tint]);$tint++)
{
if($allok === TRUE && $tint === $index) echo("<option VALUE=\"" . $text_index[$tint]["short"] . "\" SELECTED>" . $text_index[$tint]["long"] . "</option>\n");
else echo("<option VALUE=\"" . $text_index[$tint]["short"] . "\">" . $text_index[$tint]["long"] . "</option>\n");
} ?>
so i try to search and put php code and hope it can handling at all :
e.g.
<?php
$path = ".";
$dh = opendir($path);
//$i=0;
$i= 1;
while (($file = readdir($dh)) !== false) {
if($file != "." && $file != "..") {
echo "\$fn[$i]['short'] = '$file'; $fn[$i]['long'] = '$file(splited)';<br />"; // Test
$i++;
}
}
closedir($dh);
?>
but i'm wrong, the output is not similar to what i want, e.g.
$fn[0]['short'] = 'file-name.txt'; ['long'] = 'file-name.txt'; //<--not splitted
$fn[1]['short'] = 'file-name_1.txt'; ['long'] = 'file-name_1.txt'; //<--not splitted
because i am little known with php so i don't know how to improve code more, there are any good tips of you guys could help me, Please
New answer after OP edited his question
From your edited question, I understand you want to dynamically populate a SelectBox element on an HTML webpage with the files found in a certain directory for option value. The values are supposed to be split by dash, underscore and number to provide the option name, e.g.
Directory with Files > SelectBox Options
filename1.txt > value: filename1.txt, text: Filename 1
file_name2.txt > value: filename1.txt, text: File Name 2
file-name3.txt > value: filename1.txt, text: File Name 3
Based from the code I gave in my other answer, you could achieve this with the DirectoryIterator like this:
$config = array();
$dir = new DirectoryIterator('.');
foreach($dir as $item) {
if($item->isFile()) {
$fileName = $item->getFilename();
// turn dashes and underscores to spaces
$longFileName = str_replace(array('-', '_'), ' ', $fileName);
// prefix numbers with space
$longFileName = preg_replace('/(\d+)/', ' $1', $fileName);
// add to array
$config[] = array('short' => $filename,
'long' => $longFilename);
}
}
However, since filenames in a directory are unique, you could also use this as an array:
$config[$filename] => $longFilename;
when building the config array. The short filename will form the key of the array then and then you can build your selectbox like this:
foreach($config as $short => $long)
{
printf( '<option value="%s">%s</option>' , $short, $long);
}
Alternatively, use the Iterator to just create an array of filenames and do the conversion to long file names when creating the Selectbox options, e.g. in the foreach loop above. In fact, you could build the entire SelectBox right from the iterator instead of building the array first, e.g.
$dir = new DirectoryIterator('.');
foreach($dir as $item) {
if($item->isFile()) {
$fileName = $item->getFilename();
$longFileName = str_replace(array('-', '_'), ' ', $fileName);
$longFileName = preg_replace('/(\d+)/', ' $1', $fileName);
printf( '<option value="%s">%s</option>' , $fileName, $longFileName);
}
}
Hope that's what your're looking for. I strongly suggest having a look at the chapter titled Language Reference in the PHP Manual if you got no or very little experience with PHP so far. There is also a free online book at http://www.tuxradar.com/practicalphp
Use this as the if condition to avoid the '..' from appearing in the result.
if($file != "." && $file != "..")
Change
if($file != "." ) {
to
if($file != "." and $file !== "..") {
and you get the behaviour you want.
If you read all the files from a linux environment you always get . and .. as files, which represent the current directory (.) and the parent directory (..). In your code you only ignore '.', while you also want to ignore '..'.
Edit:
If you want to print out what you wrote change the code in the inner loop to this:
if($file != "." ) {
echo "\$fn[\$i]['long'] = '$file'<br />"; // Test
$i++;
}
If you want to fill an array called $fn:
if($file != "." ) {
$fn[]['long'] = $file;
}
(You can remove the $i, because php auto increments arrays). Make sure you initialize $fn before the while loop:
$fn = array();
Have a look at the following functions:
glob — Find pathnames matching a pattern
scandir — List files and directories inside the specified path
DirectoryIterator — provides a simple interface for viewing the contents of filesystem directories
So, with the DirectoryIterator you simply would do:
$dir = new DirectoryIterator('.');
foreach($dir as $item) {
if($item->isFile()) {
echo $file;
}
}
Notice how every $item in $dir is an SplFileInfo instance and provides access to a number of useful other functions, e.g. isFile().
Doing a recursive directory traversal is equally easy. Just use a RecursiveDirectoryIterator with a RecursiveIteratorIterator and do:
$dir = new RecursiveIteratorIterator(new RecursiveDirectoryIterator('.'));
foreach($dir as $item) {
echo $file;
}
NOTE I am afraid I do not understand what the following line from your question is supposed to mean:
echo "$fn[$i]['long'] = '$file'<br />"; // Test
But with the functions and example code given above, you should be able to do everything you ever wanted to do with files inside directories.
I've had the same thing happen. I've just used array_shift() to trim off the top of the array
check out the documentation. http://ca.php.net/manual/en/function.array-shift.php

Categories