Как стать автором
Обновить

Комментарии 131

Меня всегда очень бесило обилие массивов когда брал проекты на битрикс. Особенно если нужно было сделать доработки после реализации проекта джуном самоучкой. $arResult это просто trash, кто работал с битрикс меня поймет.
Судя по тому, что ключи массивов написаны капсом — его писали блондинки.
НЛО прилетело и опубликовало эту надпись здесь
Главная проблема битрикса конечно не в массивах, а в огромном техническом долге, который только усугубляется.
А по поводу массивов — работа через объекты позволяет использовать автодополнение и как минимум избавляет от ошибок из-за опечаток. Ну тут уже встаёт вопрос падения производительности.
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
Боюсь заминусуют но тут:
new StockData("Perch", 50, "2012-02-02 05:23:32")

можно и статическим методом обойтись, зачем каждый раз инстацировать объект, для выполнения одного вычисления?
Не говори так!
Статические методы не ООП подход?
Я у автора спрашиваю, просто.
статические методы это обычные функции привязанные к контексту каких-то объектов, они обозначают что мол "я функция которая позволяет вам что-то сделать с объектами этого типа".
Статические методы — это нормально, плохо и не ОО подход — статические методы, которые оперируют каким-то своим состоянием. stateful-статика — это плохо, stateless статика — это нормально. Класс Utils и подобные — плохо, поскольку тогда мы просто пишем функции не привязанные ни к какому контексту, а стало быть лучше просто функции и писать. Благо с php 5.6/7 использование функций — одно удовольствие:
<?php

use function \myCoolApp\array\{map, reduce, last};

function makeSomethingUseful(array $collection) {
    return reduce(
         map($collection, function($item) {
                 // do something
                 return $item;
         }),
         function ($result, $item) {
             return $result + $item;
         }
    );
}
статические методы это обычные функции привязанные к контексту каких-то объектов, они обозначают что мол «я функция которая позволяет вам что-то сделать с объектами этого типа».

Вы сейчас описали обычные функции, разве нет?
Единственная проблема, в том что язык не всегда помогает дополнять функциями существующие классы, поэтому иногда возникают "статические" функции.
Я больше к тому что разницы между "функцией" и "статическим методом" с технической точки зрения нет. Разница лишь в семантике и доступе к внутреннему состоянию объекта. То есть по сути если функция "должна" знать о реализации объекта, скажем для удобства, то ее можно сделать статическим методом.

Например есть у нас ValueObject который содержит какое-то состояние, и мы хотим по нему отсортировать коллекцию. Причем делать геттер для конкретного поля нельзя. В итоге у нас появляется статический метод compare, который действует как обычная функция, но имеет доступ к внутреннему состоянию объекта своего типа. Пример таких извращений.
Простите, вот тут я ввел вас в заблуждения. Я согласен с вашими утверждениями, но это все еще не ООП подход, так как "функции" и "статический метод" нарушают принципы ООП.
НЛО прилетело и опубликовало эту надпись здесь
Вы сами поняли что написали?

Сингелтон — это вырожденный случай registry, который гарантирует нам то, что в рамках этого процесса будет порожден один единственный объект. Это нужно обычно только в оооочень редких случаях когда у нас есть физические ограничения. Например у нас может быть объект, который обеспечивает работу с каким-то внешним устройством через PCI или USB и вам смертельно важно сохранить последовательность операций иначе внешний девайс сломается например.

В WEB и конкретно в PHP сингелтоны… ну по сути вообще не нужны.

Так вот, вернемся к вашему… случаю. У "сингелтона" по сути нет никаких статических методов кроме как "create". По сути этот stateful статический метод и есть имплементация паттерна сингелтон. Далее все остальные методы — обычные методы.

И все зло сингелтона — это stateful статика. Больше никакого зла. Ну и я уже описал случаи когда он нам нужен, и для таких случаев пойти на такое вот "нарушение" вводя "почти глобальное" состояние можно. В PHP таких задач… меньше десятитысячной доли процента.
НЛО прилетело и опубликовало эту надпись здесь
Почитайте мануал http://php.net/manual/ru/language.oop5.static.php и особенно строку
Так как статические методы вызываются без создания экземпляра класса, то псевдо-переменная $this не доступна внутри метода, объявленного статическим.

Статические методы не инстацируют объект, так что ваша теория
Так вот, что я хотел сказать-то. Класс и его статические методы можно представить себе как синглетон, который в общем случае может быть оправдан, а может быть натягиванем совы на глобус

Немного притянута…
простейший пример синглтона
class psevdoDb {

    private $_connect = null;    

    private function __constructor() {
    }

    public function getConnect() {
        if(!is_null($this->_connect)) {
              return $this->_connect;
        }

        $this->_connect = new PDO('bla bla bla');
        return $this->_connect;
    }

}

