Подтвердить что ты не робот

PHP OOP много настроек, getters

Мне нужно создать ок. 5-7 классов, каждый класс будет содержать много членов (скажем, каждый класс будет содержать 20 членов). Я мог бы создать их с помощью общедоступного доступа, например:

class A {
    public $myPropertyOne = '';
    public $myPropertyTwo = '';
    ...
}

Мой предпочтительный способ, конечно, сделать эти члены частными и создать методы get/set для каждого свойства. То есть.

class A {
    private $myPropertyOne = '';
    private $myPropertyTwo = '';

    public function getMyPropertyOne() {
            return $this->myPropertyOne;
    }

    public function setMyPropertyOne($myPropertyOne) {
            $this->myPropertyOne = $myPropertyOne;
    }

    public function getMyPropertyTwo() {
            return $this->myPropertyTwo;
    }

    public function setMyPropertyTwo($myPropertyTwo) {
            $this->myPropertyTwo = $myPropertyTwo;
    }
}

Но если у класса будет 20 свойств, у меня будет в дополнение к этому добавить 40 методов. И моя забота о том, как это замедлит script и гораздо больше памяти, это потребует (помните, что у меня будет несколько классов, подобных этому).

Другим решением может быть использование магических функций __set, __get, но я не хочу, потому что завершение кода в разработке IDE не будет предлагать свойства, которые имеют решающее значение для меня.

Если бы это был скомпилированный язык (например, С++), у меня не было бы вопроса и он использовал бы решение с помощью getters, seters, но поскольку PHP интерпретируется языком, я заинтересован в том, чтобы мои скрипты использовали меньше ОЗУ и были такими же быстрыми насколько это возможно.

Спасибо заранее, любые мысли по этому вопросу были бы высоко оценены!


Мое мнение

Спасибо всем за ваши ответы, я просто хотел поделиться своим мнением, если кто-то будет искать ответ на этот вопрос.

Я не могу полностью согласиться с теми, кто говорит, что вы не должны заботиться о производительности, поскольку это задача оптимизаторов, я думаю, что это важный фактор (по крайней мере, как и для меня), когда мы имеем дело с интерпретируемым языком, таким как PHP мы всегда будем думать о памяти и скорости (все это напоминает мне время, когда я разрабатывал системные приложения для DOS, хех:), и вы всегда были ограничены плохим процессором и килобайтами от общей ОЗУ, так что вы были счастливы, если бы могли сохранить дополнительный байт), в PHP-разработке у вас будет такое же изображение, как и независимо от того, сколько серверов вы добавите, количество пользователей будет всегда выше, так что вам всегда нужно решить, хотите ли вы следовать классическому/безопасному/правильному методу или избегайте этого и получаете некоторый выигрыш в скорости или памяти.

Итак, мое мнение заключается в том, что лучший способ здесь - использовать общедоступный доступ для всех участников и избегать getters/seters для всех свойств и использовать закрытый доступ с методами get/set для свойств, для которых требуется проверка или инициализация данных до значение будет установлено.

Например:

class B {
    public $myPropertyOne = '';
    public $myPropertyTwo = '';
    private $myPropertyThree = array();


    public function getMyPropertyThree() {
        return $this->myPropertyThree;
    }

    public function setMyPropertyThree($val) {
        if(!is_array($val)) {
            return;
        }

        $this->myPropertyThree = $val;
    }
}

Спасибо, что потратили время на мой вопрос!

4b9b3361

Ответ 1

Простые тесты показывают, что экземпляры занимают одинаковый объем памяти, не зависящий от количества методов в классе:

Класс без методов:

class Test1 { }

Класс с 20 методами:

class Test2 {

    function test1() { return true; }
    function test2() { return true; }
    function test3() { return true; }
    function test4() { return true; }
    function test5() { return true; }
    function test6() { return true; }
    function test7() { return true; }
    function test8() { return true; }
    function test9() { return true; }
    function test10() { return true; }
    function test11() { return true; }
    function test12() { return true; }
    function test13() { return true; }
    function test14() { return true; }
    function test15() { return true; }
    function test16() { return true; }
    function test17() { return true; }
    function test18() { return true; }
    function test19() { return true; }
    function test20() { return true; }

}

Тестовый цикл, тот же для обоих тестов:

$test = array();
$base = memory_get_usage();
for ($i = 0; $i < 10000; $i++) {
    $test[] = new ClassToBeTested();
}
$used = memory_get_usage() - $base;
print("used: $used\n");

Результат для класса Test1 (без методов):

