• Как сложить сумму элементов с одинаковой датой?

    Maksclub
    @Maksclub Куратор тега PHP
    maksfedorov.ru
    <?php
    
    $json = <<<JSON
    {
      "issuance": {
        "1": {
          "data": "01.20",
          "quantity": 2
        },
        "2": {
          "data": "01.20",
          "quantity": 4
        },
        "3": {
          "data": "04.20",
          "quantity": 2
        },
        "4": {
          "data": "04.20",
          "quantity": 2
        }
       }
    }
    JSON
    ;
    
    $arr = json_decode($json, true, 512, JSON_THROW_ON_ERROR);
    
    $res = new \stdClass();
    $res->issuance = array_values(
        array_reduce(
            $arr['issuance'],
           function ($res, $el) {
                $res[$el['data']]['data'] = $el['data'];
                $res[$el['data']]['quantity'] = isset($res[$el['data']]['quantity'])
                    ? $res[$el['data']]['quantity'] + $el['quantity']
                    : $el['quantity'];
    
                return $res;
            },
            []
        )
    );
    
    var_dump(json_encode($res, JSON_THROW_ON_ERROR | JSON_PRETTY_PRINT, 512));

    sandbox.onlinephpfunctions.com/code/c5986c6fd8244a...

    * JSON_THROW_ON_ERROR — этот флаг появился только в 7.3, если версия меньше — убрать
    Ответ написан
    Комментировать
  • Как правильно вести переговоры с руководством при продлении контракта?

    Maksclub
    @Maksclub Куратор тега Карьера в IT
    maksfedorov.ru
    Как правильно вести переговоры с руководством и поднять себе цену?

    Сергей Горностаев написал отличный совет: Какие стратегии повышения зарплаты существуют?
    Ответ написан
    Комментировать
  • Сервис по запоминанию паролей к сайтам?

    Maksclub
    @Maksclub Куратор тега Веб-разработка
    maksfedorov.ru
    Ответ написан
    Комментировать
  • Как использовать Jms Serializer с Doctrine с настройкой Lazy?

    Maksclub
    @Maksclub
    maksfedorov.ru
    Аннотация @Accessor

    /** @Accessor(getter="getName") */
    private $name;
    
    public function getName()
    {
         return $this->name;
    }

    При вызове указанного геттера произойдет вызов и запрос. Соответственно lazy вернет результат.

    Если yaml, то в той же доке указано как задать аксессор.
    Не забудьте почистить кеш (не всегда чистится консольной командой, удалите папку jms - когда с 3й работал, то были такие глюки) .


    А вообще, если пишите с нуля, то знайте — от JMS Serializer все уходят в сторону Symfony Serializer
    В контейнере уже должен быть у вас сервис @serializer сразу после установки компонента и можно просто заинжектить через SerializerInterface в конструкторе
    Ответ написан
    5 комментариев
  • Как реализовать облачное хранилище?

    Maksclub
    @Maksclub Куратор тега PHP
    maksfedorov.ru
    Для облачного хранилищ нужно облако (логично, судя по названию)
    Потому нужно создать это самое облако -- начните с OpenStack (на вики)
    PHP SDK: https://github.com/php-opencloud/openstack

    Посмотрите в сторону Swift (на вики)из OpenStack
    https://www.openstack.org/software/releases/train/...

    не работал с данным стеком
    Ответ написан
    Комментировать
  • Как в spring вернуть лист объектов?

    Maksclub
    @Maksclub
    maksfedorov.ru
    @Repository
    class ShipRepository {
     
        @PersistenceContext
        private EntityManager entityManager;
     
        @Override
        public List<Ship> findLimitedTo(int limit) {
            return entityManager.createQuery("SELECT s FROM Ship s ORDER BY s.id",
              Ship.class).setMaxResults(limit).getResultList();
        }
    }
    Ответ написан
    1 комментарий
  • Как при выполнении Carbon->addDays(int) не обновлять состояние?

    Maksclub
    @Maksclub Куратор тега PHP
    maksfedorov.ru
    We also provide CarbonImmutable class extending DateTimeImmutable. The same methods are available on both classes but when you use a modifier on a Carbon instance, it modifies and returns the same instance, when you use it on CarbonImmutable, it returns a new instances with the new value.

    https://carbon.nesbot.com/docs/


    CarbonImmutable при изменении данных создает новый обьект, не меняя старый. Так как работает на основе DateTimeImmutable:
    https://www.php.net/manual/ru/class.datetimeimmuta...
    Ответ написан
    1 комментарий
  • В Rust стрелочка -> в объявлении функции foo()->i32{ для красоты?

    Maksclub
    @Maksclub
    maksfedorov.ru
    носит чисто декоративный характер или как то помогает парсеру?

    Скорее лексеру обнаружить нужные токены/лексемы

    В данном докладе язык PHP, но не пугайся! Кирилл Несмеянов очень наглядно и доступно показал как в целом устроены парсеры и лексеры некого абстрактного языка:
    https://youtu.be/zZTv7HMxKXI?t=16074
    Ответ написан
  • Как добавить в ассоциативный массив значение attributes() эллемента xml?

    Maksclub
    @Maksclub Куратор тега PHP
    maksfedorov.ru
    Когда вы превращает документа в SimpleXMLElement, то каждая дочернаяя нода тоже таковой становится и у нее также есть свой набор атрибуттов $element->attributes()
    Итоговый код

    <?php
    
    $string = <<<XML
    <offer id="130" available="true" >
    <url>http://api.loc/index.php?route=product/product&amp;path=3899&amp;product_id=130</url>
    <price>850</price>
    <currencyId>UAH</currencyId>
    <categoryId>3899</categoryId>
    <delivery>true</delivery>
    <stock_quantity>100</stock_quantity>
    <name>Босоножки 82BLUE р. 27 17,5 см Синий</name>
    <vendor>(производитель не указан)</vendor>
    <barcode>200</barcode>
    <param name="Размер обуви">46</param>
    <param name="Размер стельки">19</param>
    </offer>
    XML
    ;
    
    $xml = new SimpleXMLElement($string);
    
    $params = [];
    // Все ноды с тегом param ушли в массив, каждый из из которых  SimpleXMLElement
    foreach($xml->param as $param) {
        // а также @attributes, в котором все атрибуты текущего элемента, достаем тот, что name
        $paramName = $param->attributes()['name'];
        $params[(string) $paramName] = (string) $param;
    }
    
    var_dump($params);
    // [
    //     "Размер обуви"   => string(2) "46"
    //     "Размер стельки" => string(2) "19
    // ]


    UPD: Чтобы руками все не писать и не гадать, какой параметр пришел каким по счету (а могут прийти в одной выгрузке в разном порядке из-за того, что у одного товара просто не указан один из параметров, то предлагаю сделать так:

    1. Завести карту всех соответствий
    $featuresMap = [
        'Размер обуви' => 'size',
        'Размер стельки' => 'stelka',
    ];

    2. И уже динамически собирать с каждого элемента по этой карте параметры
    foreach($xml->param as $param) {
        $paramName = $param->attributes()['name'];
        $paramAlias = $featuresMap[(string) $paramName]
        $params[$paramAlias] = (string) $param;
    }


    И тогда вам нужно будет только расширять свою карту соответствий, а код цикла всегда будет оставаться одним и тем же. Ну добавив пару проверок и например транслитерировать новые значения, добавляя их в БД, и карту уже брать из той же БД.
    Ответ написан
  • Как в типизированных свойствах задать массив типа?

    Maksclub
    @Maksclub Куратор тега PHP
    maksfedorov.ru
    Дженерики еще не подвезли, которые бы сделали это возможным
    Используйте коллекции (из Симфони или Ларавел возьмите), если хотите, чтобы был некий контроль за типом, но и они, опять же, не будут полноценно контролировать тип элемента сами по себе.

    class Bar
    {
        /** @var ArrayCollection|Bar[] */
        public ArrayCollection $props;
    }


    Для решения вашей задачи нужен еще один виток развития языка :)

    НЕсуществующий код!
    class ArrayCollection<T>
    {
        public getElement(): <T>;
        public addElement(<T> $element): void;
    }
    
    class Bar
    {
        public ArrayCollection<Bar> $barCollection;
    }


    Единственное, можно свои коллекции прокачать на проверку типа при создании объекта этой коллекции
    Ответ написан
    Комментировать
  • Что за Undefined offset?

    Maksclub
    @Maksclub Куратор тега PHP
    maksfedorov.ru
    У вас дампится все отлично — если увидите, на скрине вверху есть слово login
    Очевидно код срабатывает еще раз, там где нет метода и крашится, тк в новый раз этих данных нет...

    Чтобы это узнать, перед получением $s сделайте:
    dd(get_class($event->getController()));
    И покажите полный вывод ВСЕХ значений...

    Вообще потратьте время и поставьте xDebug, вы бы все поняли в течение 2 секунд что и куда прилетает и почему...

    Если выбрали дебаг как раньше на коленке, то у симфы есть функция dump(), все вызовы которой выводятся в панеле разработчика!
    Ответ написан
  • Как спарсить этот JSON?

    Maksclub
    @Maksclub Куратор тега PHP
    maksfedorov.ru
    <?php
    
    $jsonProducts = '[
      {
        "market_name": "T-shirts",
        "size": "M"
      },
      {
        "market_name": "T-shirts",
        "size": "L"
      }, 
      {
        "market_name": "Jacket",
        "size": "M"
      }, 
      {
        "market_name": "Jeans",
        "size": "XL"
      }
    ]';
    
    $jsonPrice = '{
        "data": [
            {
              "updated_at": 1576048969000,
              "prices": {
                "last": 5300
              },
              "name": "Jacket"
            },
            {
              "updated_at": 1576048969000,
              "prices": {
                "last": 2000.12
              },
              "name": "T-shirts"
            }
        ]
    }';
    
    $products = json_decode($jsonProducts, true);
    $price = array_column(json_decode($jsonPrice, true)['data'], 'prices', 'name');
    
    $result = array_map(function($item) use ($price) {
        $product              = new \stdClass();
        $product->market_name = $item['market_name'];
        $product->size        = $item['size'];
        $product->price       = $price[$item['market_name']]['last'] ?? null;
        
        return $product;
    }, $products);
    
    $result = json_encode($result, JSON_PRETTY_PRINT);
    
    var_dump($result);
    // [
    //     {
    //         "market_name": "T-shirts",
    //         "size": "M",
    //         "price": 2000.12
    //     },
    //     {
    //         "market_name": "T-shirts",
    //         "size": "L",
    //         "price": 2000.12
    //     },
    //     {
    //         "market_name": "Jacket",
    //         "size": "M",
    //         "price": 5300
    //     },
    //     {
    //         "market_name": "Jeans",
    //         "size": "XL",
    //         "price": null
    //     }
    // ]


    sandbox.onlinephpfunctions.com/code/935656788a07af...
    Ответ написан
  • DI: как инстанциировать реализацию интерфейса с кастомным значением параметра конструктора?

    Maksclub
    @Maksclub Куратор тега PHP
    maksfedorov.ru
    Используйте фабрику:

    - В конфиге контейнера
    // регайте ваш интерфейс, но ссылаясь на метод фабрики,
    // которая и произведет ваш сервис
    \App\Writer\WriterInterface::class => DI\factory('\App\Writer\TextWriterFactory::create'),

    - Код фабрики:
    class TextWriterFactory implements WriterFactoryInterface
    {
        public function __construct(Settings $settings, DataConverter $dataConverter)
        {
            $this->settings = $settings;
            $this->dataConverter = $dataConverter;
        }
    
        public function create(string $filePath): WriterInterface
        {
            return new TextWriter($this->settings, $this->dataConverter, $filePath);
        }
    }


    Источник: php-di.org/doc/php-definitions.html#factories
    Ответ написан
  • Как переписать preg_replace_callback()?

    Maksclub
    @Maksclub Куратор тега PHP
    maksfedorov.ru
    Callback можно задавать как
    Как массив объекта и его метода: [$obj, 'myCallbackMethod']
    Для статического метода: [MyClass::class, 'myCallbackMethod']
    Другой способ для статического метода: 'MyClass::myCallbackMethod'

    Пример для вас:
    <?php
    
    class TestListener
    {
      //   сигнатуру тут лишнюю для простоты примера просто убрал
      public function onContentPrepare(&$row) {
    
        $row->text = preg_replace_callback('|{gold}|', [$this, 'insertgold'], $row->text);
      } 
    
      public function insertgold(array $matches)
      {
          return $matches[0] . 'Called';
      }
    }
    
    
    // Example
    $string = new stdClass();
    $string->text = 'TestText with gold  and gold ';
    
    $listener = new TestListener();
    $listener->onContentPrepare($string); 
    var_dump($string->text ); //TestText with goldCalled  and goldCalled
    Ответ написан
  • Чем представлена абстракция (принцип ООП) в Java?

    Maksclub
    @Maksclub
    maksfedorov.ru
    Абстракция — ключевое явление в ООП

    Сам класс — уже абстракция чего-то, когда я создаю класс Product, то это абстракция некоторых объектов моей системы, что их отличает от всего внутреннего мира системы уже как минимум названием (и потом интерфейсом и поведением, описанным в классе).

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

    Также мы можем абстрагировать некий функционал от привязки к конкретному типу. И создать функционал над абстрактным (обобщенным) типом — дженерики (параметрический полиморфзм).

    Наследование, инкапсуляция и полиморфизм — ключевые способы для создания абстракции.
    • Полимофризм — создаем или интерфейс или абстрактный класс, что очертит границы абстракции и уже в конкретных реализациях абстракцию "материализуем". Или создаем некий класс, который работает с любым типом, но строго указанным при создании объекта (параметрический полиморфизм)
    • Наследование — похожее поведение у ряда классов выносим в абстракцию (родительский класс, абстрактный класс)
    • Инкапсуляция — очищаем абстракцию, отдав наружу только публичный интерфйес (границы абстракции), все остальное (не относящиеся к нашей абстракции) прячем
    Ответ написан
    Комментировать
  • Как разрулить конфликт зависимостей composer?

    Maksclub
    @Maksclub Куратор тега PHP
    maksfedorov.ru
    Если под 3 версию не хватает адаптеров, то нужно:
    • либо доработать адаптеры под 3-ю версию и внести в клад в опенсорс,
    • либо сделать форк 2 версии для самой библиотеки и для common, адаптировать common (форк) под работу с symfony/http-foundation 4 версии, выложить на Packagist и затянуть к себе уже свой форк


    Приходилось как-то пару раз мутыжиться со вторым способом... гемморно, но нужно было
    Может так статься, что адаптер форкнуть будет проще
    Ответ написан
    9 комментариев
  • Что является связующим звеном между backend и frontend?

    Maksclub
    @Maksclub
    maksfedorov.ru
    Связующее звено — веб-сервер

    Как правило это Nginx, но может быть и голый сервер на том языке, на котором сделан бекенд.
    Работает по принципу запрос-ответ. Например сделал запрос через GET/POST, не важно — через AJAX (JS) или напрямую, запрос попадает на бекенд и обрабатывается, летит ответ и вы с ним работаете.

    Также браузеры поддерживают протокол вебсокет.
    Ответ написан
    23 комментария
  • Как решить проблему с set(), get()?

    Maksclub
    @Maksclub
    maksfedorov.ru
    Вывести откуда? Если из бд, то посмотрите в сторону active record и data mapper (repository) — лучше последний. Есть уже готовые интерфейсы: JPA

    Сеттеры и геттеры переменных вам ничем не помогут, тк дают доступ к свойствам вашей бизнес-сущности (и вообще делают его структурой) , а вот как они заполнятся — дело не данного обьекта (кроме Active Record паттерна), ровно как и вывод коллекции этих объектов, и точно не сортировкой заниматься.
    Ответ написан
    Комментировать
  • Как асинхронно выполнить скирпт php?

    Maksclub
    @Maksclub Куратор тега PHP
    maksfedorov.ru
    Возьмите любой асинхронный фреймворк на php:
    RoadRunner
    ReactPHP

    С помощью него запускайте свой воркер
    И результат через веб-сокет отдавайте на клиент
    Ответ написан
    Комментировать
  • Почему PHP требует Apache или Nginx чтобы работать в docker контейнере?

    Maksclub
    @Maksclub Куратор тега PHP
    maksfedorov.ru
    какой смысл использовать Apachе или Nginx содержащий образ? Разве нельзя работать с контейнером содержащим только php?

    Разве нельзя работать с контейнером содержащим только php?

    Можете. Вы можете поставить PHP-CLI контейнер и работать с ним без веб-сервера конечно же
    FROM php:7.1-cli
    Что позволит вам запускать консольные команды (композер туда же)

    Если ставите PHP-FPM контейнер, то понятное дело вам нужен веб-сервер (гуглите принцип работы с Fast CGI).
    Нужен, если вы хотите общаться с приложением через HTTP
    FROM php:7.1-fpm
    Ответ написан
    1 комментарий