p2p.wrox.com Forums

Need to download code?

View our list of code downloads.


  Return to Index  

beginning_php thread: Replace function


Message #1 by Jefferis Peterson <jefferis@p...> on Tue, 08 Oct 2002 14:31:10 -0400
I'm trying to strip out "images/" and .jpg or .gif from a string  called
$img but I'm getting an error on the comma in line 1:


<?php $iden = str_replace(("images\/") || (".jpg") || (".gif")), "",$img);
echo $iden;
?>

The item might be "images/R-02-2.jpg"

Any  idea what I'm doing wrong?


Jeff


~~~~~~~~~~~~
Jefferis Peterson, Pres.
Web Design and Marketing
http://www.PetersonSales.net
Tel .  xxx-xxx-xxxx
ICQ 19112253

http://www.Slippery-Rock.com - 7,000 hits per year

Message #2 by "Nikolai Devereaux" <yomama@u...> on Tue, 8 Oct 2002 12:07:01 -0700
Yeah, you have an extra close-paren in your function def.

Lemme show you:

str_replace(("images\/") || (".jpg") || (".gif")), "",$img);

str_replace((A) || (B) || (C)), "", $img);

See it after (C)?


Now a couple of unasked for comments, in true Nik style. =)


First off, You don't need to escape the forward-slash in a string.

Next, you're not using str_replace correctly.  You can see in the simplified
version that you're creating a boolean expression.


str_replace() expects a string as it's first pattern.  You're passing a boolean
expression, which evaluates to either true or false.  When PHP encounters this
value, it converts it into a string.  True becomes "1" and false becomes the
empty string.

Since non-empty strings (in boolean contexts) evaluate to true, you're really
calling this function:

str_replace("1", "", $img);

I bet that if $img was "images/testing1.1.php", you'd end up with
"images/testing..php".


If you're passing a pattern, you need to use a regex function like ereg_replace
or, preferrably, preg_replace.

This should work, for example:

$txt = preg_replace('!(images/)|(\.jpg)|(\.gif)!', '', $img);


Lastly, there are built-in functions that do this for you:
  http://www.php.net/basename

$file = basename($img, '.gif');
$file = basename($img, '.jpg');



Take care,

nik





Message #3 by Jefferis Peterson <jefferis@p...> on Tue, 08 Oct 2002 15:26:27 -0400
I knew there had to be a simpler way :-)

However, this works to strip the prefix but not the suffix:

> <?php $iden= basename($img, '.gif');
> $iden = basename($img, '.jpg');
> $iden = basename($img, 'images/');
> ?> 
> <HTML>
> <HEAD> 
> 
> <script language="JavaScript" type="text/JavaScript">
  > <TITLE>Large View of <?php echo $iden; ?></TITLE> On 10/8/02 3:07 PM,


What happens is that images/R-59B-02.jpg prints as
"Large View of Item no. R-59B-02.jpg"  or .gif, if the item is a gif.

Does only the last function work?



"Nikolai 
> Devereaux" <yomama@u...> wrote:

> If you're passing a pattern, you need to use a regex function like
> ereg_replace
> or, preferrably, preg_replace.
> 
> This should work, for example:
> 
> $txt = preg_replace('!(images/)|(\.jpg)|(\.gif)!', '', $img);
> 
> 
> Lastly, there are built-in functions that do this for you:
> http://www.php.net/basename
> 
> $file = basename($img, '.gif');
> $file = basename($img, '.jpg');
> 
> 
> 
> Take care,
> 
> nik

~~~~~~~~~~~~
Jefferis Peterson, Pres.
Web Design and Marketing
http://www.PetersonSales.net
Tel .  xxx-xxx-xxxx
ICQ 19112253

http://www.Slippery-Rock.com - 7,000 hits per year

Message #4 by "Nikolai Devereaux" <yomama@u...> on Tue, 8 Oct 2002 12:42:30 -0700
> However, this works to strip the prefix but not the suffix:

Hmm, that's weird.  basename() strips the path leading up to the filename,
regardless of what you pass as the second parameter.  The optional second
parameter specifies the suffix, if any, you'd like stripped as well.

> <?php $iden= basename($img, '.gif');
> $iden = basename($img, '.jpg');
> $iden = basename($img, 'images/');
> ?>


Okay, I see what you're doing -- you're overwriting the value of $iden each
time, but you're never changing $img.

This is yet another example of when it's useful to do draw out the state of
variables by hand (use a debugger, if you're more comfortable, but doing it by
hand really hammers in what's happening).

I'll show you.

Lines:
1: $iden= basename($img, '.gif');
2: $iden = basename($img, '.jpg');
3: $iden = basename($img, 'images/');


      \ vars:      $img           |  $iden
values  \  +----------------------+---------------
at line # \|                      |
           |                      |
    1      | /images/R-69B-02.jpg | R-69B-02.jpg
           |                      |
    2      | /images/R-69B-02.jpg | R-69B-02
           |                      |
    3      | /images/R-69B-02.jpg | R-69B-02.jpg
           |                      |
-----------+----------------------+---------------


See what I mean?

You should rewrite your code to look like this:

$iden = basename($img,  '.jpg');
$iden = basename($iden, '.gif');


See how we use $iden as the source string in the second call to basename?

This is streamlined a little bit by chaining the calls together:

$iden = basename(basename($img, '.gif'), '.jpg');


Hope this clears things up!

nik

Message #5 by Jefferis Peterson <jefferis@p...> on Tue, 08 Oct 2002 16:10:44 -0400
On 10/8/02 3:42 PM, "Nikolai Devereaux" <yomama@u...> wrote:

> You should rewrite your code to look like this:
> 
> $iden = basename($img,  '.jpg');
> $iden = basename($iden, '.gif');
> 
> 
> See how we use $iden as the source string in the second call to basename?
> 
> This is streamlined a little bit by chaining the calls together:
> 
> $iden = basename(basename($img, '.gif'), '.jpg');
> 
> 
> Hope this clears things up!
> 
> nik

Thanks Nik,  

This worked:
<?php $id1 = basename($img, '.gif');
$id2 = basename($id1, '.jpg');
$iden = basename($id2, 'images/');
?> 

This did not:
> $iden = basename(basename($img, '.gif'), '.jpg');

~~~~~~~~~~~~
Jefferis Peterson, Pres.
Web Design and Marketing
http://www.PetersonSales.net
Tel .  xxx-xxx-xxxx
ICQ 19112253

http://www.Slippery-Rock.com - 7,000 hits per year

Message #6 by "Nikolai Devereaux" <yomama@u...> on Tue, 8 Oct 2002 13:40:50 -0700
> This worked:
> <?php $id1 = basename($img, '.gif');
> $id2 = basename($id1, '.jpg');
> $iden = basename($id2, 'images/');
> ?>

That looks fine, but my problem with it is that you're creating too many
temporary variables that are never used outside the scope of that little code
block.

You'll end up using slightly less memory and your script will be more efficient
(since the garbage collector/reference counter has less things to keep track
of) if you just stick with two variables:

$iden = basename($img,  '.gif');
$iden = basename($iden, '.jpg');


> This did not:
> > $iden = basename(basename($img, '.gif'), '.jpg');

Weird... works for me:

----- bn.php -------
<?php
$img = 'images/1_2_3_test_4.gif';

echo "Chained basenames:\n";
echo "img is $img\n";
echo "basename is " . basename(basename($img, '.jpg'), '.gif');
?>
--------------------

----- Output: ------
Chained basenames:
img is images/1_2_3_test_4.gif
basename is 1_2_3_test_4
----------------------------

take care,

nik

Message #7 by Jefferis Peterson <jefferis@p...> on Tue, 08 Oct 2002 16:51:41 -0400
On 10/8/02 4:40 PM, "Nikolai Devereaux" <yomama@u...> wrote:

> $iden = basename($img,  '.gif');
> $iden = basename($iden, '.jpg');
 but then it seemed to lose it on the last one:

> $iden = basename($id2, 'images/');

Since is was reintroducing $iden again.  You said that it was creating the
problem when I kept using $img...


~~~~~~~~~~~~
Jefferis Peterson, Pres.
Web Design and Marketing
http://www.PetersonSales.net
Tel .  xxx-xxx-xxxx
ICQ 19112253

http://www.Slippery-Rock.com - 7,000 hits per year

Message #8 by "Nikolai Devereaux" <yomama@u...> on Tue, 8 Oct 2002 14:11:44 -0700
I'm sorry, Jeff, you totally lost me on that last one.

Can you rephrase that for me?

> > $iden = basename($img,  '.gif');
> > $iden = basename($iden, '.jpg');
>  but then it seemed to lose it on the last one:
>
> > $iden = basename($id2, 'images/');
>
> Since is was reintroducing $iden again.  You said that it was creating the
> problem when I kept using $img...


The reason this works:

$iden = basename($img,  '.gif');
$iden = basename($iden, '.jpg');

is because after the first line, $iden holds the result of the first basename
call, which would've stripped the path and, if the extension was .gif, that as
well.  If the file was a .jpg, then $iden would still have the .jpg suffix.

The second call to basename accepts $iden as the parameter, which has already
been trimmed as described above.  If the image was a gif, then this call to
basename() returns $iden unchanged -- the path is already gone, and the .gif
was removed on the previous line.  If, on the other hand, the image was a jpg,
then this call to basename will strip the .jpg suffix.

Leaving you with just the filename without a path or extension.


About basename(basename($img, '.gif'), '.jpg'):

The reason the chained method works is because basename() *returns* the
modified string, it doesn't modify the source string.

When PHP encounters a function call, it has to evaluate all the parameters
before calling the function.  This is really similar to when you were passing
(A) || (B) || (C) to str_replace.  Since that was an expression, it was
evaluated to a boolean result and converted to a string before str_replace was
actually called.

In this case, the inner call to basename() must be executed, and its result
string value (the first stripped string described above) is passed to the outer
call to basename() as the first parameter.


Nik

Message #9 by Jefferis Peterson <jefferis@p...> on Tue, 08 Oct 2002 19:21:16 -0400
If the path consists only if images/


Is that enough to be considered a path and stripped?


Jeff


On 10/8/02 5:11 PM, "Nikolai Devereaux" <yomama@u...> wrote:

> If the image was a gif, then this call to
> basename() returns $iden unchanged -- the path is already gone, and the .gif
> was removed on the previous line.  If, on the other hand, the image was a jpg,
> then this call to basename will strip the .jpg suffix.
> 
> Leaving you with just the filename without a path or extension.

~~~~~~~~~~~~
Jefferis Peterson, Pres.
Web Design and Marketing
http://www.PetersonSales.net
Tel .  xxx-xxx-xxxx
ICQ 19112253

http://www.Slippery-Rock.com - 7,000 hits per year

Message #10 by "Nikolai Devereaux" <yomama@u...> on Tue, 8 Oct 2002 16:45:35 -0700
> If the path consists only if images/
>
>
> Is that enough to be considered a path and stripped?


That's an interesting question because it illustrates some slightly confusing
behavior with basename().

When you pass a directory path to basename (whether or not the trailing slash
is there), basename returns the name of the bottom most directory.

Examples:

// command                                output

echo basename('/my/dir/is/images');    // images
echo basename('/my/dir/is/images/');   // images
echo basename('/images');              // images
echo basename('/images/');             // images
echo basename('images/');              // images


The reasoning behind this may be that, technically speaking, directories *ARE*
files, they're just a special kind of file.

Since basename() expects a string which is a path to a filename, it returns the
last filename in the string.


dirname() also has some weird behavior when you pass a path that ends with a
directory (trailing slash or not).

nik


  Return to Index