我正在尝试编写一个允许我将数据写入文件然后读取它的类。在某些情况下,我还会锁定文件以进行写入,然后在写入完成后将其解锁。
我遇到的问题是,当我尝试使用getCache()
方法获取文件内容时,该文件变为空。似乎在调用getCache()
方法时,由于某种原因删除了文件的内容。
这是我的班级
<?php
namespace ICWS;
use \ICWS\showVar;
use \DirectoryIterator;
/**
* CacheHandler
*
* @package ICWS
*/
class CacheHandler {
/* Max time second allowed to keep a session File */
private $maxTimeAllowed = 300;
private $filename = '';
private $handle;
public function __construct( $filename ){
$this->filename = $filename;
// 5% chance to collect garbage when the class is initialized.
if(rand(1, 100) <= 5){
$this->collectGarbage();
}
}
/**
* Add/Update the cached array in the session
*
* @param string $key
* @param bigint $id
* @param array $field
* @return void
*/
public function updateCache($key, $id, array $field)
{
$currentVal = (object) $field;
$this->openFile();
$this->lockFile();
$storage = $this->readFile();
//create a new if the $id does not exists in the cache
if( isset($storage[$key]) && array_key_exists($id, $storage[$key]) ){
$currentVal = (object) $storage[$key][$id];
foreach($field as $k => $v){
$currentVal->$k = $v; //update existing key or add a new one
}
}
$storage[$key][$id] = $currentVal;
new showVar($storage);
$this->updateFile($storage);
$this->unlockFile();
$this->closeFile();
}
/**
* gets the current cache/session for a giving $key
*
* @param string $key
* @return object or boolean
*/
public function getCache($key)
{
$value = false;
$this->openFile();
$storage = $this->readFile();
if(isset($storage[$key])){
$value = $storage[$key];
}
$this->closeFile();
return $value;
}
/**
* removes the $id from the cache/session
*
* @param string $key
* @param bigint $id
* @return boolean
*/
public function removeCache($key, $id)
{
$this->openFile();
$this->lockFile();
$storage = $this->readFile();
if( !isset($storage[$key][$id])){
$this->unlockFile();
$this->closeFile();
return false;
}
unset($storage[$key][$id]);
$this->updateFile($storage);
$this->unlockFile();
$this->closeFile();
return true;
}
/**
* unset a session
*
* @param argument $keys
* @return void
*/
public function truncateCache()
{
if(file_exists($this->filename)){
unlink($this->filename);
}
}
/**
* Open a file in a giving mode
*
* @params string $mode
* @return void
*/
private function openFile( $mode = "w+"){
$this->handle = fopen($this->filename, $mode);
if(!$this->handle){
throw new exception('The File could not be opened!');
}
}
/**
* Close the file
* @return void
*/
private function closeFile(){
fclose($this->handle);
$this->handle = null;
}
/**
* Update the file with array data
* @param array $data the array in that has the data
* @return void
*/
private function updateFile(array $data = array() ){
$raw = serialize($data);
fwrite($this->handle, $raw);
}
/**
* Read the data from the opned file
*
* @params string $mode
* @return array of the data found in the file
*/
private function readFile() {
$length = filesize($this->filename);
if($length > 0){
rewind($this->handle);
$raw = fread($this->handle, filesize($this->filename));
return unserialize($raw);
}
return array();
}
/**
* Lock the file
*
* @return void
*/
private function lockFile( $maxAttempts = 100, $lockType = LOCK_EX) {
$i = 0;
while($i <= $maxAttempts){
// acquire an exclusive lock
if( flock($this->handle, LOCK_EX) ){
break;
}
++$i;
}
}
/**
* Unlock the file
*
* @return void
*/
private function unlockFile() {
fflush($this->handle);
flock($this->handle, LOCK_UN);
}
/**
* Remove add cache files
*
* @return void
*/
private function collectGarbage(){
$mydir = dirname($this->filename);
$dir = new DirectoryIterator( $mydir );
$time = strtotime("now");
foreach ($dir as $file) {
if ( !$file->isDot()
&& $file->isFile()
&& ($time - $file->getATime()) > $this->maxTimeAllowed
&& isset($file->getFilename) && $file->getFilename != 'index.html'
) {
unlink($file->getPathName());
}
}
}
}
这就是我打电话给我的课程
<?php
require 'autoloader.php';
try {
$cache = new \ICWS\CacheHandler('cache/12300000');
$field = array('name' => 'Mike A', 'Address' => '123 S Main', 'phone' => '2152456245', 'ext' => 123);
$cache->updateCache('NewKey', '123456', $field);
echo '<pre>';
print_r($cache->getCache('NewKey'));
echo '</pre>';
} catch (exception $e){
echo $e->getMessage();
}
?>
评论专栏print_r($cache->getCache('NewKey'));
时,文件12300000
将按预期显示以下数据
a:1:{s:6:"NewKey";a:1:{i:123456;O:8:"stdClass":4:{s:4:"name";s:6:"Mike A";s:7:"Address";s:10:"123 S Main";s:5:"phone";s:10:"2152456245";s:3:"ext";i:123;}}}
但是,当调用方法print_r($cache->getCache('NewKey'));
时,文件变为空。
我在这里做错了什么?为什么我的print_r($cache->getCache('NewKey'));
方法会清空文件?
答案 0 :(得分:3)
openFile($mode = "w+")
'w +'开放阅读和写作;将文件指针放在文件的开头,并将文件截断为零长度。如果该文件不存在,请尝试创建它。
因此它会重置文件,删除其中的所有内容。
您可能想要模式a+
:
'a +'开放阅读和写作;将文件指针放在文件的末尾。如果该文件不存在,请尝试创建它。在此模式下,fseek()()仅影响读取位置,始终追加写入。