2

Really quick noob question with php:

I'm trying to create a conditional statement where I can check if a variable partially matches a substring.

More specific in my case:

$cal is the name of a file, I want it so if $cal contains ".cfg" it echos some text.

pseudocode:

<?php if ($cal == "*.cfg")
 {
    echo "Hello ";
 }
?> 
dukevin
  • 22,384
  • 36
  • 82
  • 111

5 Answers5

6
if (strpos($cal, ".cfg") !== false)
{
  echo "some text";
}

EDIT

My proposal for matching exactly "*.cfg":

$cal = "abc.cfgxyz";
$ext = "cfg";

if (strrpos($cal, ".".$ext) === strlen($cal)-strlen($ext)-1)
{
    echo "matched";
}
Maxime Pacary
  • 22,336
  • 11
  • 85
  • 113
  • He said it only had to match .cfg. He didn't say anything about it not matching stuff that doesn't end in .cfg. So it matches the specifications given in the question. – GordonM Apr 12 '11 at 10:25
  • @Gordon Well, in the words. The code example uses `*.cfg`, which suggests the OP wanted to test the end of the string. – lonesomeday Apr 12 '11 at 10:27
  • @mvds: If you find it too ugly / unreadable, you can wrap it in any function/method you want, and write for example `if (match_extension($filename, $ext)) { ... }` instead. – Maxime Pacary Apr 12 '11 at 10:33
  • @Frosty: Once you put `strrpos`, `strlen` and (again) `strlen` in one line, it's time to consider a regexp. This is really hard to maintain or understand. – mvds Apr 12 '11 at 10:39
  • 1
    @mvds: The readability argument sounds valid to me. Plus, a few quick benchmarks show that `preg_match` can be a reasonable alternative here, unless an "extreme" use leads to the feared performance issue: 10000 iterations on my "EDIT" answer need around 20 milliseconds, and with `preg_match` 38 ms. Adding 3-4 `strlen` or `strpos` simple calls to my answer easily reaches 40 ms (Intel Core 2 Duo 3.16 GHz, 4GB RAM). However, when a simple `strpos` use is efficient and readable enough, I would prefer it (just for information: 13 ms for my inital answer). – Maxime Pacary Apr 12 '11 at 11:18
3
if ( preg_match('/\\.cfg$/',$cal) ) echo "Hello ";

should to it. (Assuming you want to match the end of the input string, otherwise, leave out the $)

mvds
  • 45,755
  • 8
  • 102
  • 111
  • Shouldn't it be \.cfg instead of \\.cfg? – fresskoma Apr 12 '11 at 10:24
  • Might be, but worth a downvote?! I thought downvotes were for blatantly wrong answers. – mvds Apr 12 '11 at 10:26
  • @x3ro: `\.cfg` will work because `.` doesn't need escaping, but technically the backslash needs escaping. (this is just like `"$"` will contain a literal `$`, which I think is not something to rely on) – mvds Apr 12 '11 at 10:28
  • 1
    @mvds: Wait a minute... In this case the "." does need escaping, because otherwise you would also match acfg, bcfg,... \\.cfg whould therefor match \acfg (including the backslash, because it is escaped). – fresskoma Apr 12 '11 at 10:30
  • @x3ro: There are two stages; we need a string containing literally "\.cfg", because `preg_match` needs to `.` to be escaped. However, the \ also serves to escape things we put in literal strings. So if we say '\\.' we make a string containing \. which is what we need. So there are two levels of escaping, so to speak. – mvds Apr 12 '11 at 10:33
  • @x3ro: I visited the link, but the point is that the string, which is passed to `preg_match`, will contain only one backslash. – mvds Apr 12 '11 at 10:36
  • @mvds: Ah I see your point now. Didn't know about that inconsistency in PHP (because \n for example is not converted inside '...' Which characters do need to be escaped inside '...' ? ). – fresskoma Apr 12 '11 at 10:43
  • I think only the singe quote. And the backslash itself, being the escaping character. (btw you could equally well call it an inconsistency of users to write \n where it should (could?) be \\n) – mvds Apr 12 '11 at 10:48
3

In this case, you can simply look at the last four characters of $cal using substr:

if (substr($cal, -4) === '.cfg') {
    echo "Hello ";
}

You should look into regular expressions for more complex problems.

lonesomeday
  • 233,373
  • 50
  • 316
  • 318
  • Everyone gave really insightful answers; I have to say I learned something for sure today. However, sometimes KISS is sometimes the best. Thanks everyone! – dukevin Apr 12 '11 at 11:03
3

for simple patterns strpos will do nicely.

if (strpos ('.cfg', $string) !== false)
{
    // etc
}

For more complicated parterns, you want preg_match, which can compare a string against a regular expression.

if (preg_match ('/.*?\.cfg/', $string))
{
    // etc
}

The former offers better performance, but the latter is more flexible.

GordonM
  • 31,179
  • 15
  • 87
  • 129
2

You can use various approaches here. For example:

$cal = explode('.', $cal);
if(last($cal) === "cfg")) {
    echo "Hello";
}

Or using regular expressions (which are probably way slower than using strpos for example):

if(preg_match("/\.cfg$", $cal)) {
   echo "Hello";
} 

I honestly don't know how the explode() version compares to substr() with a negative value (lonesomeday's answer) or strpos() (which has its flaws, Frosty Z's answer). Probably the substr() version is the fastet, while regular expressions are the slowest possible way to do this).

fresskoma
  • 25,481
  • 10
  • 85
  • 128