tags:

views:

125

answers:

9

Hi there,

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.

+2  A: 
 $ext = strtolower(substr($file, -3));

 if($ext == "mp4" || $ext == "mov" || $ext == "flv"){...
jakenoble
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().
cdburgess
+1  A: 

A more concise way:

if ( preg_match('/(mp4|mov|flv)$/', $file) ) { ...
kemp
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.
cdburgess
@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.
kemp
@kemp: My apologies. I completely missed the `$`.
cdburgess
+4  A: 

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
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
@Bevor: The only reason is "because C also has that function".
KennyTM
+12  A: 

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
You beat me for 41 secs :-(
M42
@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
@Stephen: There you go.
Gumbo
@Gumbo - Mrm, I think that will do. It's not bad, at least. :p.
Stephen
Thank you very much everyone for all your answers, much appreciated!
Jacob Schindler
@Jacob Schindler: You’re welcome. And don’t forget to accept an answer.
Gumbo
+3  A: 

Another way to do it :

if ( in_array(strtolower(substr($file, -3))),  array('mp4', 'mov', 'flv') ) {
    // do something
}
M42
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.
cdburgess
A: 

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
+1  A: 

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

Gordon
@Gordon: 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.
cdburgess
@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
I was more talking about glob. However, maybe you could update your comment to show a good example of `fnmatch`.
cdburgess
A: 

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

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

tummy.developer
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.
cdburgess
A: 

Thanks to everyone for their help, much appreciated!

Jacob Schindler