【问题标题】:PHP Class members and methodsPHP 类成员和方法
【发布时间】:2013-04-02 00:17:37
【问题描述】:

我已经四处搜索,但找不到关于在 PHP 类中使用 $this 的明确答案(如果有的话)。我仍在尝试使用 OOP 方法,并希望确保我使用的是最佳实践。

所以我的问题是关于应该如何以及何时定义变量以及何时应该使用 $this 来引用它们。

假设我有以下课程....

class Foo {

private $pin;
private $stat;

public function get_stat($pin) {
            $this->stat = shell_exec("blah read $pin");
            return $this->stat;
    }
}

所以在上面的函数中,我将 var $pin 传递给了类方法。无需使用 $this->pin 就可以正常工作...但是下面的代码似乎更像是做同样事情的正确方法.....

class Foo {

private $pin = 0;
private $stat = 0;

public function get_stat($pin) {
            $this->pin = $pin;
            $this->stat = shell_exec("blah read $this->pin");
            return $this->stat;
    }
}

另外,我已将 $pin 和 $stat 变量设置为 = 0。我认为这可以只是一个默认值,或者我可以像第一个示例中那样定义它们 private $pin;和私人 $stat;.

回到我的问题,关于如何在类方法中使用成员和 $this 的最佳实践是什么?每个示例的优点或缺点是什么?

【问题讨论】:

  • 我在codereview.stackexchange 上得到了一个很好的答案。看看here
  • 感谢 ASOK 的链接!现在,为什么你应该只使用 $this ... 来引用类中的属性是有道理的。我不太明白在课堂外访问它们的关系。
  • 请不要使用未转义的值调用 shell! shell_exec("blah read $pin"); 对代码注入开放。始终使用转义函数,在这种情况下用于 shell 命令:escapeshellarg()
  • 嗨,斯文,是的,我对没有“清理”输入感到内疚。这只是我试图快速开始工作的一个快速而肮脏的例子。在我完全理解我想要完成的 OOP 方面之后,转义的其余逻辑就会出现。再次感谢!
  • @user2233942 "WouterJ" 指的是从类外部访问属性与类内的$this-> 比较,例如$Foo = new Foo() 然后$Foo->get_stat("Variable Passed") 与类内的$this->get_stat("Variable Passed")。跨度>

标签: php oop class


【解决方案1】:

在使用任何类成员时都必须使用 $this。使用局部变量时不能使用它。如果没有必要,您应该避免使用类成员,例如第二个示例中的 $this->pin

【讨论】:

  • 感谢斯文。所以简而言之,我应该使用 $this 的唯一时间是我需要与班级成员一起工作的时候。否则根本不需要?
  • 我不会称之为“不需要”。处理本地变量时不能使用$this
  • @ColeJohnson:这完全取决于编码风格。只要语言支持,就是有效的方法。
  • 有效和理智可能是两种不同的东西。虽然我同意你的观点,但 php 会在技术上评估你传递的任何字符串。这并不意味着通过 eval 运行所有内容是一个明智的选择,只是因为语言支持它。因此,从技术上讲,彻底滥用班级或本地 vars 可能会奏效,但如果朝错误的方向发疯,可能会导致他获得一份高薪工作或生活在桥下。
  • 但是假设我有一个变量$var,其中包含word。使用这种编码风格,我会输入"$vars",当我真正的意思是$var + "s"时,这将导致一个未定义的变量。
【解决方案2】:

“最佳实践”取决于您的需要。在您的示例中,看起来 pin 是静态的。您可以只在最初设置它,甚至不将其传递给方法。

private $pin = 'abc123';

public function get_stat() {
    $this->stat = shell_exec("blah read $this->pin");
    return $this->stat;
}

只有当您需要类中的方法可以访问它们时,设置类变量才有意义。在您的示例中, key 和 stat 都可能在许多方法中使用,因此将它们定义为类变量并使用 $this->key$this->stat 访问它们是合理且合乎逻辑的。如果像 stat 这样的东西只用在特定的方法中,或者根据特定的数据集进行更改,从而使 stat 成为许多对象的属性而不是类的公共属性,那将是没有意义的。

正如 Sven 指出的那样,在将 $pin 传递给类时使用 $this->pin 是不明智的。将其分配为类变量并使用$this->pin 会更合乎逻辑,如果引脚没有更改并且对于实例是通用的,在这种情况下,您不需要将任何内容传递给该方法。例如,密钥不太可能更改的 API 请求。如果$key 可以是任何东西,比如来自数据库的结果、用户输入或其他任何来源不明的东西,那么将$key 传递给该方法是有意义的。

我不知道这是否会有很大帮助,但如果您打算根据一般或抽象传递的任何内容更改 pin 或 stat 的值,这里有一个使用 getter 和 setter 的示例。 Getter and Setter?

【讨论】:

  • 这实际上对凯很有帮助。正如您和 Sven 指出的那样, $this->pin 不是必需的,因为它一开始就传递给了类。我的断开是类内部和外部的 var 之间的关系(似乎没有任何关系)。
【解决方案3】:

如果您想坚持 OOP 的良好实践,那么您真的应该为您的实例变量设置 setter 和 getter。例如,这是您的代码的修订版:

class Foo {

    // common practice to begin private variables and methods with an underscore
    private $_pin = 0;
    private $_stat = 0;

    // this is called a setter because we are setting a value
    // note the lack of a return
    public function setStat($stat) {
        // we use $this-> because we are referencing THIS instance of THIS class/object
        // and in doing so we refer to our private $_stat instance variable.
        $this->_stat = $stat;
    }

    // this is called a getter because we are getting a value
    // not how we are NOT setting values here.
    public function getStat() {
        return $this->_stat;
    }

}

总的来说,当您引用类的 this 实例(也称为对象)时,您使用$this。拥有一个类的好处是您可以拥有一个类定义的多个对象。例如:

class Person {

    public $name, $age, $gender;

    public function setName($name) {
        $this->name = $name;
    }
    public function setAge($age) {
        $this->age = $age;
    }
    public function setGender($gender) {
        $this->gender = $gender;
    }
    public function getName() {
        return $this->name;
    }
    public function getAge() {
        return $this->age;
    }
    public function getGender() {
        return $this->gender;
    }

}

// outside the class
$john = new Person();
$john->setName('John Doe');
$john->setAge(22);
$john->setGender('male');
var_dump($john);

var_dump 将显示:

object(Person)#1 (3) { 
    ["name"]=> string(8) "John Doe" // $this->name
    ["age"]=> int(22)               // $this->age
    ["gender"]=> string(4) "male"   // $this->gender
}

希望这会有所帮助!

【讨论】:

  • 不,抱歉,我不同意。您的“getStat”getter/setter 示例完全错误。您的代码是 getStat() 调用 getStat() 的无限循环,这个想法是错误的。拥有一个带有方法的对象是一件好事,这些方法通过传递的参数执行某些操作并返回结果。您的另一个示例是一个完全不同的示例,因为您使用没有任何功能的值存储来说明 getter/setter。
  • 感谢您分享您的意见
  • 好吧,getStat() 中的无限循环仍然存在,无论我对您的其余代码有何看法。
  • Sevn,我终于明白你在说什么了,哈哈。有时就像对着一堵砖墙说话-___-。它已得到纠正。谢谢指出
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-08-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多