I have an xml file with database information that should be loaded when the script is installed or when the content of the file changes. Can I use md5_file() on the xml file and then store the value in the db and compare it to the file's hash each time the script is run? Does it have any drawbacks and are there any other methods that are faster/simpler?
- Yes, you can use a hash, or simply check the modified time of the file. You could just have typed you question in a search engine...Green Black– Green Black2013-02-04 23:46:37 +00:00Commented Feb 4, 2013 at 23:46
- 4I just typed it into a search engine and I ended up here. A totally legit question and this is the best place for a discussion, imo.Octopus– Octopus2014-01-30 20:11:16 +00:00Commented Jan 30, 2014 at 20:11
5 Answers
It depends on what you mean by "changed". If you require that the contents actually be modified, then checking filemtime is not enough - it's a fantastic first step, and should be used first, but it is not sufficient on its own.
Conbine the filemtime with a hash of the file's contents (such as md5_file) and it will work efficiently.
5 Comments
filemtime check is intended to act as a much more efficient lookup. Then, only if the modification time has changed will it perform the expensive md5_file call.touch() function is called on it.Perhaps you could use PHP's filemtime() function. Simply put, this function gets file modification time for a specified file.
This function returns a unix time stamp, so you'll need to save the last known modification time somewhere in order to compare it to the new value.
$modifiedTs = filemtime($filename); if ($modifiedTs != $lastModificationTs){ echo "$filename was modified!"; } 2 Comments
filemtime. When you don't have a modification time, you can take the current time stamp - then when you call filemtime again and compare it to the previous value, it will be different and you'll know that the file has changed.I know that I am going back in time here, but the question helped me so I want to share what I did with it, so while this is not an answer to the question I will make it a community wiki so it can be improved (I'm no expert).
This was part of a much larger class so I have stripped out the rest and provided just the applicable code and turned it into an easy to follow example using a very common file:
class ApplicationLogger { private $logfile, $path; public function __construct() { $this->logfile = 'error.log'; $this->path = '/var/log/apache2/'; } public function logState() { $files = array( 'target' => $this->path . $this->logfile, 'lastmod' => $this->path . $this->logfile . '_lastmod' ); if (file_exists($files['lastmod']) && file_exists($files['target'])) { $lfh = fopen($files['lastmod'], 'r'); while (!feof($lfh)) { $lines[] = fgets($lfh); } fclose($lfh); } $modified = false; /** * check if we have a matching hash. */ if (isset($lines) && filemtime($files['target']) != $lines[0]) { // mod time mismatch if (md5_file($files['target']) != $lines[1]) { // content modified $modified = true; } } /** * update or create the lastmod file */ if (!file_exists($files['lastmod']) || $modified) { $current_mod = filemtime($files['target']) . "\n" . md5_file($files['target']); file_put_contents($files['lastmod'], $current_mod); $modified = true; } return $modified; } } Usage is straight forward:
$mod = new ApplicationLogger(); if ($mod->logState()) { // changed do something } Adapt it to your needs, improve it however you see fit. I hope that you will contribute your adaptations by editing this CW.