• Как вытянуть оригинал картинки с сервера. (Авито и прочие)?

    alexey-m-ukolov
    @alexey-m-ukolov Куратор тега Веб-разработка
    Очевидно, что ссылки на картинки где-то есть или их адреса можно составить по предсказуемой схеме, чем сайт-сервис и пользуется, проведя исследование.
    Как выдернуть - найти ссылки или понять схему. Для этого нужно использовать консоль/код/сурс, разумеется, но ещё и голову. Научить этому в рамках общего вопроса здесь невозможно, а конкретный вопрос будет заданием.
    Ответ написан
    2 комментария
  • Как можно сделать такой живой дым на сайте css и js?

    Get-Web
    @Get-Web Куратор тега CSS
    Front-End Developer
    Можно спрайтами, у меня дыма готового нет, но есть свеча для примера:
    Ответ написан
    5 комментариев
  • Почему Service Locator это зло и что использовать вместо?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Все эти страшные слова - они на самом деле всегда про одно и то же - про связность. Когда ты хардкодишь внутри класса вызов какого-то конкретного сервиса - ты намертво к нему привязываешься. И чтобы поменять сервис на другой, ты будешь вынужден поменять код класса. Окей, поменял. И тут же в другом месте, где этот же класс использовался, что-то сломалось! И что теперь? Делать два класса, которые различаются одной строчкой? Нет конечно. А как тогда использовать один и тот же класс для обработки разных входящих данных (или одних и тех же данных, но разными способами)? Сделать его поведение изменяемым. То есть сделать изменяемыми те инструменты, которыми он пользуется - т.е. его зависимости.

    Поэтому все зависимости обычно передаются через конструктор (и поэтому и называются инъекция зависимостей.)

    Таким образом мы можем менять поведение класса, не меняя его код

    Но тут надо понимать, что всё это работает только при правильном применении ООП. А точнее просто при применении ООП. Потому что 98% "ООП" кода, который пишется на РНР - это голимая процедурщина, даже если она обёрнута в классы и методы. Если у тебя метод класса представляет из себя стену кода, которую ты тупо перенёс из файла, инклюдившегося в любимое похапешное спагетти - то это не ООП. Это та же процедурщина, вид сбоку. И смысл использования dependency injection ты с ним не почуствуешь. Будешь конечно применять, но в качестве карго культа - потому что тебе это на тостере написали.
    А вот когда твой код начнет становиться действительно объектным - тогда стразу станет понятнее.


    Похожим на сервис локатор является сервис- или DI-контейнер. Используемый вручную, он является тем же самым сервис локатором. Поэтому вручную его никогда не надо вызывать - что и запрещается в симфоневских конроллерах - а только для автоматического создания классов. В МВЦ у тебя ведь очень многие объекты создаются автоматом - сущности, контроллеры. И вот для того, чтобы при автоматическом создании экземпляра класса у тебя были на руках все требуемые сервисы - и нужен контейнер.

    Соотвтственно, ответ на вопрос "что использовать?" очень простой:
    - при ручном создании экземпляра объекта, все зависимости передавать в него через конструктор, а не получать "из воздуха" в коде.
    - при автоматическом создании экземпляра объекта, использовать dependency injection container

    В этим смысле очень полезно освоить Симфони - строгий фрейворк, в котором нет сервис локатора и в котором запрещено пользоваться контейнером напрямую.
    Ответ написан
    4 комментария
  • Почему отрубается asterisk?

    ioangrozniy
    @ioangrozniy Автор вопроса
    После долгих мытарств поставил Астер 16.10.0
    Всё заработало. Так что как я понял - это косяки версии 17.3.0
    Очень жаль.
    Ответ написан
    Комментировать
  • Как реализовать алгоритм группировки массива по значению?

    Eridani
    @Eridani
    Мимо проходил
    Если по замыслу Владимир Проскурин
    $openingHours = [
                ['day' => 'monday', 'time' => '08:00-20:00'],
                ['day' => 'tuesday', 'time' => '08:00-20:00'],
                ['day' => 'wednesday', 'time' => '08:00-20:00'],
                ['day' => 'thursday', 'time' => '10:00-20:00'],
                ['day' => 'friday', 'time' => '10:00-18:00'],
                ['day' => 'saturday', 'time' => '10:00-16:00'],
                ['day' => 'sunday', 'time' => '10:00-16:00'],
            ];
    $temp = array();
    $result = array();
    
    foreach($openingHours as $key => $item) {
      $temp[$item['time']][] = $item['day']; 
    }
    foreach($temp as $key => $item){
      $count = count($item) -1;
      $count >= 1 ? $result[$item[0].'-'.$item[$count]] = $key : $result[$item[0]] = $key; 
    }
    print_r($result);


    Array
    (
        [monday-wednesday] => 08:00-20:00
        [thursday] => 10:00-20:00
        [friday] => 10:00-18:00
        [saturday-sunday] => 10:00-16:00
    )


    P.S. На другие реализации или упрощение вышеописанного и сам с удовольствием посмотрю
    Ответ написан
    1 комментарий
  • Как реализовать алгоритм группировки массива по значению?

    GomelHawk
    @GomelHawk
    PHP / Symfony developer
    Если предположить, что дни недели упорядочены по возрастанию, то можно использовать что-нибудь такое:

    $openingHours = [
        ['day' => 'monday', 'time' => '08:00-20:00'],
        ['day' => 'tuesday', 'time' => '08:00-20:00'],
        ['day' => 'wednesday', 'time' => '08:00-23:59'],
        ['day' => 'thursday', 'time' => '08:00-20:00'],
        ['day' => 'friday', 'time' => '08:00-20:00'],
        ['day' => 'saturday', 'time' => '10:00-16:00'],
        ['day' => 'sunday', 'time' => '10:00-16:00'],
    ];
    
    $result = $active = [];
    
    $openingHours[] = ['day' => '', 'time' => '']; // empty value to simplify code
    
    foreach ($openingHours as $openingHour) {
        if ($active) {
            if ($active['time'] === $openingHour['time']) {
                $active['end'] = $openingHour['day'];
            } else {
                $key          = $active['end'] ? $active['start'] . '-' . $active['end'] : $active['start'];
                $result[$key] = $active['time'];
                $active       = [];
            }
        }
        $active = $active ?: [
            'time'  => $openingHour['time'],
            'start' => $openingHour['day'],
            'end'   => null,
        ];
    }
    
    print_r($result);
    Ответ написан
    1 комментарий
  • Как реализовать алгоритм группировки массива по значению?

    Vlad_IT
    @Vlad_IT
    Front-end разработчик
    Решение в лоб: создаете ассоциативный массив, где ключ - время, значение - массив дней недели. И просто проходите каждый элемент $openingHours, берете с него время, проверяете, есть ли оно в нашем созданном массиве, если нет, создаем и добавляем туда день, если есть, то просто добавляем туда день.
    Ну, потом уже пишите функцию, которая преобразует наш созданный массив в тот, что вам нужно. Это тоже довольно просто, смотрим ключ, берем его значения, соединяем их через разделитель -, и используем как ключ в новом массиве.
    Ответ написан
    1 комментарий
  • И снова this в javascript?

    @BlackSSA Автор вопроса
    Ребята, всем-всем огромное спасибо! По-моему, после 1000-го раза прочтения Ильи Кантора и перепиской с форумчанами понял! Под "контекстом вызова" понимается простой вызов метода! Я, ошибочно, отождествлял контекст со scope! А оказалось все проще). Напишу для таких-же, как я(если они существуют и основным направлением является что-то типа C# ;)), javascript-кодерам лучше не читать ))) :
    В javascript "контекст вызова" = экземпляру класса, в котором вызван метод. Т.к. глобальный инстанс в web javascript = window, то все функции (в javascript функции и методы - ЭТО РАЗНЫЕ ВЕЩИ!!! Вернее, по мне, так js-"функции" - это те-же методы объекта window, но в документации они разделяются) вызываются под ним. Т.е., если в коде есть:
    function foo()//учел правильную критику Дениса Ишенина с наименованиями
    {
        console.log(this);
    }

    то это равнозначно в шарпе:
    class Window{
    public ... Foo(...)
    }

    и соответственно вызов в js в любом месте кода
    ...
    foo();
    ...

    хоть внутри метода, хоть в внутри другой функции, хоть "в корне" кода - "контекстом вызова"(инстансом по нашему в C#) будет естественно Window. При этом, как ни странно, не важно, где определять функцию! В js ее (именно функцию, а не метод!!!) можно определить даже внутри метода! И она все-равно будет инстансом Window! Ну вот например:
    var foo = {
        someFunc: function(){
            ...
            function innerFunction(){
                console.log(this);
            }
            innerFunction();
        }
    }

    угадайте, что выведет innerFunction? Правильно, "Window"!
    Но есть несколько "но"(как-же без них )):
    1) Если написать "use strict" вначале кода или этой функции, то будет совсем не Window, а undefine
    2) В js метод одного инстанса(1) можно вызвать в другом инстансе(2)(соответственно этот вызов будет видеть переменные этого самого другого инстанса(2)) с помощью bind и т.д.. Мне сложно провести аналогию с C#.
    3) Пока не разобрался с "потерей контекста", но, думаю, завтра на свежую голову, с пониманием, что такое "контекст вызова" - разберусь.
    4) Есть еще "стрелочные функции", но с ними, как ни странно у меня проблем не возникло. )
    P.S. прав был дяденька Декарт, когда сказал, что половину споров на земле не существовало бы, если бы люди знали смысл слов, о которых они спорят ))) Наконец-то я для себя понял(надеюсь, что правильно), как это работает! Два года писал код "как надо", и вот сегодня отважился задать вопрос и благодаря ответам наконец-то разобрался "почему". Еще раз всем огромное спасибо!
    P.P.S. Коллега подсказал, что еще проще понять(и я с ним согласен), если везде, где нет точки при объявлении/вызове функции мысленно писать Window. Т.е., вместо
    function foo()
    {
        console.log(this);
    }

    в голове сразу строится конструкция
    function Window.foo()//учел правильную критику Дениса Ишенина с наименованиями
    {
        console.log(this);
    }
    ,
    а вместо
    var foo = {
        someFunc: function(){
            ...
            function innerFunction(){
                console.log(this);
            }
            innerFunction();
        }
    }

    строится
    var foo = {
        someFunc: function(){
            ...
            function Window.innerFunction(){
                Window.console.log(this);
            }
            Window.innerFunction();
        }
    }

    и тогда инстанс, он-же "контекст вызова" - очевиден ;).
    Еще, kova1ev подсказал в коментах первого ответа про потерю контекста. Рекомендую его ответ, мне он помог!
    Ответ написан
    1 комментарий
  • Простым языком о замыканиях?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    1. Для чего замыкание существуют?
    Для инкапсуляции данных.
    В ООП есть модификаторы доступа (private, protected), которые закрывают доступ к данным извне класса, но позволяют обращаться к ним из методов.
    В ФП для этой задачи используют замыкания, закрывая данные внутри функции. Из вне данные недоступны, но вложенные функции имеют к ним доступ.

    2. В каких условиях они создаются?
    Когда вложенная функция обращается к переменным внешней функции.

    Хоть и просили без примеров, но на примере показать проще:
    // makeCounter - внешняя функция
    function makeCounter(initialValue) {
      var value = +initialValue || 0;
      // counter - внутренняя функция
      // она использует переменную value из внешней функции
      // что-бы это было возможным, для counter создается замыкание,
      // в котором хранится переменная value
      // переменная initialValue функции counter не нужна, поэтому ее можно "забыть"
      return function counter() {
        return value++;
      };
    }
    
    // у нас 3 экземпляра функции counter
    var counter1 = makeCounter();
    var counter2 = makeCounter();
    var counter3 = makeCounter(100);
    // и для каждой есть своя переменная value
    console.log(counter1()); // 0
    console.log(counter1()); // 1
    console.log(counter2()); // 0
    console.log(counter1()); // 2
    console.log(counter3()); // 100
    
    // а вот получить как-то напрямую переменную value мы не можем
    // инкапсуляция нам не дает поломать данные
    Ответ написан
    Комментировать
  • Для чего делать такие размеры?

    delphinpro
    @delphinpro Куратор тега CSS
    frontend developer
    Смотрите ситуацию. Я человек с плохим зрением. В моём браузере стоит увеличенный размер шрифта. Я открываю сайт в котором верстальщик шрифты указал как надо, в rem, а на размеры/отступы забил и задал их в пикселях. Получается уродство:

    5b935705491c9619831053.png

    Потом верстальщик стал умнее, и переписал размеры/отступы в rem'ы и сразу всё стало очень хорошо:

    hzhezdpprfkudyrsgnvz0iz1bhs.png

    Понятно?
    Ответ написан
    3 комментария
  • Как сделать тяжелый импорт из excel 800к товаров?

    syschel
    @syschel
    freelance/python/django/backend
    1. У вас именно EXEL файл или всётаки CSV который вы открываете на десктопе с помощью экселя?
    2. Если всётаки EXEL файл. Там слишком много всего нагорожено, на вроде вёрсток и формул или голые таблицы?
    3. Если всётаки голые таблицы. Вы можете делать именно CSV файл?

    Если данные будут в CVS формате, то можно всё загрузить средствами MYSQL и не использовать для обработки PHP или его библиотеки. Тогда результат будет в разы выше, чем если перебирать с помощью ПХП и потом кормить в MSQL

    Когда я в своё время сталкивался с проблемой загрузки файла товаров в базу, там было несколько миллионов единиц, то оптимальным стало именно такое решение > LOAD DATA

    Кусок моего старого MySQL кода, для наглядности
    // Загружаем кашерный файл
    LOAD DATA LOCAL INFILE '/srv/cms_cpa/files/adimport_items.csv' INTO TABLE adimport_tmp CHARACTER SET utf8 FIELDS TERMINATED BY '|' ENCLOSED BY "'" LINES TERMINATED BY '\n' IGNORE 1 LINES (id_adimport,article,available,currencyId,delivery,description,id,name,oldprice,param,picture,price,url,vendor,advcampaign_id,advcampaign_name);
    
    // Загружаем только нужные поля (!!!)
    LOAD DATA LOCAL INFILE '/srv/cms_cpa/files/adimport_items.csv' INTO TABLE adimport_tmp CHARACTER SET utf8 FIELDS TERMINATED BY '|' ENCLOSED BY "'" LINES TERMINATED BY '\n' IGNORE 1 LINES (id_adimport,@ISBN,@adult,@age,article,@attrs,@author,available,@barcode,@binding,@brand,@categoryId,@country_of_origin,currencyId,delivery,description,@downloadable,@format,@gender,id,@local_delivery_cost,@manufacturer_warranty,@market_category,@model,@modified_time,name,oldprice,@orderingTime,@page_extent,param,@performed_by,@pickup,picture,price,@publisher,@sales_notes,@series,@store,@syns,@topseller,@type,@typePrefix,url,vendor,@vendorCode,@weight,@year,advcampaign_id,advcampaign_name,@deeplink);
    
    // Все поля
    LOAD DATA LOCAL INFILE '/srv/cms_cpa/files/adimport_items.csv' INTO TABLE adimport_tmp CHARACTER SET utf8 FIELDS TERMINATED BY '|' ENCLOSED BY "'" LINES TERMINATED BY '\n' IGNORE 1 LINES (id_adimport,ISBN,adult,age,article,attrs,author,available,barcode,binding,brand,categoryId,country_of_origin,currencyId,delivery,description,downloadable,format,gender,id,local_delivery_cost,manufacturer_warranty,market_category,model,modified_time,name,oldprice,orderingTime,page_extent,param,performed_by,pickup,picture,price,publisher,sales_notes,series,store,syns,topseller,type,typePrefix,url,vendor,vendorCode,weight,year,advcampaign_id,advcampaign_name,deeplink);

    Ответ написан
    Комментировать
  • Какой движок посоветуете для такой игры?

    alexiusp
    @alexiusp
    senior frontend developer
    Судя по всему 3D тут вообще-то не нужен, раз планеты вращать не нужно. Нужно просто грамотно нарисовать полигональные спрайты, которые бы выглядели как 3D. Я бы делал на Phaser (https://phaser.io/) - он гораздо проще и легче, чем Unity. Коллизии, физика - всё что нужно там есть.
    Ответ написан
    Комментировать