关于oop:php使用中的私有方法和变量

private methods and variables in PHP usage

本问题已经有最佳答案,请猛点这里访问。

我一直在考虑在PHP中使用private变量和方法。

我不想谈论一类汽车或类似的事情。我想谈谈自己的剧本。

为程序员和脚本所有者使用public或private有什么区别?

如果脚本是一个计算器,而我是将来唯一一个可以输入代码的人。我什么时候必须使用方法的私有变量?这将如何改变脚本中的任何内容?

另外,如果是关于接触变量?如果有人试图改变价值,但他不能因为私事。他会直接用二传手来改变吗?

我需要一个很好的例子,我可以看到私有方法或变量对程序员或最终用户有很好的好处。

我正在编写一些脚本,有个人告诉我不要在课堂上使用var。我问他为什么?他说你必须使用公共的或私人的。问为什么?

如果有直接更改变量的方法,为什么要使用setter?

如果有直接更改变量的方法,为什么要使用getter?


首先,在开发强大的OO类时,应该尽可能少地公开类的内部语义(显然不会影响功能)。

一些变量只在类本身的上下文中有价值,对于使用类的开发人员来说没有意义。将变量设为public允许任何使用该类的人随意更改此类变量,尽管他们可能不知道它的用途。在PHP中,这可能是一个特别的问题,当您甚至没有类型安全性来至少减轻可能造成的损害时。

考虑一下:您有一个类,它包装了一些I/O操作。我们叫它FileReader

1
2
3
4
5
6
7
8
9
10
11
12
class FileReader {
    public $_handle;

    public function __construct($filepath) {
        $this->_handle = fopen($filepath, 'r');
        if ($this->_handle === NULL) {
            throw new Exception("Unable to open the file for reading");
        }
    }

    // ... the rest of the class
}

现在您可以看到类打开了一个文件的句柄。通过将$_handle变量公开,您已经将它暴露给了在您的类中工作的所有人。他们不需要知道你打开的原始文件句柄,他们只想使用你的好类来执行一些读取操作。然而,它是公开的;他们不仅可以看到它,而且可以改变它。这很糟糕,尤其是当您的其他代码假定$_handle变量有效时。

1
2
3
$reader = new FileReader();
$reader->_handle ="I hope this doesn't break anything. /trololol";
$reader->someOperation(); // oh no! Our file handle has just been changed to something completely wrong, this is now going to the break the class.

这种荒谬的场景可以通过首先使变量私有化来完全避免。有关每个访问修饰符所做的以及何时应用它们的更多(更好)示例,请参见此答案。

现在,让我们来看看getter和setter。在您的问题中,您似乎假定所有getter和setter都是按以下方式编写的:

1
2
3
4
5
6
7
8
9
10
11
class Foo {
    private $_bar;

    public function getBar() {
        return $this->_bar;
    }

    public function setBar($newBar) {
        $this->_bar = $newBar
    }
}

在这种情况下,你是绝对正确的,这和把$_bar变量改成公共变量没有区别。

但是,getter和setter方法让您可以控制外部开发人员如何设置变量,因此您可以立即检测何时会生成boo boo,并避免以后出现未定义的行为。例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Foo {
    private $_bar;

    public function getBar() {
        return $this->_bar;
    }

    public function setBar($newBar) {
        // Now we're going to ensure that $newBar is always an integer
        if (!is_int($newBar)) {
            // not an integer, throw out an exception to let the developer know that somewhere is setting invalid input
            throw new Exception("Expected an integer value for 'Bar'");
        }
        $this->_bar = $newBar;
    }
}

这不仅使类更加健壮,而且使使用类的开发人员的生活更加容易。当类试图使用$_bar的损坏值时,他们不必在稍后的某个地方调试一个非常奇怪的问题,而是可以很容易地从堆栈跟踪中分辨出损坏值是从哪里设置的,并在源代码处修复它。

这里有大量关于变量访问和GETTE/SETER方法的文档,它适用于各种语言,所以不要害怕查找基于C++/C*/VB.NET的文章,它们都粗略地翻译成相同的材料。


最终用户看不到代码,因此没有(dis)优势。

对于程序员来说,将对象外部不需要的东西声明为private只是一种良好的编程实践和保护机制。从技术上讲,如果您是一个完美的程序员,而且您不关心代码的外观,那么使用private将不会给您带来任何好处。然而,私有成员强制使用黑盒模型——您只关心对象做什么,而不关心它是如何工作的(从外部看时)。最后,如果您(或其他人)出于任何原因需要/想要使用代码,他们将知道要使用/调用什么方法和属性来获得对象的功能,而不修改对象需要维护的内部值。它可能会给您带来任何好处,也可能不会给您带来任何好处——这只是关于代码的外观。这就是好的编程实践的目的,通常都会遵循它们,因为经验表明它们倾向于最小化错误。

至于var,它被否决了。这意味着它将来可能(也将)被移除。


public、private和protected仅在PHP中起作用,前提是它们是函数的一部分或类的一部分。

如果您想设置一次变量并"锁定它",以便以后不能更改该值,则可以将其设置为define或将其设置为const常量。

public scope to make that variable/function available from anywhere,
other classes and instances of the object.

private scope when you want your variable/function to be visible in
its own class only.

protected scope when you want to make your variable/function visible
in all classes that extend current class including the parent class.

请参见:http://php.net/manual/en/language.oop5.visibility.php