File cache driver refactoring and optimization

1. External locking for writing files
I replaced fopen(), fwrite() and fclose() with file_put contents() to avoid race conditions when writing the cache contents into a file. Currently an exclusive lock is not acquired which could cause unexpected errors when multiple php threads try to save the same file simultaneously (the value of the time() function is identical for every thread) .

2. Cache cleanup optimization
Currently a cleanup (glob on all files in cache floder) is executed in __construct() on every request. This is not necessary and is more or less a performance penalty (especially when having thousands of cache files, which is the case with some extensions). 
I added a condition so the cleanup is executed randomly based on probability (currently 25%). There is an additional check in get() method to avoid fetching expired cache data before it has been purged.

3. Custom expiration per key 
I added an optional $expire argument to the set() method, which makes it easy to cache 
data with custom expire time without having to make a new cache class instance.