или статический метод
class psevdoDb {

    private static $_connect = null;    

    private function __constructor() {
    }

    public static function getConnect() {
        if(!is_null(self::$_connect)) {
              return self::$_connect;
        }

        self::$_connect = new PDO('bla bla bla');
        return self::$_connect;
    }

}

Ну и т.д.
НЛО прилетело и опубликовало эту надпись здесь
Я бы сказал, что (публичные) статические методы нужны в тех случаях, когда они возвращают экземпляр класса.

Например, именованные конструкторы:

class User {
private $login, $password, ...;
public static function constructWithCredentials(Credentials $creds):User {
$self = new self();
$self->login = $creds->getLogin();
$self->password = $creds->getPassword();
return $self;
}
}
Как они упаковываються? к примеру:
      public static function getObject() {
            new static()
      }

Цитата:
Одиночка (англ. Singleton) — порождающий шаблон проектирования, гарантирующий, что в однопоточном приложении будет единственный экземпляр класса с глобальной точкой доступа.

Да статическими методами и параметрами класса реализуеться singleton, но эта реализация разрабатываеться программистом, а не статичным параметром/методом.
простой пример, одно соеденение с базой или 100, 100 пользователей и лимит соеденений превышен. Этот патерн довольно широко распространён в вебе. сессия, соеденение с б.д. классы которые пронести через 100 файлов и сохранить структуру. Да и лишних созданных объектов.
регитри и IoC/DIC. Коннекшен к базе — бывает такое что надо больше одного в рамках одного процесса. Сессия? нет сессий, или сессия в базе. Никаких сингелтонов.

Проблема сингелтонов в том что это пожалуй самый простой в реализации паттерн и его юзат все кому не лень. Хотя по хорошему у вас просто не должно возникать в нем необхоздимости. Если вы зависимости до сих пор руками разгребаее — ну это ваша проблема. А контейнеры зависимостей делают это за меня и сами следят что не сделают 2 инстанса вместо одного.
Так какие принципы нарушают функции/статические методы? Все ооп — это типы и сокрытие состояния. Так что наш статический метод нарушает? Инкапсуляцию?

Статический метод не имеет никакого отношения к принципам ООП. Это "функция", которая имеет прямой доступ к состоянию объекта того типа, за которым она закреплена. Вот и все. Это не нарушает инкапсуляцию, так как детали реализации известны только члену объекта относящегося к данному типу.
статических методов просто нет в ООП.
Там только объекты. Как можно выразить статический метод через взаимодействие через объекты?
Статический метод — это обычная функция (как правило чистая), которая имеет доступ к внутреннему состоянию объекта того типа, за которым она закреплена. Это непосредственно к ООП имеет прямое отношение, так как позволяет нам на каждый чих для любых мелких задач не делать отдельные методы геттеры предоставляющие доступ к состоянию объекта. Вот и все.
Вся суть в удобстве. Статика — это хорошо, stateful статика плохо.
Ну и да, если мы будем выражать все исключительно объектами и сообщениями между ними, если мы говорим о языке без ad-hoc полиморфизма, возможности делать различные варианты конструкторов и т.д. то наш код просто превратится в раздудую систему из объектов.
А ведь все ООП вертится только вокруг сокрытия состояния от чужих глаз (в этом случае статика — не чужие глаза), и управление зависимостями.
Не нарушают они принципов сам по себе. Они могут нарушать, если программист захочет нарушать или не сможет не нарушать, но это относится и к обычным свойствам и методам.
В ООП просто нет этих сущностей. Возможно, я неправильно написал фразу, но суть моей претензии только в этом.
В классическом ООП нет и сущности "метод", тем не менее в мэйнстримовых ООП-языках, метод лишь разновидность функции (когда де-факто, а когда и "де-юре" как в PHP), а то и вообще обычная функция, которая называется методом, лишь потому что объект на неё ссылается.
Прошу прощения, но в ООП есть "метод" у объекта. Иначе как с ним работать?
в ООП есть только состояние + сообщения между объектами. Методы и их вызовы — это один из вариантов реализации.
НЛО прилетело и опубликовало эту надпись здесь
у статики не должно быть состояния, но прямой доступ к состоянию инстансов оно иметь должно. В этом и соль. Если вам надо что-то сделать в рамках нескольких сущностей, и не совсем понятно кому эта операция должна быть доверена (например отсортировать коллекцию value object-ов) — то логично вынести это дело в статический метод. Тогда никаких разночтений и это весьма и весьма удобно.
Вот я не то чтобы сторонник массивов, ООП это конечно правильно, но аргументы у вас как-то не очень способствуют пониманию преимуществ.
// Что такое 100, что такое "2013-10-04 12:16:47"?
// Понятно, что IDE помогает, но когда такие билдеры на пол-экрана,
// как-то надоедает мышкой по переменным водить, чтобы понять что тут происходит.
$pond->addStockData(new StockData("Bream", 100, "2013-10-04 12:16:47"));

