0

我是 OOP 术语的新手,我正在尝试创建一个能够产生计数器的类。

我尝试下面的代码,但它只创建了一个内部值为 1 的 counter.txt 页面。我不知道它为什么不递增。

class LOGFILE {
    public function READ($FileName) {
        $handle = fopen($FileName, 'r');
        $fread = file_get_contents($FileName);
        return $fread;
        fclose($handle);
    }
    public function WRITE($FileName, $FileData) {
        $handle = fopen($FileName, 'w');
        $FileData = $fread +1;
        fwrite($handle, $FileData);
        fclose($handle);
    }
}
$logfile = new LOGFILE();

$logfile -> WRITE("counter.txt",$FileData);

echo $logfile -> READ("counter.txt");
4

5 回答 5

1

原因是和方法$fread都是局部变量。您需要为您的班级设置全局变量:READWRITEprivate

class LOGFILE {
    private $fread;

    public function READ($FileName) {
        $this->fread = file_get_contents($FileName);
        return $this->fread; 
    }
    public function WRITE($FileName) {
            $this->READ($FileName);
        $handle = fopen($FileName, 'w');
        $FileData = $this->fread +1;
        fwrite($handle, $FileData);
        fclose($handle);
    }
}
$logfile = new LOGFILE();

$logfile -> WRITE("counter.txt");

echo $logfile -> READ("counter.txt");

注意:我已经删除了fopenfclose因为file_get_contents不需要它。在写你可以使用file_put_contents. 也删除了未使用的变量$FileData。在需要时创建变量方法和类始终是一个好习惯。

还可以查看如何命名类、变量、方法等的最佳实践。这是最好的指南,IMO。

于 2012-12-11T07:42:20.380 回答
1

让我们开始检查更正后的代码,看看缺少什么:

<?php

class LOGFILE {

    public function READ($FileName) {
        $handle = fopen($FileName, 'r');
        $fread = fgets($handle, 8192);
        fclose($handle);
        return $fread;        
    }

    public function WRITE($FileName, $FileData) {        
        $counter = $this->READ($FileName);        
        $handle = fopen($FileName, 'w');        
        fwrite($handle, $FileData + $counter);
        fclose($handle);
    }
}
$logfile = new LOGFILE();
$FileData = 1;
$logfile -> WRITE("counter.txt",$FileData);
echo $logfile -> READ("counter.txt")."\n";
$logfile -> WRITE("counter.txt",$FileData);
echo $logfile -> READ("counter.txt")."\n";

?>
  1. 在 READ 中使用 offgets而不是file_get_contents(您可以选择使用 file_get_contents,但我宁愿与使用的其他功能保持一致fopen
  2. 在函数 WRITE 中使用 READ(代码重用原则)
  3. 在 WRITE 中打开具有写权限的文件:'w'
  4. 在里面$FileData = 1;
  5. 无需持有私人会员:$fread
  6. 最重要的是:不要在之后写语句return(就像你在 READ 中所做的那样) - 在之后写的语句return将不会被执行!

此解决方案已成功测试。

于 2012-12-11T08:05:27.040 回答
0

OOP 必须在需要的地方使用。你需要一个简单的东西,所以不需要 OOP。

<?php

function addValue($file='counter.txt', $amount=1) {
    if( false == is_file($file) ) {
        return false;
    }
    $initial = file_get_contents($file);
    return @file_put_contents($initial+$amount);
}

addValue();

?>

测试您对复杂事物的 OOP 知识,例如购物车或其他概念。

编辑//所以,如果您需要一个看起来很复杂的简单示例,请点击此处:)

<?php

class log {

    public $file = '';
    private $amount = 0;

    public function __construct( $file ) {
        $this->file = $file;
        $this->amount = 1;
    }

    public function makeAdd() {
        $initial = file_get_contents($this->file);
        return @file_put_contents($this->file, $initial + $this->amount);
    }

    function __call($f, $args) {
        switch( $f ) {
            case 'add':
                if(isset($args[0]) && !empty($args[0])) {
                    $this->amount = (int)$args[0];
                }
                if( $this->amount == 0 ) {
                    throw new Exception('Not a valid amount.');
                }
                return $this->makeAdd();
            break;
        }
    } 

}

try {

    // create log
    $L = new log('count.txt');

    // this will add 2
    var_dump($L->add(2));

    // this will also add 2
    var_dump($L->add());

    // until you rewrite the amount
    var_dump($L->add(1));

    // final result -> 5

} catch(Exception $e) {
    die($e->getMessage());
}

?>

祝你好运!

于 2012-12-11T07:45:38.830 回答
0
  • 使用 UpperCamelCase 作为类名。LogFile,不是LOGFILE。当你有一个变量时,最有趣的是它应该持有对is_a LogFile你应该命名的东西的引用logFile
  • 函数使用 lowerCamelCase。读写,而不是读写
  • 箭头运算符周围没有空格
  • 方法中的 return 语句后面的代码永远无法到达,所以删除它。
  • read() 不使用 fopen 返回的句柄,所以不要调用 fopen
  • 临时变量 $freed 并不能帮助我们理解代码,所以我们可能会丢失它
  • read 是一个有点不合常规的名字。如果我们将函数重命名为 getCount,它的作用会更明显。
  • 你说你想做一个命中计数器。因此,将类从 LogFile 重命名为 HitCounter,并将变量重命名为 hitCounter
  • 没有使用要写入的 $FileData 参数,因为在函数内部重新分配了变量。我们可以失去它。
  • write 方法应该将文件中的数字加一。写并没有真正表达这一点。将其重命名为增量。
  • 在函数之间使用空行。最后的程序代码通常应该在一个单独的文件中,但在这里我们可以添加几行额外的代码。删除最后三行代码之间的空格。
  • 不要重复你自己——我们不应该不止一次提到“counter.txt”。OOP 就是将数据结构和行为组合到类中,因此创建一个类私有变量来保存文件名,并通过构造函数传递它
  • $fread 不存在于增量范围内,所以我们不能使用它。这行不通。将其替换为对 getCount() 的调用
  • 交换增量的前两行,因此我们不会对同一个文件进行两次并发访问,尽管我们可能在运行我们的脚本两次并且仍然进行两次并发访问的服务器中运行。
  • 将变量 $FileData 重命名为 $count,因为它就是这样。
  • 用 file_put_contents 替换 fopen,fwrite,fclose 序列,因为它做同样的事情并且更简洁。
    • 我们需要标签,因为我们的 php 代码继续到文件的末尾。

这给我们留下了:

<?php

class HitCounter {
    private $fileName;

    public function __construct($fileName){
      $this->fileName = $fileName;
    }

    public function getCount() {
        return file_get_contents($this->fileName);
    }

    public function increment() {
        $count = $this->getCount() + 1;
        file_put_contents($this->fileName, $count);
    }
}


$hitCounter = new HitCounter("counter.txt");    
$hitCounter->increment();    
echo $hitCounter->getCount();
于 2017-08-03T00:05:54.780 回答
-3

您可以创建一个静态计数器并每次递增(而不是创建文件)

<?php
class CountClass {
    public static $counter = 0;

    function __construct() {
        self::$counter++;
    }
}

new CountClass();
new CountClass();


echo CountClass::$counter;
?>
于 2012-12-11T07:41:35.820 回答