3

Forgive me if this has been covered before, I searched to no avail.

I have a script that looks into a directory to find the files inside. There is a conditional line that only looks for files with a certain extension:

if(strtolower(substr($file, -3)) == "mp4"){...

So that will only look for files with an 'mp4' extension.

I need to add some "or" operators to add two more extension types. I tried the following but it didn't work:

if(strtolower(substr($file, -3)) == "mp4" || == "mov" || == "flv"){...

Now the line seems to be ignored and it gets every file in the directory. If anyone could help me out, I'd be very grateful! I know this is probably as basic as it gets, but my grasp of PHP is extremely limited (although I do see its beauty!!!)

Thanks in advance.

Matteo Riva
  • 24,728
  • 12
  • 72
  • 104
  • Note that file extension may be more or less than three characters long. It would be better to use a regex or split the name on every occurrence of a dot and take the last part. – Sven Koschnicke Sep 03 '10 at 08:31

8 Answers8

11

The way you tried it does not work because the comparison operator == is a binary operator and expects two operands, i.e. operand1 == operand2. The same applies to the logical OR operator that is also a binary operator, i.e. operand1 || operand2.

That means you would need to write something like this:

$ext = strtolower(substr($file, -3));
if ($ext == "mp4" || $ext == "mov" || $ext == "flv")

Here $ext is just used to avoid repeated call of strtolower(substr($file, -3)). In this case each binary operator has two operands:

((($ext == "mp4") || ($ext == "mov")) || ($ext == "flv"))
   \__/    \___/
     \__==___/        \__/    \___/
         \              \__==___/
          \_______||_______/
                   \                      \__/    \___/
                    \                       \__==___/
                     \________________||_______/

(I added parentheses to highlight the order in which the expression is evaluated.)

So this is how you would have to write it.

But you could also use an array and in_array:

in_array(strtolower(substr($file, -3)), array("mp4","mov","flv"))

And pathinfo is probably better to get the file name extension, so:

in_array(pathinfo($file, PATHINFO_EXTENSION), array("mp4","mov","flv"))
Gumbo
  • 643,351
  • 109
  • 780
  • 844
  • @Gumbo - Although your answer is good, it currently does not actually address the OP's question, which was why his "or"s were not working. I know it has been covered by other answers here, but please considering adding in a brief description of why his code did not work and I will give you a +1. – Stephen Sep 03 '10 at 08:39
  • @Gumbo - Mrm, I think that will do. It's not bad, at least. :p. – Stephen Sep 03 '10 at 11:05
  • Thank you very much everyone for all your answers, much appreciated! – Jacob Schindler Sep 04 '10 at 02:01
4

The problem is that PHP does not automatically know that you want to compare to strtolower(substr($file, -3)) in each "or" section. You need to explicitly state this:

if(strtolower(substr($file, -3)) == "mp4" || strtolower(substr($file, -3)) == "mov" || strtolower(substr($file, -3)) == "flv"){...

Note that it would probably be neater to do something like:

$tmp = strtolower(substr($file, -3));

if($tmp == "mp4" || $tmp == "mov" || $tmp == "flv"){...
Stephen
  • 6,027
  • 4
  • 37
  • 55
  • I'm no PHP guru but wouldn't it be better to use strcmp for comparing strings? I guess there is a good reason why there is such a function. – Bevor Sep 03 '10 at 08:19
  • @Bevor: The only reason is "because C also has that function". – kennytm Sep 03 '10 at 08:27
2
 $ext = strtolower(substr($file, -3));

 if($ext == "mp4" || $ext == "mov" || $ext == "flv"){...
Jake N
  • 10,535
  • 11
  • 66
  • 112
  • What happens when you add 15 extensions? You wind up with a mess of `|| $ext == 'blah'` statements in a very unwieldy IF statement. While this is a working solution, it would be much better to use the in_array(). – Chuck Burgess Sep 03 '10 at 14:30
2

Another way to do it :

if ( in_array(strtolower(substr($file, -3))),  array('mp4', 'mov', 'flv') ) {
    // do something
}
Toto
  • 89,455
  • 62
  • 89
  • 125
  • This in my opinion is the best solution. The array of file types can can expanded (or automated from the database) and not affect the efficacy of the code. This is the most elegant solution to this problem. – Chuck Burgess Sep 03 '10 at 14:24
1

A more concise way:

if ( preg_match('/(mp4|mov|flv)$/', $file) ) { ...
Matteo Riva
  • 24,728
  • 12
  • 72
  • 104
  • This is not good coding practice. The user is looking for a specific extension. This will return true on files like: mymoviescript.txt because `mov` is found in the file name. This is bad code. – Chuck Burgess Sep 03 '10 at 14:20
  • @cdburgess: this is false, note the `$` anchor which limits the search to the end of the string. Please understand regular expressions before accusing code of being bad. – Matteo Riva Sep 03 '10 at 14:34
  • My apologies. I completely missed the `$`. – Chuck Burgess Sep 03 '10 at 14:48
1

If you want to match only specific filenames in a directory, you can use glob

$files = glob('/path/to/dir/*.{mp4,mov,flv}', GLOB_BRACE);

to return an array of matching file paths.

Or you use fnmatch to match a filename against a pattern.

In addition, if you want to make sure the images are really images, consider checking against the MimeType instead of or in addition to the extension

Community
  • 1
  • 1
Gordon
  • 312,688
  • 75
  • 539
  • 559
  • This is a great solution if you want to cycle through a directory of files. However, if you are uploading a file or need to check one file, the in_array() solution proves to be a better solution. – Chuck Burgess Sep 03 '10 at 14:28
  • @cdburgess *I have a script that looks into a directory to find the files inside* doesnt sound like uploading or checking a single file only (for which you can still use `fnmatch`). – Gordon Sep 03 '10 at 15:12
  • I was more talking about glob. However, maybe you could update your comment to show a good example of `fnmatch`. – Chuck Burgess Sep 03 '10 at 15:51
0

if you want to compare using ||, here's the syntax:

if(strtolower(substr($file, -3)) == "mp4" || strtolower(substr($file, -3)) == "mov" || strtolower(substr($file, -3)) == "flv"){...

of course to make it a bit faster, fill strtolower(substr($file, -3)) in a variable so php doesn't execute those functions more than once:

$extension=strtolower(substr($file, -3));
if($extension == "mp4" || $extension == "mov" || $extension == "flv"){...

The other good news is, PHP got a builtin function to search whether a value exists in an array of values (in_array):

if(in_array(strtolower(substr($file, -3)), array('mp4', 'mov', 'flv')))

One last thing, if you have simple strings like those, ones who you don't want php to expand variables and stuff inside, use single qutations instead of doubles, that is a good practice and saves some execution time (of course barely noticed with a string or two, but it's a good practice on the long range).

aularon
  • 11,042
  • 3
  • 36
  • 41
0

$ext = strtolower(substr($file, -3));

switch ( $ext ) { case 'mp4': case 'mov': case 'flv': /// some operation break; }

thomasbabuj
  • 3,779
  • 3
  • 24
  • 22
  • This is not very flexible. I would also consider this poor coding. in_array() would be much easier. They way you have coded it will require the developer to write additional lines of code when they want to add new file types (like mp5 in the future for example). The code should use variables, you shouldn't write variable code. – Chuck Burgess Sep 03 '10 at 14:23