// Вот если массивом объявить, то сразу понятно, что 100 - это количество. Да и выглядит компактнее.
$pond = [
    'name' => 'Breakspear',
    'amenities' => ['shop'],
    'fishBreeds' => [
        ['name' => 'Bream', 'number' => 100, 'stocked' => '2013-10-04 12:16:47'],
        ['name' => 'Perch', 'number' => 50, 'stocked' => '2012-02-02 05:23:32'],
        ['name' => 'Common Carp', 'number' => 10, 'stocked' => '2011-01-23 14:42:59'],
    ],
];
$ponds[] = $pond;

К тому же для объектов надо билдеры писать, а массив объявил и все. А если из базы грузим, то и объявлять не надо.

Намного меньше кода для получения того же результата.

Код будет такой же, только в функцию getNamed() добавится аргумент $ponds, а в getTotalStocked() аргумент $pond.

Часто это реализовывается как многофункциональные классы со здоровыми методами, использующими вложенные циклы.

А как вы без вложенных циклов посчитаете $stockedFish? Код будет аналогичный, один цикл по $ponds, второй в getTotalStocked($pond).

$ponds = new PondsCollection(); $ponds->add(...);

Зачем мне создавать коллекцию для методов типа add(), если я могу просто сделать $ponds[] = $pond? А если индексировать массив не числами, а первичными ключами сущности pond, то и получение или удаление можно сделать без всяких циклов, просто unset($ponds[$pond->id]).

Я хочу сказать, что такие аргументы только добавляют непонимания для тех, кто везде использует массивы вместо объектов.
Массивы при всех их минусах имеют большой плюс — зайдя в средненький по качеству код с десятком разных структур (хранящихся в массиве) обычно понимаешь как эту структуру модифицировать после пары вардампов, интерфейс взаимодействия понятен и знаком любому программисту. Если упираться сильно в "правильный" ООП, то может получиться обратная ситуация — в коде куча структур тупо эмулирующих хранение неких данных, причем у каждой из этих структур автор кода радостно напридумывал методов ->add (ну, у одной add, у другой addItem, у третей addOne() — именование зависит от настроения, конечно) В результате — без подсказок IDE и изучения кода — шагу не ступишь. При доработках таких "классов" — обычно еще и наступает борьба с плохими абстракциями. Мораль какая? Везде должен быть баланс) не надо притягивать ООП за уши там где это не очень надо, надо смотреть на конкретную ситуацию.
Полностью согласен, но найти ошибку в таком коде будет проблематично:
'fishBreeds' => [
        ['name' => 'Bream', 'numbr' => 100, 'stocked' => '2013-10-04 12:16:47'],
        ['name' => 'Perch', 'number' => 50, 'stocked' => '2012-02-02 05:23:32'],
        ['name' => 'Common Carp', 'number' => 10, 'slocked' => '2011-01-23 14:42:59'],
    ]
```А их там аж 2...
Но для того чтобы от них избавиться не нужна ООП модель, достаточно объявить константы и использовать их, конечно будет не айс, но и не будет механических ошибок.
Ну и да, с именованным массивом всё не так ужасно, а вот если переписать это на обычный, и представить как с ним работать — вот это ещё тот адок — array + magic numbers много-много радости детишкам принесут...
'fishBreeds' => [
____['name' => 'Bream',_______'numbr' => 100, 'stocked' => '2013-10-04 12:16:47']
___ ,['name' => 'Perch',_______ 'number' => 50, 'stocked' => '2012-02-02 05:23:32']
___ ,['name' => 'Common Carp', 'number' => 10, 'slocked' => '2011-01-23 14:42:59']
]
```А их там аж 2…

При правильном форматировании обе бросаются в глаза. (мда, без тегов выглядит уныло)
Пожалуйста, не нужно советовать так форматировать код, это пережитки прошлого.
А вообще при добавлении нового массива, никто не будет набирать ключи с клавиатуры, их можно скопировать, или ctrl+d в ide.
НЛО прилетело и опубликовало эту надпись здесь
это пережитки прошлого

а, ну извините, не держите зла.
Безусловно в вашем посте есть здравый смысл, но во всем нужна мера.
Может получиться так, что новичек прочтет ваш пост и начнет плодить сотни классов оберток, когда это нужно и не нужно.
Не стоит забывать, что на объявление класса и тратится процессорное время и оперативная память (внутренее устройство сложнее).
Доступ к данным поля объекта через вызов метода значительно медленнее, чем доступ к элементу массива, а если еще используются магические методы, разница огромна.
«внутренее устройство сложнее»

