30

How would I insert "_thumb" into files that are being dyanmically generated.

For example, I have a site that allows users to upload an image. The script takes the image, optimizes it and saves to file. How would I make it insert the string "_thumb" for the optimized image?

I'm currently saving 1 version of the otpimized file. ch-1268312613-photo.jpg

I want to save the original as the above string, but want to append, "_thumb" like the following string ch-1268312613-photo_thumb.jpg

8 Answers 8

45

No need to use regex. This will do it:

$extension_pos = strrpos($filename, '.'); // find position of the last dot, so where the extension starts
$thumb = substr($filename, 0, $extension_pos) . '_thumb' . substr($filename, $extension_pos);
Sign up to request clarification or add additional context in comments.

2 Comments

wont for such thing as .tar.gz
20

Rather than take the regular expression route (or other crude string manipulation) perhaps some filename-related functions might be easier to live with: namely pathinfo (to get the file extension) and basename (to get the filename minus extension).

$ext   = pathinfo($filename, PATHINFO_EXTENSION);
$thumb = basename($filename, ".$ext") . '_thumb.' . $ext;

Edit: @tanascius sorry for the very similar answer, guess I should've checked the little pop-up whilst writing this (it took a while, I got distracted).

1 Comment

Not quite worthy of a new answer but this can be one line: pathinfo($filename,8) . '_thumb.' . pathinfo($filename,4);
5

Why do you want to use a RegEx? Is the extension always .jpg and is there only one extension? Maybe you can replace it by _thumb.jpg?

If it is not that simple, you can use a function like pathinfo to extract the basename + extension and do a replace there. That is working without a regex, too, which might be overkill here:

$info = pathinfo( $file );
$no_extension =  basename( $file, '.'.$info['extension'] );
echo $no_extension.'_thumb.'.$info['extension']

Comments

3

Assuming you only have the occurrence of ".jpg" once in the string, you can do a str_replace instead of regex

$filename = str_replace(".jpg", "_thumb.jpg", $filename);

or even better, substr_replace to just insert the string somewhere in the middle:

$filename = substr_replace($filename, '_thumb', -4, 0);

Comments

3
 preg_replace("/(\w+)\.(\w+)/","'\\1_thumb.\\2'","test.jpg"); 

I think that using a regexp is far more speed effective AND really better for flexibility.

But I admit Chad's solution is elegant and effective

3 Comments

There are a couple things wrong with this. You didn't escape the period in the pattern, so that will match any character at all. Also, \w does not cover all possible filename characters.
True, because I didn't mark it as code so \. was interpreted like . And True again but does the filesystem has the right to use any char, I bet no
Good one! But I'd do it like so: preg_replace("/^(.+)\.(\w+)$/","\\1_thumb.\\2",$filename); -- check with "local.server.com/wp-content/uploads/2017/07/filename.jpg"
1
$str = "ch-1268312613-photo.jpg";
print preg_replace("/\.jpg$/i","_thumb.jpg",$str);

Comments

1

This is fast and can correct to show it,

/**
* 增加後綴字至檔名後方
* Add suffix to a file name
* 
* @example suffixFileName("test.tar.gz", '_new'); //it will retrun "test.tar_new.gz"
* @version 2023.06.20 Jwu
* @param string $fullPath filename
* @param string $suffix   insert String Before File Extension
*
* @return string new file path
*/
function suffixFileName($fullPath, $suffix = "_thumb"){
    $pos = strrpos($fullPath, ".");
    if(substr($fullPath, -1) == '.'){
        $pos = strrpos(substr($fullPath, 0, $pos), ".");
    }
    if ($pos === false) {
        return $fullPath . $suffix;
    }
    //$filenameWithoutExt = substr($fileName, 0, -(strlen($pos) + 2));
    return substr_replace($fullPath, $suffix, $pos, 0);
}

Test Demo:

// Unit Test
function output($n){
    print_r($n);
    print_r('<br>');
    print_r(suffixFileName($n, "_thumb"));
    print_r('<hr>');
}
$testFiles = array(
    'C:\Jwu\TestPictures\sample.jpg',
    'http://Jwu/TestPictures/sample.jpg',
    'TestPictures\this.is.a.jpg',
    'sample.tar.gz',
    '1.jpg',
    '.jpg',
    'recent.image.jpg.',
    'image.gift.1234.gif'
);
array_map('output', $testFiles);

Output:

C:\Jwu\TestPictures\sample.jpg
C:\Jwu\TestPictures\sample_thumb.jpg

http://Jwu/TestPictures/sample.jpg
http://Jwu/TestPictures/sample_thumb.jpg

TestPictures\this.is.a.jpg
TestPictures\this.is.a_thumb.jpg

sample.tar.gz
sample.tar_thumb.gz

1.jpg
1_thumb.jpg

.jpg
_thumb.jpg

recent.image.jpg.
recent.image_thumb.jpg.

image.gift.1234.gif
image.gift.1234_thumb.gif

Comments

-1

Assuming you are wanting to inject your substring just before the first occurring dot, preg_replace() is a direct technique. Using a start of string anchor and a negated character class in the pattern, there can only be one replacement at most. Because \K restarts the fullstring match, the replacement string only replaces the literal dot that is matched.

Code: (Demo)

$strings = [
    "ch-1268312613-photo.jpg",
    "foo.inc.php",
    ".htaccess",
    "no_ext",
];

var_export(
    preg_replace(
        '~^[^.]*\K\.~',
        '_thumb.',
        $strings
    )
);

Output:

array (
  0 => 'ch-1268312613-photo_thumb.jpg',
  1 => 'foo_thumb.inc.php',
  2 => '_thumb.htaccess',
  3 => 'no_ext',
)

Just for fun, these 2-call techniques also work: (Demo)

echo implode('_thumb.', explode('.', $string, 2));

and

echo implode('_thumb', sscanf($string, '%[^.]%s'));

1 Comment

Any comment to accompany the dv on my answer which is proven to work correctly?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.