2013-04-02 4 views
5

Я искал, но не смог найти окончательный ответ (если он есть) при использовании $ this в классе PHP. Я все еще пытаюсь склонить голову, используя подход ООП, и хочу убедиться, что я использую лучшие практики.Члены и методы класса PHP

Итак, мой вопрос в том, как и когда вы должны определить vars и когда вы должны использовать $ this для ссылки на них.

Скажет, у меня есть следующий класс ....

class Foo { 

private $pin; 
private $stat; 

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

Таким образом, в приведенной выше функции, у меня есть переменные $ булавки, переданная метода класса. Это прекрасно работает без использования $ this-> контактный ... Однако приведенный ниже код, кажется, больше похоже, что это правильный способ сделать то же самое .....

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 vars to = 0. Я полагаю, это может быть просто значение по умолчанию, или я могу просто определить их, как в первом примере private $ pin; и частный $ stat ;.

Итак, вернемся к моему вопросу, каковы наилучшие методы использования членов и $ this в методах класса? И каковы были бы преимущества или недостатки на каждом примере?

+1

Я получил довольно хороший ответ по этому поводу на [codereview.stackexchange] (http://codereview.stackexchange.com/). Проверьте это [здесь] (http://codereview.stackexchange.com/a/23857/20878) – jnthnjns

+0

Спасибо за ссылку ASOK! Теперь имеет смысл, почему вы должны использовать только $ this ... для ссылки на свойства внутри класса. Я не мог понять отношения с доступом к ним за пределами класса. – user2233942

+0

Пожалуйста, НИКОГДА не вызывайте оболочку с неопределенными значениями! 'shell_exec (« blah read $ pin »);' широко открыт для ввода кода. Всегда используйте функции экранирования, в этом случае для команд оболочки: escapeshellarg() – Sven

ответ

6

Вы должны использовать $ this при использовании любого члена класса. Вы не должны использовать его при использовании локальных переменных. Вы должны избегать использования членов класса, если они не нужны, например, $this->pin во втором примере.

+0

спасибо Свену. Короче говоря, единственный раз, когда я использую $, это когда мне нужно работать с членом класса. Это просто не нужно в противном случае? – user2233942

+0

Я бы не назвал это «не нужно». '$ this' не должно использоваться при работе с локальными варами. – Sven

+0

Вам следует избегать использования переменных непосредственно в строках ... –

-1

Если вы хотите придерживаться хороших практик ООП, тогда у вас действительно должны быть сеттеры и геттеры для ваших переменных экземпляра. Например, вот пересмотр кода:

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, когда вы обратитесь к этот экземпляр класса (также называемый объект). Преимущество наличия класса в том, что вы можете иметь несколько объектов, которые определяет класс. Например:

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 
} 

Надеется, что это помогает!

+0

Нет, извините, я не согласен. Пример вашего getter/setter для «getStat» неверен, полностью. Ваш код представляет собой бесконечный цикл с getStat(), вызывающий getStat(), и идея неправильная. Хорошо иметь объект с методами, которые делают что-то с переданными параметрами и возвращают результат. Другой пример - совсем другой пример, потому что вы иллюстрируете геттеры/сеттеры с хранилищем значений без каких-либо функций внутри. – Sven

+0

Спасибо, что поделились вашим мнением – djthoms

+0

Ну, бесконечный цикл в 'getStat()' все еще существует, независимо от того, что мое мнение касается остальной части вашего кода. – Sven

1

«передовая практика» зависит от ваших потребностей. В вашем примере это похоже на то, что pin - статический. Вы могли бы просто установить это изначально и даже не передать его методу.

private $pin = 'abc123'; 

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

Установка переменных класса имеет смысл только в том случае, если они вам доступны с помощью методов внутри класса. В вашем примере оба ключа и stat потенциально могут использоваться во многих методах, поэтому имеет смысл определить их как переменные класса и получить доступ к ним с помощью $this->key, а $this->stat - разумно и логично. Было бы нецелесообразно, если бы что-то вроде stat использовалось только в определенном методе или изменялось в зависимости от конкретного набора данных, делающего stat атрибутом многих объектов вместо общего атрибута класса.

Как указал Свен, используя $this->pin, когда $pin передано классу, не является нормальным. Логичнее было бы назначить его как переменную класса и использовать $this->pin, если штифт не изменяется и является общим для экземпляра, и в этом случае вам не нужно передавать что-либо методу.Например, запрос API, в котором ключ вряд ли изменится. Передача $key методу имеет смысл, если $key может быть любым, например, результатами из базы данных, ввода пользователем или чего-либо еще, где источник не известен конкретно.

Я не знаю, поможет ли это много, но вот пример использования геттеров и сеттеров, если вы намерены изменить значения pin или stat на основе чего-либо, переданного в общем или абстрактно. Getter and Setter?

+0

Это был действительно полезный Кай. Как вы и Свен указывали, $ this-> pin не нужен, так как он передается классу для начала. Мое отсоединение - это связь между var внутри и снаружи класса (который, как представляется, не существует). – user2233942

0

Никогда не используйте var. Это устаревшая форма публики. Избегайте использования общедоступной информации о своих свойствах, вы хотите иметь контроль над значением каждого свойства в своем классе.