Пожалуйста, прекратите распространять этот миф времен PHP4.

https://gist.github.com/nikic/5015323
Вы невнимательно прочитали мой комментарий.
В какой момент очевидные вещи стали мифами?
Вот вам несколько тестов на скорость доступа к данным:
test_array.php — использование массива
test_object.php — использование класса-обертки
test_object_magic.php — использование класса-обертки с магическим методом
PHP 7.0.4
Исходники
Array:
<?php
$time = microtime(true);
$data = [0,1,2,3,4,5,6,7,8,9];
for($i=0;$i<500;$i++){
  $item = $data[rand(0,9)];
}
echo (microtime(true) - $time).' '.memory_get_usage()."\n";

Object:
<?php
$time = microtime(true);

class Example
{
    protected $data = [0,1,2,3,4,5,6,7,8,9];

    public function getItem($index)
    {
      return $this->data[$index];
    }
}

$object = new Example();

for($i=0;$i<500;$i++){
  $item = $object->getItem(rand(0,9));
}

echo (microtime(true) - $time).' '.memory_get_usage()."\n";

Object + magic:
<?php
$time = microtime(true);

class Example
{
    protected $data = [0,1,2,3,4,5,6,7,8,9];

    public function __call($method , $params)
    {
      if($method == 'getItem'){
    return $this->data[$params[0]];
      }
    }
}

$object = new Example();
for($i=0;$i<500;$i++){
  $item = $object->getItem(rand(0,9));
}

echo (microtime(true) - $time).' '.memory_get_usage()."\n";


XDebug Profile


Array: time: 0.006110 memory: 365072
Object: time: 0.012696 memory: 366160
Object + magic: time: 0.017254 memory: 366448
Эх, сложность алгоритмов оцениваеться не по времени выполнения, а в зависимости от входных данных, и операций над ними.
Про сложность алгоритмов я ничего не писал. А так, полностью согласен.
Из вашего комментария следует, что не только при использовании оберток, а вообще таки всегда, мой ответ относится только к этой части, я даже процитировал.

А обертки — отдельный вопрос, как по мне, сами по себе они бессмысленны. ООП нужно не для того, чтобы писать анемичные обертки, а для инкапсуляции логики.
Если объявить плоский класс с публичными свойствами, то да, все будет отлично. Но это же не то, для чего придумывали ООП, верно? А в том случае, о котором говорит комментатор выше — доступ к данным через методы — оверхед все равно будет. Хорошо это или плохо, допустимо или недопустимо, наверное, нужно решать в каждом случае отдельно.
НЛО прилетело и опубликовало эту надпись здесь
ООП придумали не для того, чтобы писать геттеры и сеттеры :-)
В php я не силен и возможно пример в статье так себе, но я сразу начинаю думать о классах…
Все же скажите, в PHP все действительно настолько плохо, что вы написали статью как крик отчаяния в безысходности?
Да не всё нормально в PHP, просто когда на поддержке работаешь, особено после фрилансеров и веб студий, которые клепают сайты под ключ, довольно много непонятного кода. Но это во всех языках "кастыли" пишут и на c++, c, pascal, java, js, php в общем, "кастыли" "языконезависимые".
Вот и мне думается, что в самом языке все нормально. Больше всего меня удивило, что пост посвящен конкретному одному костылю в конкретном одном ЯП. При чем сам костыль заключается исключительно в теоретически неверно выбранном паттерне к какому-то конкретному случаю. Возникает вопрос: при чем тут массивы? Может просто «проблема» в том, что порог вхождения достаточно низок, чтобы часто наблюдать некачественный код?
Жаль, что автор перевода не особо участвует в обсуждении.
Возможно я и неправ, но массив как то понятнее, структуру данных сразу видно, не надо вникать в код классов чтобы понять как получить доступ к данным, да и вносить изменения, например добавить поле в массив проще, чем перелапачивать код классов и переписывать конструкторы инициализации и саму инициализацю в том числе.
Если это одномерный массив да. Но когда многомерный, и его можно в любом месте, приложения перезаписать $array['test'] = 3 к стати как то я 3 дня искал баг, и как раз из за этого. Если у вас объект вы можете защитить данные разграничить классы которые могут туда записать и т.д. и слёгкостью отследить в какой момент произошла запись вызов сеттера(исли он реализован).
Вы немного ушли от темы массивов к глобальным переменным. Массив вполне себе может находиться внутри объекта и быть недоступен извне.
Да нет там не глобальная переменная была, там массив передовался в один метод, обрабатывался, возвращался и в другой метод. Где именно, произошла перезапись сложно отследить 'тогда я правда не пользовался xdebug', да и не всегда заметно баг. Да и тут, правильно люди говорят, что массив или объект должны использоваться по ситуации, если система построена на MVC с прослойками абстракции, и там по архитектуре приложения используються объекты, значит мы должны использовать объекты. Если удобно, и это вписываеться в архитектуру, то нужны массивы, если становиться неудобно то нужен объект. В общем всем должен управлять сдравый смысл.
Ждем статью "Хватит злоупотреблять классами!"

