__FILE__ is the file name that the __FILE__ token is in, and $0 is a variable containing the name of the program, as given to the shell.

They can most certainly be different - one case that comes to mind is a __FILE__ token in a library called by your program, but there are many others, particularly since you can assign to $0 (with varying effects on different OS), but you can't meaningfully assign to __FILE__.