За последние 24 часа нас посетили 21683 программиста и 1060 роботов. Сейчас ищут 714 программистов ...

PHP OOП статический метод

Тема в разделе "PHP для профи", создана пользователем Evgenij85, 12 фев 2018.

Метки:
  1. Evgenij85

    Evgenij85 Новичок

    С нами с:
    20 сен 2017
    Сообщения:
    48
    Симпатии:
    0
    Привет, ребята подскажите , не уверен что так можно но все же спрошу ,
    как правильно обратится со статического метода к обычному свойству (не константа) ?

    к примеру
    PHP:
    1. publick $a;
    2. public static function b(){
    3.   return $this->$a;
    4. }
    можно конечно сделать свойство $a статическим и обратиться self::$a но как по мне не совсем красиво и я к примеру это свойство хочу в других не статических методах использовать как быть подскажите
     
    #1 Evgenij85, 12 фев 2018
    Последнее редактирование модератором: 15 фев 2018
  2. valentinnew

    valentinnew Активный пользователь

    С нами с:
    30 янв 2011
    Сообщения:
    160
    Симпатии:
    35
    нельзя в статическом методе обращаться с свойству объекта.
     
    Evgenij85 нравится это.
  3. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.554
    Симпатии:
    1.754
    @Evgenij85, статические свойства и статические методы - это свойства и методы, общие для всех экземпляров. Поэтому в статические методы не передаётся ссылка на экземпляр $this (да, на самом деле $this - это дополнительный скрытый параметр). Соответственно, чтоб получить доступ к полю объекта, надо его явно в статический метод передать через параметр, либо создать его внутри статического метода
     
    artoodetoo нравится это.
  4. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.410
    Симпатии:
    1.768
    можно сделать $а статик и обращаться. Со всеми вытекающими.
     
  5. Deonis

    Deonis Старожил

    С нами с:
    15 фев 2013
    Сообщения:
    1.521
    Симпатии:
    504
    Чисто теоретически можно, но это не красивее, чем self::$a и чувствую, что меня будут бить за то, что я вам такое показываю :)
    PHP:
    1. <?php
    2. class A {
    3.     public $a = 'Hi';
    4.     public static function b() {
    5.         return (new static)->a;
    6.     }
    7. }
    8. echo A::b(); // Hi
     
    Walk и Evgenij85 нравится это.
  6. Zuldek

    Zuldek Старожил

    С нами с:
    13 май 2014
    Сообщения:
    2.381
    Симпатии:
    344
    Адрес:
    Лондон, Тисовая улица, дом 4, чулан под лестницей
    чистка зубов через задницу
     
  7. Evgenij85

    Evgenij85 Новичок

    С нами с:
    20 сен 2017
    Сообщения:
    48
    Симпатии:
    0
    а какие вытекающие могут быть с статистическими свойствами безопасность чтоли ?
     
  8. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.410
    Симпатии:
    1.768
    один на всех
     
  9. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.554
    Симпатии:
    1.754
    @Evgenij85, расскажи, чем классы от объектов отличаются?
     
  10. Evgenij85

    Evgenij85 Новичок

    С нами с:
    20 сен 2017
    Сообщения:
    48
    Симпатии:
    0
    если ничего не путаю обьект экземпляр класса , а класс это часть функциональности обьекта , чем это поможет в моем вопросе ?
     
  11. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.554
    Симпатии:
    1.754
    Разные названия одного и того же - не есть определение.

    Хорошо, тогда так. Чем один объект класса А отличается от другого объекта класса А
     
  12. Evgenij85

    Evgenij85 Новичок

    С нами с:
    20 сен 2017
    Сообщения:
    48
    Симпатии:
    0
    если не ошибаюсь , ничем не должен отличаться
     
  13. Evgenij85

    Evgenij85 Новичок

    С нами с:
    20 сен 2017
    Сообщения:
    48
    Симпатии:
    0
    и в чем суть вопросов мне же нужно вывод сделать ?
     
  14. valentinnew

    valentinnew Активный пользователь

    С нами с:
    30 янв 2011
    Сообщения:
    160
    Симпатии:
    35
    Залей сюда весь код класса. Как сделать, зависит от конкретного случая.
     
  15. Evgenij85

    Evgenij85 Новичок

    С нами с:
    20 сен 2017
    Сообщения:
    48
    Симпатии:
    0
    Код (Text):
    1. class AffilatesLevel extends \yii\db\ActiveRecord
    2. {
    3.     const CACHE_TIME = 60;
    4.     const STATUS_ACTIVE = 1;
    5.  
    6.     public static $amount;
    7.     public static $user;
    8.     public static $user_main;
    9.  
    10.  
    11.     /**
    12.      * @inheritdoc
    13.      */
    14.     public static function tableName()
    15.     {
    16.         return 'table_name';
    17.     }
    18.  
    19.     /**
    20.      * @inheritdoc
    21.      */
    22.     public function rules()
    23.     {
    24.         return [
    25.             [['interest_rate', 'status'], 'integer'],
    26.         ];
    27.     }
    28.  
    29.     /**
    30.      * @inheritdoc
    31.      */
    32.     public function attributeLabels()
    33.     {
    34.         return [
    35.             'id' => 'ID',
    36.             'interest_rate' => 'Interest Rate',
    37.             'status' => 'Status',
    38.         ];
    39.     }
    40.  
    41.     public static function getAll()
    42.     {
    43.         if (!$arr = Yii::$app->cache->get('affilates_All')) {
    44.             $arr = array();
    45.             $values = static::find()->where(['status' => self::STATUS_ACTIVE])->asArray()->all();
    46.             foreach ($values as $value) {
    47.                 $arr[$value['id']] = [$value['interest_rate']];
    48.             }
    49.             Yii::$app->cache->set('affilates_All', $value = $arr, self::CACHE_TIME );
    50.         }
    51.         return $arr;
    52.     }
    53.  
    54.     /**
    55.      * @param $level
    56.      * @return mixed
    57.      * Метод кеширования.Ожидаем ид уровня, а отдаем процент уровня.
    58.      */
    59.     public static function getValueInterest($level)
    60.     {
    61.         if (!$value = Yii::$app->cache->get('affilates_level_interest')){
    62.             Yii::$app->cache->set('affilates_level_interest', $value = static::getAll(), self::CACHE_TIME );
    63.         }
    64.  
    65.         return $value[$level][0];
    66.     }
    67.  
    68.  
    69.  
    70.     /**
    71.      * @param $level
    72.      * @return mixed
    73.      * Метод кеширования.Ожидаем ид уровня, а отдаем статус уровня.
    74.      */
    75.     public static function getValueStatus($level)
    76.     {
    77.         if (!Yii::$app->cache->get('affilates_level_status')){
    78.             $model = static::find()->all();
    79.             $arr = array();
    80.             foreach ($model as $value){
    81.                 $arr[$value->id] = [$value->status];
    82.             }
    83.             Yii::$app->cache->set('affilates_level_status', $arr,self::CACHE_TIME );
    84.         }
    85.         else{
    86.             $arr = Yii::$app->cache->get('affilates_level_status');
    87.         }
    88.         return $arr[$level][0];
    89.     }
    90.  
    91.     /**
    92.      * Метод проверяет активность уровня если уровень выше отключен соотвественно уровень ниже не может работать
    93.      * Расчет с первого уровня
    94.      * $level - входящий параметр это уровень
    95.      * возвращает true или false
    96.      * $level integer
    97.      */
    98.     public static function getActiveLevel($level)
    99.     {
    100.         if ($level == 1){
    101.             if (self::getValueStatus(1) == 1){
    102.                 return true;
    103.             }
    104.         }
    105.         if ($level == 2){
    106.             if (self::getValueStatus(1) == 1 && self::getValueStatus(2)==1){
    107.                 return true;
    108.             }
    109.         }
    110.  
    111.         if ($level == 3){
    112.             if (self::getValueStatus(1) == 1 && self::getValueStatus(2)==1 && self::getValueStatus(3)==1){
    113.                 return true;
    114.             }
    115.         }
    116.  
    117.         if ($level == 4){
    118.             if (self::getValueStatus(1) == 1 && self::getValueStatus(2)==1 && self::getValueStatus(3)==1 && self::getValueStatus(4)==1){
    119.                 return true;
    120.             }
    121.         }
    122.  
    123.         if ($level == 5){
    124.             if (self::getValueStatus(1) == 1 && self::getValueStatus(2)==1 && self::getValueStatus(3)==1
    125.                 && self::getValueStatus(4)==1 && self::getValueStatus(5)==1){
    126.                 return true;
    127.             }
    128.         }
    129.  
    130.         if ($level == 6){
    131.             if (self::getValueStatus(1) == 1 && self::getValueStatus(2)==1 && self::getValueStatus(3)==1
    132.                 && self::getValueStatus(4)==1 && self::getValueStatus(5)==1 && self::getValueStatus(6)==1){
    133.                 return true;
    134.             }
    135.         }
    136.  
    137.  
    138.         return false;
    139.     }
    140.  
    141.     /**
    142.      * Метод получает всех id юзеров и id_affiliate
    143.      * с данным масивом мы сможем работать когда будем проверять существуют партнеры ниже по уровню или нет
    144.      * Ключ массива есть id основного user значение это affilates_id
    145.      * Пример массива array(14) { [1]=> NULL [18]=> int(31) [21]=> int(18) [22]=> int(21) [78]=> NULL [79]=> NULL
    146.      * [80]=> int(0) [81]=> int(80) [82]=> int(81) [83]=> int(82) [84]=> int(83) [85]=> int(84) [86]=> int(85) [87]=> int(81) }
    147.      */
    148.     public static function getBelow()
    149.     {
    150.         if (!$levels = Yii::$app->cache->get('cache_level_below')) {
    151.             $levels = ArrayHelper::map(User::find()->select('id, user_affiliate_id')->asArray()->all(),'id', 'user_affiliate_id');
    152.             Yii::$app->cache->set('cache_level_below', $levels, self::CACHE_TIME);
    153.         }
    154.  
    155.         return $levels;
    156.     }
    157.  
    158.     /**
    159.      * @param $id ид юзера
    160.      * @return mixed
    161.      * Метод возвращает юзернейм пользователя
    162.      *
    163.      */
    164.     public static function getUserName($id)
    165.     {
    166.         if (!$levels = Yii::$app->cache->get('chanche_level_username')) {
    167.             $levels = ArrayHelper::map( User::find()->select('id, username')->asArray()->all(),'id', 'username');
    168.             Yii::$app->cache->set('chanche_level_username', $levels, self::CACHE_TIME);
    169.         }
    170.  
    171.         if(!isset($levels[$id])){
    172.             return 'undefended';
    173.         }
    174.  
    175.         return $levels[$id];
    176.     }
    177.  
    178.     /**
    179.      * Распределение по реферальной программе
    180.      * $user - обьект юзера который сделал пополнение , далее ищем кто подключал реффералов и начисляем им бонусы в
    181.      * зависимости от уровня реферальной программы.
    182.      * $amount сумма на которую пополнил $user
    183.      * $namePaymentSystem название платежной системы
    184.      */
    185.    public static function distributionReferralProgram($user, $amount = 0.00, $namePaymentSystem = '')
    186.    {
    187.        if(!is_object($user) && !is_numeric($amount) && !is_string($namePaymentSystem)){
    188.            return false;
    189.        }
    190.        if(Settings::getSettingsValue('aff_onoff') != '1'){ //включаем партнерскую программу
    191.            return false;
    192.        }
    193.  
    194.        self::$user = $user;
    195.        self::$amount = (float)$amount;
    196.        $count_level = count(self::getAll());
    197.  
    198.  
    199.        for ($i = 1; $i <= $count_level; $i++){
    200.            if(AffilatesLevel::getActiveLevel($i) && self::$user->user_affiliate_id != null){
    201.                $refAmount = self::$amount * (AffilatesLevel::getValueInterest($i) / 100);
    202.                self::$user_main = User::findOne(self::$user->user_affiliate_id);
    203.  
    204.                if (!empty(self::$user)) {
    205.                    self::$user_main->power += $refAmount;
    206.                    self::$user_main->save();
    207.  
    208.                    $aff = new Affiliates();
    209.                    $aff->amount = $amount;
    210.                    $aff->aff_amount = $refAmount;
    211.                    $aff->aff_amount_usd = $refAmount;
    212.                    $aff->aff_level = $i;
    213.                    $aff->user_id = self::$user->user_affiliate_id;
    214.                    $aff->ref_user_id = self::$user->id;
    215.                    $aff->comment = 'For you charged from referal ' . self::$user->username;
    216.                    $aff->payment_system = $namePaymentSystem;
    217.                    $aff->payment_amount = self::$amount ;
    218.                    if($aff->save(false)){
    219.                        self::$user = self::$user_main;
    220.                    }
    221.                }
    222.            }else{
    223.                break;
    224.            }
    225.        }  //for end
    226.  
    227.        return true;
    228.    }
    и у меня получается много статики из-за того что использую много в Views , может конечно во многом не прав но нужно развиваться ,
    то что я уточнял последний метод distributionReferralProgram() я обращался к статическим свойствам , но код мне не нравится, готов выслушать всю критику по коду
     
  16. valentinnew

    valentinnew Активный пользователь

    С нами с:
    30 янв 2011
    Сообщения:
    160
    Симпатии:
    35
    Так а зачем тебе здесь сообще сохранять в статическую переменную? Используй ту, что передается в параметрах?
    Ты понимаешь, что если после вызова этого метода, вызвать другой метод, в котором задействовать переменную self::$user, например, она будет заполнена?
    Статические переменные в классе - это альтернатива глобальным переменным.
    И вообще, с таким подходом, если перенести код из AffilatesLevel::distributionReferralProgram() функцию AffilatesLevel_distributionReferralProgram() абсолютно ничего не изменится. Это не ООП.
    И в amount используй целое.
     
  17. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.554
    Симпатии:
    1.754
    Ну вот я объект класса "человек", и вы объект класса "человек", мы ничем не отличаемся? Или всё таки каждый своего роста, с разной длинной различных органов? Вот это всё (рост, длина всяких органов) - соответственно, нестатические свойства (потому что у всех разные). А какой-нибудь там показатель количества женщин на земле, или количество китайцев - это статические свойства, общие для всех экземпляров класса человек
     
  18. Abyss

    Abyss Старожил

    С нами с:
    12 дек 2015
    Сообщения:
    1.298
    Симпатии:
    218
    Адрес:
    Default city
    А вот нихрена, это свойства объекта Race, одного из тех, который наследует Homo.
     
  19. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.410
    Симпатии:
    1.768
    нехрен потому что аналогии придумывать
     
  20. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.554
    Симпатии:
    1.754
    По-любому, статика.
     
  21. Evgenij85

    Evgenij85 Новичок

    С нами с:
    20 сен 2017
    Сообщения:
    48
    Симпатии:
    0
    в продолжении нашего диалога я пытаюсь уйти от статических методов , подскажите насколько будет правильно использовать обычный метод а к нему обращаться статическим методом к примеру через (new self())->personalInterestProduct($id, $short) и не будит ли это потери скорости или увеличении памяти ?

    Код (Text):
    1.  public function personalInterestProduct($id, $short)
    2.     {
    3.         $this->columnName = $short.'_'.$id;
    4.         if ($this->personal == null){
    5.             $this->personal = self::find()->where(['user_id'=>12])->asArray()->One();
    6.         }
    7.         if(is_array($this->personal) && !array_key_exists($this->columnName, $this->personal)){
    8.             return 0;
    9.         }
    10.  
    11.         if($this->personal[$this->columnName] == 0){
    12.             return 0 ;
    13.         }
    14.  
    15.         return (float)$this->personal[$this->columnName] / 100 ;
    16.     }
    17.  
    18.     public static function getPersonalInterestProduct($id,$short)
    19.     {
    20.        return (new self())->personalInterestProduct($id, $short);
    21.     }
     
  22. valentinnew

    valentinnew Активный пользователь

    С нами с:
    30 янв 2011
    Сообщения:
    160
    Симпатии:
    35
    не делай ооп ради ооп. ооп упрощает сложные проекты, а ты усложняешь. Зачем тебе здесь создавать отбъект?
    И используй не self а static
     
    Walk нравится это.
  23. Evgenij85

    Evgenij85 Новичок

    С нами с:
    20 сен 2017
    Сообщения:
    48
    Симпатии:
    0
    если обращаюсь через
    return static::personalInterestProduct($id, $short);

    у меня ругается на this в методе personalInterestProduct Ошибка : Using $this when not in object context

    из ошибки я так понимаю что он начинает воспринимать метод personalInterestProduct как статический
    http://prntscr.com/ifi5s2
     
  24. valentinnew

    valentinnew Активный пользователь

    С нами с:
    30 янв 2011
    Сообщения:
    160
    Симпатии:
    35
    я писал, что надо испольовать вместо self - static. https://secure.php.net/manual/ru/language.oop5.late-static-bindings.php
    В твоем случае надо сначала разобраться с пониманием что такое объект и зачем он нужен, потом рефакторить код.
     
  25. Evgenij85

    Evgenij85 Новичок

    С нами с:
    20 сен 2017
    Сообщения:
    48
    Симпатии:
    0
    то есть так будет правильно
    return (new static())->personalInterestProduct($id, $short); ?