А по факту и то, и то — лишь инструмент и использовать его надо для подходящих для него задач.
Серебряной пули нет и не было никогда.

P.S. С классами то оёёй как можно переборщить, если везде тыкать их бездумно.
Ждем статью "Хватит злоупотреблять классами!"

"Как перестать программировать и начать жить", чо уж там
НЛО прилетело и опубликовало эту надпись здесь
Ждем статью «Хватит злоупотреблять классами!»
Не статья, но все же:
www.youtube.com/watch?v=o9pEzgHorH0
НЛО прилетело и опубликовало эту надпись здесь
Вместо var_dump попробуйте настроить xdebug и все можно увидеть прямо в IDE и даже c удаленной машины.
1001 комментарий на Хабре человека, который не может найти в переводе ссылку на источник.
Пора бы уже UI девелоперам Хабра задуматься.
Вот соглашусь. Да и сама структура ссылки на автора в виде "Перевод: %authorname%" запутывает. Получается, перевод сделал %authorname%? (по аналогии с "Графика: %artistname%", "Музыка: %composername%")
image
Ну да, не указал самого главного....:(

Статья понравилась, спасибо за перевод!
Опа! Думал, в какой-то веки на хабре нормальная статья, а тут опять перевод!
Прекрати злоупотреблять массивами в PHP
private $collection = array();
бдыщь
НЛО прилетело и опубликовало эту надпись здесь
А по мне, нет ничего плохого в массивах, если нам нужны данные без поведения, то бишь структуры. Такие, например, как конфиги.
А если нужно поведение (примерно как в статье), то, конечно, лучше код инкапсулировать внутрь данных и получить объект.
Не стоит эмулировать массивы объектами.
Я бы так сказал.
Нет ничего страшного в использовании массивов внутри границ классов или функций. Создавать массивы проще и удобней, и поддерживать код не сложно, т.к. все в одном месте.
Не стоит использовать массивы как некий набор данных для передачи или возврата из функции. В этом случае массив "разбежится" по проекту, ключи могут составляться сложным образом(не дай бог), перетекать в другие массивы(array_merge), и тогда удачной отладки. В этом случае лучше создать структуру(т.е. класс)
Кстати говоря, этот код бесполезная обертка над массивом, что она дает если в коллекцию можно добавлять элементы любого типа?
class PondsCollection implements IteratorAggregate
{
    private $collection = array();

    public function getIterator()
    {
        return new ArrayIterator($this->collection);
    }

    public function add($pond)
    {
        $this->collection[] = $pond;
    }
}

Если уж делать коллекцию определенного типа, то нужно же указать этот самый тип:
class PondsCollection implements IteratorAggregate
{
    private $collection = array();

    public function getIterator()
    {
        return new ArrayIterator($this->collection);
    }

    public function add(Pond $pond)
    {
        $this->collection[] = $pond;
    }
}

Вот теперь это определенный тип — коллекция Pond-ов.
НЛО прилетело и опубликовало эту надпись здесь
Я бы перефразировал…
«Прекрати злоупотреблять ООП в PHP»
Всегда раздражало чрезмерное использование ООП даже там где оно вообще не нужно. (Привет блондинкам из SocialEngine, по меньшей мере версии 4. Это был ад.)
Я сам сторонник классов. Но вот реалии таковы, что при переходе от массивов к классам начинает страдать производительность. В свое время убил немало времени, чтоб в одном из проектов увидеть это наглядно — и создание объектов, и итерации, и доступ к отдельным элементам — это все в классах полчается медленнее, чем в массивах. И пришлось откатить все от красивых классов к грубым массивам. Было это, правда, на 5.х, как обстоят дела в PHP7 не знаю.
Так что вывод как всегда: для разных случаев — разные решения, а универсального рецепта не сущестует
используя массивы я всего лишь c помощью require могу подгружать конфиги и данные. и php opcache мне их закеширует
этакое nosql-хранилище

$config = require «config/app.php»;

$getProducts = function () {
foreach (require «db/products/index.php» as $product) {
$product = require «db/products/». $product[«ID»]. ".php";
//… do some work with $product;
yeild $product;
}
};

foreach ($getProducts() as $product) {
print_r($product);
//…
}
Не могу согласиться. Замена массивов на объекты не даст ощутимых выгод, если в системе отсутствует ORM, и не проводилось хотя бы минимальное моделирование, а проблем прибавит:
— в объектах рано или поздно появятся private\protected поля, в итоге их сохранение (напомню, у нас нет ORM) будет неудобным и громоздким
— довольно быстро выявится потребность в ленивой загрузке, потому что поле данных\связь у объекта есть, но загружать её именно сейчас дорого\не имеет смысла
— клонирование объектов со всеми вложенными сущостями не столь тривиально, по сравнению с массивами
Вместо изначального тезиса, об использовании объектов, предложу использовать модель предметной области + какую-никаую orm.
Остается только подписаться под каждым словом. Единственное место, по хорошему, где могут появиться описанные деревья объектов — сериализатор/десериализатор для какого-либо API. Описанный же в публикации сценарий работы с БД — не что иное, как изобретение специфичного для проекта кривого и неполного подобия ORM.
Кстати, в статически типизированных языках проблемы работа с такими деревьями не составляет: есть LINQ, линзы [https://github.com/julien-truffaut/Monocle] и прочие функциональные комбинаторы.
Немого не понял смысла статьи:

Использование массивов в PHP как единицы данных плохо.

Нет не плохо, наоборот ассоциативные массивы, имхо, в PHP очень элегантны.

Нужно инкапсулировать массивы в классы для удобства работы с ним.

Конечно нужно!

> Нужно инкапсулировать массивы в классы для удобства работы с ним.

нет не нужно.
http://php.net/manual/ru/ref.array.php

посмотреть — в каждом долбаном фреймворке свои «удобные» классы для работы с массивами — да что они себе позволяют. возомнили себя умнее Расмуса…
НЛО прилетело и опубликовало эту надпись здесь
для поточной обработки сущесвуют генераторы с yeild
http://php.net/manual/ru/language.generators.overview.php — где можно уместить логику в одной функции

а итераторы на классах с кучей методов устарели и излишни.
НЛО прилетело и опубликовало эту надпись здесь
> мне приходится работать вплоть до ПХП 5.2

сочуствую. но у меня так получается — что клиенты с устаревшими движками под php 5.2 слишком мало платят и слишком многого хотят. поэтому задерживаются не долго.
а в основном неважно на чем там работает. главное чтоб запускалось. так что а я вот просто пишу новые проекты и функционал уже на php7, как в bitrix добавят поддержку вообще заживем.
для любителей старых версий получается просто дополнительные накладные расходы за перевод под старые версии php. имхо так и надо с клиентами иначе будут сидеть на старых ветках до скончания веков
НЛО прилетело и опубликовало эту надпись здесь
Знакомо с ошибками (включая свои собственные), но пути решения есть, даже если расчёты всегда производятся на лету, а не раз посчитанные результаты хранятся в БД. Как чисто технические пути (различные варианты реализации выбора алгоритмов расчёта в зависимости от, например, даты выставления счёта или заключения договора), так и административные — после исправления ошибки, выявляются проблемные сущности и бухгалтерия проводит по ним дополнительные начисления-списания. Сейчас вот переписываю проект с PHP5.3(Symfony1) на PHP7(Symfony3) и активно использую оба метода, предпочитая сначала попробовать вторым.
Подход с использованием паттерна object-value хорош, но только когда существует нормальная доменная модель. Заменять бездумно все многомерные массивы классами везде подряд, имхо, неоправданно. Многомерный массив может быть прекрасным наглядным примером, отражающим сразу и структуру данных и ее содержимое. Да, злоупотребрять не нужно, но и кардинально переписывать все на классы (так можно и заболеть ООП головного мозга) тоже не нужно. Самый правильный подход по моему мнению – максимальная простота и читаемость кода. Если массив улучшает понимание кода – он там должен быть.
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
Это Матиас то не шарит? Может быть просто вы статью не поняли?)
Как уже было сказано, я не знаю, что значат эти числа. А что, если их нужно будет 10, или нужно поменять порядок параметров?

Значит вы не усвоили принцип protected variations и не обезопасили себя от гредующих изменений.
НЛО прилетело и опубликовало эту надпись здесь
У меня тоже ООП головного мозга, но это чуть другое ООП головного мозга нежели вы писали в своей заметке. По поводу оверюза паттернов и бездумного применения принципов (взять те же сеттеры у объектов, которые явно нарушают инкапсуляцию) я с вами полностью согласен. Люди как-то пытаются понять все эти SOLID-ы и т.д. не понимая зачем вообще придумали ОО.
В целом же лучше ОО только функциональщина, вот только это уже не про PHP.
поддерживаю.

плюсанул бы — но кармы нет

эти любители ооп в конец распоясались — сколько хороших продуктов в стагнации из за той же simphony — drupal, phpbb и другие — вместо развития продукта и улучшения api — пытаются перестроить устоявшуюся структуру и впхнуть компоненты фрейморка — а в результаты получается франкеншейн
Допустим, что в сообществах drupal, phpbb и других главенствуют (захватили власть?) любители ООП, которые пишут ООП-код ради ООП. Но что мешает не любителям ООП собраться вместе и убить всех любителей ООП и форкнуть эти проекты, развивая и улучшая их, а не рефакторить ради ООП?
Не получается? Что-то мешает? Процедурный код такого объёма не поддаётся анализу и ответственному рефакторингу? Нужен какой-то инструмент уменьшения сложности, абстрагирования, повторного использования с частичным переопределением или расширением, инкапсуляции и полиморфизма, чтобы проще было развивать и улучшать продукты?
НЛО прилетело и опубликовало эту надпись здесь
У всех мейнстримовых фрейморкох слишком много абстракций, из-за чего трудно сделать даже базовые вещи, не убив много времени на изучение фреймворка.

Ну а как без изучения, да и у фреймворков на подобие symfony, zf2, yii2 хорошо документированные методы, что позваляет cms подсвечивать как магические методы класса, так и обычные, выводя их описание и список параметров.
Да и что бы писать на языке яп, его сначала надо изучить как минимум синтаксическую базу, а потом писать. Это во всех ЯП так. Кроме php обычно на нём сначала начинаю писать а потом изучают.
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
Вы приувеличиваете, в любой фреймворк/cms есть время вхождения, ну если не писать только кастыли, по этому не стоит говорить о "элементарных вещах" быстрее всё таки изучить->реализовать->не трогать, чем кастыль->баги->исправления->изучить->переписать->нетрогать. Я понимаю каждому своё, работад не давно над рукописной cms там без заморочек контроллер->данные->рендер и реализованно без кастылей и это круто всё понятно и быстро, но это только тогда когда всё хорошо написано и логично выстроенно.
НЛО прилетело и опубликовало эту надпись здесь
С самописью взял бы и сделал и не мучался.

Достаточно выкинуть Yii и использовать нормальные компоненты. Yii — очень упрощенный фреймворк для тех кто знает нужен он им или нет. С вашими запросами вам нужно что-то более гибкое, тот же Symfony или Zend. Или быстренько свой фреймворк на базе готовых компонентов собрать.
НЛО прилетело и опубликовало эту надпись здесь
Скоро вроде будут переписывать.

Весьма сомнительный бизнес-ход.
как буду плеваться и на Symfony c Zend. :)