used: 3157408

Результат для класса Test2 (20 методов):

used: 3157408

Я запустил его в двух отдельных сценариях, так как запуск двух тестов в одном script, по-видимому, показал некоторое внутреннее распределение PHP, а второй тест потреблял меньше памяти, чем первый, независимо от того, какой из них первый или второй.

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

Ответ 2

Но если у класса будет 20 свойств

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

У меня будет в дополнение к этому добавить 40 методов.

Совсем нет. Если эти классы не являются строгими структурами данных, вы не хотите, чтобы на них были Getters и Setters, потому что они разрушают инкапсуляцию. Поместите методы в открытый API, с помощью которых вы сообщаете объектам что-то делать.

И моя забота о том, как это замедлит script и гораздо больше памяти, это потребует (помните, что у меня будет несколько классов, подобных этому).

Это не проблема.

Другим решением может быть использование магических функций __set, __get, но я не хочу, потому что завершение кода в разработке IDE не будет предлагать свойства, которые имеют решающее значение для меня.

Современные IDE могут автозаполняться по магическим методам.

Однако, если вы уже обеспокоены производительностью на микроуровне, тогда вам не нужны магические методы, потому что они определенно медленнее.

Кроме того, Magic Methods не являются заменой для геттеров и сеттеров, но обработчики ошибок, которые запускаются, когда вызывалось недоступное свойство или метод.

Кроме того, магические методы неочевидны и делают сложными для чтения API.

Ответ 3

Помните, что мой код считал, что имя свойства было объявлено в нижнем регистре...

  <?php

    class Modelo {
        var $attr1 = "default";
        var $attr2 = 0;


        public function __call($name, $arguments)
        {
            if (method_exists($this, ($method = $name))){
                return $this->$method();
            }
            else{       
                $attribute = split("get",$name);
                if(count($attribute)==2){
                    $attribute = strtolower($attribute[1]);
                    if(isset($this->$attribute)){
                        return ($this->$attribute);
                    }
                }else{
                    $attribute = split("set",$name);
                    if(count($attribute)==2){
                        $attribute = strtolower($attribute[1]);
                        if(isset($this->$attribute) && count($arguments)==1){
                            $this->$attribute=$arguments[0];
                        }else{
                            die("$name number of arguments error: ".join($arguments,","));
                        }
                    }else{
                        die("$name doesn't exist!");
                    }               
                }           
            }
        }


    }

    echo "<pre>";
    $m = new Modelo();
    print_r(
        array(
            "objetct"=>$m
            ,"getAttr1"=>$m->getAttr1()
            ,"getAttr2"=>$m->getAttr2()
        )
    );
    echo "setAttr1\n";
    $m->setAttr1("by set method");
    print_r(
        array(
            "objetct"=>$m
            ,"getAttr1"=>$m->getAttr1()
            ,"getAttr2"=>$m->getAttr2()
        )
    );

    ?>

Ответ 4

Как уже говорилось, довольно странно, что ваш класс должен иметь так много свойств. Однако иногда это может произойти (довольно редко). Но, как правило, эти свойства должны иметь некоторую ссылку: так что вы можете хранить их в хэш-карте, а не в качестве свойства. Затем вы просто используете один метод в качестве получателя.

Теперь это, безусловно, будет больше ресурсов, потребляющих, правда. Что касается автозаполнения, используйте константы: вы просто наберете что-то вроде:

 $my_class->getFromHashMap($parameter)

И при вводе вашего параметра вы будете использовать константу, хранящуюся в классе: здесь автозаполнение должно помочь вам.

Ответ 5

Чтобы свойства вашего класса, которые были реализованы с помощью магических методов, были выделены с помощью среды IDE, просто используйте тег @property PHPDoc @property, например:

<?php
/**
* @property int id Blog post ID
* @property string title Blog post Title
*/
class Post {

}

Подробнее о PHPDoc '@property здесь: http://manual.phpdoc.org/HTMLSmartyConverter/PHP/phpDocumentor/tutorial_tags.property.pkg.html

Как и по другим вопросам, поставленным под сомнение - комментарий Karoly Horvath полностью охватывает те PHP OOP, многие сеттеры, геттеры.

Ответ 6

Вы можете попробовать следующее:

trait get_set {

public function set($what, $value)
{
    $this->{$what} = $value;
}

public function get($what)
{
    return $this->{$what};
}

}

Он будет работать с общедоступными и защищенными переменными. Вы можете добавить if (! Isset ($ this → {$ what}) error()