老实说,我真的认为读写 PHP 文件是一个非常非常糟糕的想法。如果您正在查看配置,请使用ini
or json
。
如果你真的想读写文件,那么它可以很简单:
$file = __DIR__ . "/include/config.json";
$var = new FileVar($file);
$var['o'] = "Small o";
$var['O'] = "Big O";
$var->name = "Simple json";
echo file_get_contents($file);
输出
{
"o": "Small o",
"O": "Big O",
"name": "Simple json"
}
另一个例子
// To remove
unset($var['O']);
// to update
$var['o'] = "Smaller o";
输出
{
"o": "Smaller o",
"name": "Simple json"
}
请注意,包含文件夹包含此.htaccess
<Files "*">
Order Deny,Allow
Deny from all
</Files>
为了测试这是否真的lock
有效,我使用pthreads来模拟竞态条件
for($i = 0; $i < 100; $i ++) {
$ts = array();
// Generate Thread
foreach(range("A", "E") as $letter) {
$ts[] = new T($file, $letter);
}
// Write all files at the same time
foreach($ts as $t) {
$t->start();
}
// Wait for all files to finish
foreach($ts as $t) {
$t->join();
}
}
// What do we have
echo file_get_contents($file);
主班
class FileVar implements ArrayAccess {
private $file;
private $data;
private $timeout = 5;
function __construct($file) {
touch($file);
$this->file = $file;
$this->data = json_decode(file_get_contents($file), true);
}
public function __get($offset) {
return $this->offsetGet($offset);
}
public function __set($offset, $value) {
$this->offsetSet($offset, $value);
}
public function offsetSet($offset, $value) {
if (is_null($offset)) {
$this->data[] = $value;
} else {
$this->data[$offset] = $value;
}
$this->update();
}
public function offsetExists($offset) {
return isset($this->data[$offset]);
}
public function offsetUnset($offset) {
unset($this->data[$offset]);
$this->update();
}
public function offsetGet($offset) {
return isset($this->data[$offset]) ? $this->data[$offset] : null;
}
private function update() {
// Open file with locking
$time = time();
while(! $fp = fopen($this->file, "c+")) {
if (time() - $time > $this->timeout)
throw new Exception("File can not be accessed");
usleep(100000);
}
// Lock the file for writing
flock($fp, LOCK_EX);
// Overwrite the old data
ftruncate($fp, 0);
rewind($fp);
// Write the new array to file
fwrite($fp, json_encode($this->data, 128));
// Unlock the file
flock($fp, LOCK_UN);
// Close the file
fclose($fp);
}
}
测试班
class T extends Thread {
function __construct($file, $name) {
$this->file = $file;
$this->name = $name;
}
function run() {
$var = new FileVar($this->file);
$var[$this->name] = sprintf("Letter %s", $this->name);
}
}