У меня есть для вас совет — просто не завязывайтесь особо на фреймворк. Ну мол, что будет в контроллерах — плевать, а вот бизнес логика не особо то должна быть привязана к фреймворку. Да и штуки вроде роутеров и т.д. можно обойти. Я помниться на каком-то из проектов на Yii просто психанул и повесил свой маршрутизатор над Yii-ным, который обрабатывал 3-4 правила которые были нужны мне, и мне так было удобнее.
Для личных проектов есть ядро, которое писалось с моего начала программирования в 2008 году.

Попробуйте выкинуть велосипед из легаси и взять что-то нормальное. Серьезно. Я понимаю что велосипеды это весело, сам баловался, но только мне уже надоело их писать.
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
Статья ну уж слишком провокационна и холиварна. Таки фразы убивают:

«Единственные причины, по которым разработчики продолжают писать подобный код — это или неопытность или потерянность в процедурном прошлом.»

Одним предложением поставили диагноз тысячам программистам (теперь уже получается говнокодерам).

А меня наоборот тошнит от злоупотребления ООП. И если я увижу код, где вместо обычного массива разработчик сделал объект, раздув тем самым код, я выпадаю в осадок. Это однозначно усложнение кода на ровном месте. Фразы про то, что в будущем такой код будет легче поддерживать — это сказки. В реальности злоупотребление ООП приводит к появлению в проекте десятков и сотен мини-классов, часть из которых взаимозависимы, что еще сильнее усложняет код. И ладно, если бы эти сотни классов делали бы что-то полезное. Но они всего лишь заменяют массивы! Чума. Я не против ООП и сам его использую, но заменять массивы точно бы не кому не советовал.

