• Какой программой воспользоваться что-бы найти момент изменения кадра в видео файле на 48 часов?

    Moskus
    @Moskus
    Запустить VLC из командной строки, скормив ему нужный файл и добавив опции --video-filter=motiondetect для включения фильтра детектора движения, по вкусу - --rate= для скорости воспроизведения, ну и -vv >logfile.txt - для вывода сообщений в текстовый лог, который потом предстоит изучить.
    Ответ написан
    5 комментариев
  • Как не нарушать SOLID?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    вы путаете инверсию контроля и инверсию зависимости. Давайте по порядку кратенько.

    Зачем нам нужны контроллеры или различные представления данных

    Зачем нам в принципе контроллер? Что он делает? Для упрощения не будет воспринимать контроллер как "один объект" и вместо этого представим себе его как целый слой. Так же заменим слово "модель" словом "приложение".

    Задача контроллера - принять и обработать запрос и выдать ответ. По сути в контексте WEB наш HTTP запрос и ответ это представление, которое хочет получить клиент (браузер, мобильное приложение, SPA, что угодно). HTTP - это интерфейс пользователя (UI) для нашего web-приложения.

    Например что бы независеть от реализации клиента и что бы было удобно мы передаем даты в формате iso 8601 (пример: 2016-07-14T19:40:12Z). Это удобно что бы быть независимым от реализации клиента или сервера. Но это не удобно для нашего приложения. В приложении скорее всего нам удобнее всего работать с объектом типа DateTime. То есть приложение использует абсолютно другое представление.

    Мы могли бы прямо в приложении конвертить DateTime в iso 8601 но тогда мы делаем наше приложение привязанным к одному конкретному представлению, которое хочет получить клиент. К примеру по каким-нибудь причинам известным только темным богам, вам вдруг понадобится быстро прикрутить интеграцию с другим сервисом и те же данные гонять уже в RFC2822. И стало быть уже приложению нужно париться о еще одном представлении.

    Мы могли бы сделать какие-то адаптеры у приложения, и дергать их в зависимости от потребностей, но тогда опять же наше приложение все еще знает о представлении, которое ему собственно не нужно. То есть у нас есть зависимость приложения от его UI что... похоже на "не лучшую идею". И тут на помощь приходит Inversion of Control.

    Что такое Inversion of Control

    Тут название само говорит за себя. Допустим у нас был объект A который дергал объект B, причем объект A по сути и не должен ничего знать об объекте B потому то это не его дело. Принцип инверсии контроля говорит нам о том, что в таких ситуациях именно B должно вызывать A, таким образом меняя направление потока управления. Это позволяет нам уменьшить связанность и повысить зацепление компонентов нашей системы. Так же сделав это у нас может появиться объект C который так же будет дергать объект A. Если говорить о UI - мы просто можем сделать несколько реализаций UI.

    То есть если еще упростить - фреймворк должен дергать ваш код, а не код дергать код фреймворка. Тем самым мы снижаем связанность одного от другого.

    Роутер и контроллеры как реализация UI

    Что бы отвязать приложение от логики формирования представления, вынесем это все в отдельный "слой" и назовем этот слой - контроллеры. Точнее это будет как цепочка адаптеров. Один адаптер (фронт-контроллер по сути) получает Request и делает какие-нибудь вещи с ним. Например проверяет можем ли мы вообще делать подобный запрос. Другой адаптер вызывает роутер и выясняет какой дальше адаптер вызвать. Если следующий адаптер не вызван - надо вернуть 404-ую ошибку. Если же все пошло хорошо - мы вызываем еще один адаптер, который уже будет конвертировать HTTP запрос в какое-то действие приложения (вызов метода приложения по сути).

    Так а инверсия зависимости это что?

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

    Dependency_inversion.png

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

    Если мы не хотим завязываться на SwiftMailer, и дать возможность в будущем изменить способ отправки почты, мы можем в рамках нашего модуля объявить интерфейс а в другом модуле уже его реализовать с применением SwiftMailer. Для упрощение под модулями мы можем понимать неймспейсы например.

    Нужно ли соблюдать принцип инверсии зависимости в случае контроллеров?

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

    будет ли правильным передавать зависимости в роутинге

    Это уже вопрос реализации IoC. Конкретно вы хотите получить что-то вроде Dependency Injection. Вы можете забрать зависимости из аргументов метода экшена. или аргументов конструктора контроллера.... или просто использовать контейнер зависимостей внутри контроллера.... это совершенно не важно. Контроллеры это то место где высокая связанность на компоненты фреймворка более чем допустимы.

    С другой стороны у вас теперь роутинг совмещает обязанность маршрутизации и разруливания зависимостей. Сами понимаете что это как-то нарушает прицип единой ответственности. Этим может заниматься Controller Resolver какой-нибудь.
    Ответ написан
    2 комментария
  • Что такое "отказ от двустороннего датабиндинга"?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    есть датабиндинг, observable отношение между одним компонентом и другим. Например:

    var model = {
        title: 'Some Title'
    };
    
    function view(container) {
        var el = container.querySelector('[data-bind="title"]');
        // следим за изменениями
        Object.observe(model, (changes) => {
            if ('title' === changes.name) {
                // обновляем при изменении связанное значение у другого компонента
                el.innerHtml = model.title;
            }
        }, ['update'])
    }


    В этом случае если каким-то чудом наш элемент вдруг поменяет содержимое (ну а вдруг?) то значение внутри модели не поменяется, оно не зависит от другого компонента.

    В случае же с двусторонним датабиндингом изменения происходят с двух сторон. Грубо говоря с двух сторон стоят обзерверы которые меняют значения. И это говорит нам о том что изменения, поток данных, идут в обе стороны, потому этот вид биндингов называется двусторонним.

    Сами по себе биндинги это круто, и это то что делает современные фреймворки такими крутыми - позволяют реагировать на изменение данных и обновлять к примеру view приложения, без необходимости писать огромные куски кода отслеживающие изменения - все за нас делает фреймворк.

    Проблема с двусторонним дата биндингом очень простая - систему построенную с активным применением двустороннего биндинга крайне тежело отлаживать. Приведу простой пример. Предположим что у нас есть компонент A и компонент B. У компонента A есть свойство foo которое содержит какую-то строку, компонент B содержит свойство bar и у нас установлено двустороннее связывание между этими двумя свойствами.

    Фреймворк гарантирует нам то, что если одно из этих полей поменяется, он поменяет другое, так что A.foo всегда будет равно B.bar. Вот только это создает такую проблему, теперь оба компонента должны учитывать что значение foo и bar могут поменяться в любой момент, и не понятно кто инициировал изменения. Спокойно можно войти в состояние когда A меняет состояние, B синхронизируется и реагирует и снова меняет состояние, тогда реагирует A, и может быть появляется какие-то другие связанные компоненты. То есть мы можем быстро и просто схватить рекурсию. Если у вас на этой основе построена бизнес логика - то вам будет крайне сложно потом поддерживать эту систему, дебажить ее ад.

    Грубо говоря помимо того что дебажить эту систему становится тяжело, у нас появляется неявная зависимость между A и B, им нужно знать что они могут поменять друг дружку. А все неявное это не очень хорошо.

    Что можно сделать, можно разложить двустороннюю связь на составляющие. Односторонний биндинг из A в B и навесить ивенты если один из компонентов что-то меняет. В этом случае вы всегда можете поставить бряку и точно будете знать кто что поменял. Поддерживать такую систему куда проще.
    Ответ написан
    7 комментариев
  • Как вызвать метод класса, из другого класса, не создавая при этом экземпляра класса?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    Для начала задумайтесь, а зачем вы наследуете все от lk_core? Почитайте про принцип единой ответственности.

    Логично передавать экземпляр класса lk_bans если он у вас отвечает за логику банов в конструктор класса, который его хочет использовать (принцип инверсии зависимостей). И да, опять же. Читаем принцип подстановки барбары Лисков. Родительский класс (lk_core) ничего не должен знать о своих потомках. Вообще ничего.

    Вообще на начальных этапах старайтесь избегать наследования. Вот вообще. И почитайте про SOLID и GRASP. Сразу кучу вопросов для себя покроете.

    Есть подборка того, что должен посмотреть каждый по-ха-пэшник. Там есть и про SOLID и про GRASP и зачем это все надо.
    Ответ написан
    Комментировать
  • Сокрытие расширения PHP файлов?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Этот дебильный раздел давно надо бы убрать из документации.
    Потому что никакая защищенность от этого не повышается.

    Не говоря уже о том, что уже много-много лет стандартом де-факто является адресация через ЧПУ, при которой никаких .php файлов в любом случаеснаружи не видно.
    Ответ написан
    4 комментария
  • Register_globals как быть с ним в php 5?

    shublog.ru/php/pochemu-opasno-vklyuchat-parametr-p...

    Если в учебнике требуют включить register_globals, лучше от него бежать как можно дальше и быстрее :)
    Ответ написан
    2 комментария
  • Где скачать книгу "Разработка Backbone.js приложений"?

    iusfof
    @iusfof
    Front-end developer
    в вк в документах есть дофига книг, в том числе та, которую вы ищите
    Ответ написан
    Комментировать
  • Как определить узкое на сервере?

    DmitriyEntelis
    @DmitriyEntelis
    Думаю за деньги
    Раскидайте по коду таймеры, далее по вкусу - можно их писать куда нибудь, можно просто паралельно с тестом рукам открыть код и посмотреть результаты.
    По крайней мере будет понятно где тормозит. Сейчас явных для решения явно не достаточно.

    Гипотетически (версия из головы) может например быть какой то кривой кеш, который захлебывается, постоянно перегенерится - вот и загрузка 100%

    upd еще гипотетическая версия - у вас например есть какие то тяжелые транзакции которые мешают разным потокам скрипта.
    Ответ написан
    2 комментария
  • Как определить узкое на сервере?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    www.xdebug.org/docs/profiler - использовать только для тестов, в продакшене стоит отключить.

    Есть подозрения что у вас какая-то беда с ресолвингом DNS серверов с memcache и/или базой данных. Проверьте может?
    Ответ написан
    8 комментариев
  • Как правильно настроить несколько проектов с одинаковым доменным-именем но разными "суффиксами" (nginx)?

    Wendor
    @Wendor
    nodejs developer / *nix admin
    Вот смотрите, например у вас в exmple.com/project1/main.css есть ссылка на картинку /bla/bla/bla.jpg. Это значит что у вас ссылка exmple.com/bla/bla/bla.jpg. Nginx никак не определит, к какому проекту ее отнести. Так что, поставленную задачу средствами nginx не реализовать. Для решения проблемы, можно использовать только относительные ссылки вида bla/bla/bla.jpg.
    Либо можно добавлять к ссылкам какой-нибудь get параметр /bla/bla/bla.jpg?project=project1, а в nginx'е при обнаружении параметра делать root /project1, но это тот еще геморрой.

    Если же вы хотите чтобы nginx переписывал ссылки перед тем как отдать страницу клиенту (чтобы /bla/bla/bla.jpg заменял на /project1/bla/bla/bla.jpg) , то об этом тоже можно забыть. Нужно будет обучить веб-сервер ccs'у, js'у и html'у... разбираться в коде страниц и автоматом заменять. Это практически нереально.

    upd: Безумная мысль... при запросе, nginx'ом парсить строку referer на предмет ^/project1, и в случае успеха дописывать делать реврайт на этот самый project1 :-)
    Ответ написан
    1 комментарий