Сложный код обычно пишут именно программисты-новички. А те, кто уже съел собаку на распутывании спагетти-кода, стараются код сделать проще. KISS-идеология — наше все.
НЛО прилетело и опубликовало эту надпись здесь
Ох уж эти невидимые аргументы :)
НЛО прилетело и опубликовало эту надпись здесь
Наверное, правильнее сказать — не злоупотребление ООП, а злоупотребление объектами. ООП подразумевает инкапсуляцию логики, а не бездумные обертки с геттерами-сеттерами. Я бы сказал, что без SOLID ООП — это не ООП.

ООП — это не когда вместо $var['foo'] пишется $var->foo или $var->getFoo(). ООП — это когда пишется $this->foo.
Использование массивов само по себе ни хорошо, ни плохо. Плохо (в большинстве случаев) в настоящее время использовать в PHP массивы в качестве сишных структур, в качестве коллекций семантически разнотипных значений, особенно с ключами представляющими собой человеческие имена типа 'first_name' или 'contracts' — для этого есть объекты. А вот использовать массивы как коллекции однотипных значений с ключами в виде числовых индексов или идентификаторов объектов — хорошо.
А чем описанное в статье использование PHP-массивов принципиально отличается от JSON, который сейчас, вроде как, везде принято любить? По-моему, это абсолютно то же самое, этот код можно даже вынести в отдельный файл (с расширением .phpon?) или хранить в БД, «декодируя» вызовом функции eval. Поэтому, думаю, определённая легитимная область применения у этого подхода есть, частично совпадающая с областью применения JSON/YAML/XML.
eval зло, взломал базу->дописал shell->зашёл на сервер-> и понеслась
Само собой, зло — потому и кавычки. Но концептуально «PHP Object Notation» (или «PHP Array Notation»?) ничем не хуже JSON, кроме отсутствия аналога функции json_decode.
плохо — анемичная модель, плохо — отсутствие инкапсуляции и глобальное состояние. А все остальное — детали.
«Анемичная» модель в виде массива в качестве сущности бизнес-логики, наверное, совсем не айс, но в качестве DTO — почему нет? DTO не особенно нужна инкапсуляция, а хранить массив таких объектов в глобальной переменной никто не заставляет.
Кстати, в Python есть такая вещь, как collections.namedtuple, которая очень подходит для сущностей сложнее кортежа, но недостаточно сложных для написания отдельного рукотворного класса. Уверен, что в насквозь динамическом PHP можно сделать аналог (или он уже существует).
но в качестве DTO — почему нет?

Для DTO массивы — ок, во всяком случае в простых случаях, коих большинство. Но это никоем образом не относится к тому, о чем так печется Матиас (автор статьи, тут перевод если что) когда говорит обо всем этом — модель предметной области.
но недостаточно сложных для написания отдельного рукотворного класса.

Обычно все же эту штуку используют в качестве базового класса. Ну то есть для большинства случаев объявление нашей структуры сводится к одной вполне себе читабельной строчки, но если что — можно поведение добавлять и т.д. В PHP к сожалению таких механизмов нет.
Уверен, что в насквозь динамическом PHP можно сделать аналог (или он уже существует).

PHP то насквозь динамический, но не настолько к сожалению. Тут поможет только кодогенерация в рантайме. Всему виной различия в объектной модели php и python, у php оно более статично, в силу исторических причин и потому что слизано у java/.net.
Во всяком случае я искал в свое время и не нашел, и понял что объявить простые структурки и сгенерировать конструктор как-то выходит быстрее и проще.
p.s. вообще ооочень много вопросов и споров в этой статье свелись бы на нет, если бы автор перевода предоставил информацию о том, кто такой Матиас, с каким проектами он работает и т.д. Ибо заметки в его личном блоге обычно читают люди, кто вкурсе, что он обычно вещает о том как правильно проектировать предметную область, прославляет DDD и тд. А что у вас между контроллерами и моделью ходит в качестве DTO — массивчики динамические, статические структурки или тупые объекты без поведения — это уже вам решать.
НЛО прилетело и опубликовало эту надпись здесь
Эх поздно я вашу заметку увидел. Не дает мне Хабр ее плюсануть уже.
Солидарен на 100%. Тоже всегда вызывает недоумение.
Самое интересное, что ассоциативные контейнеры есть ведь во многих языках. Но только в php придумали использовать их вместо объектов. И не просто придумали, это стало просто эпидемией какой-то. Пандемия.
да ладно вам, в javascript сообществе с этим похуже как-то пока. Но ребята растут, развиваются. А у PHP-ников пока отсутствует понятие "состояни" и "побочные эффекты".
Придумали в то время, когда ещё объектов не было. И натолкнули на мысль авторы языка прежде всего, предоставляя окружение и запрос в виде суперглобальных ассоциативных массивов. Хочешь написать hello $name — используй массив.
НЛО прилетело и опубликовало эту надпись здесь
А поведение где? Как вы будете спасаться от сайд эффектов? Из вашего описания получается какая-то процедурщина.
Вообще есть хорошее правило — не стоит быть столь категоричными. Для каждой ситуации свой подход.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории