• Асинхронная многопоточность в PHP: для чего?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    Все очень просто. Вот вам приблизительное значение таймингов доступа к данным:
    io-cost.png

    То есть запросив данные в сети мы тупо ждем. Долго ждем и ничего не делаем.

    В случае с curl (он же HTTP) мы можем соорудить очередь запросов и послать их одним махом и ждать пока завершится загрузка всех документов в очереди для обработки результатов. Если мы хотим забрать 10 документов, то без multi curl у нас ушло бы времени "среднее время получения документа" * 10. И это примерно. В случае же с мультикурлом мы получаем время обработки 10 запросов как время выполнения самого долгого запроса. Если представить что время запросов всегда одинаковое, получаем выйгрыш примерно в 10 раз.

    С сокетами веселее. Они бывают блокируемые (по умолчанию) и неблокируемые (выставляется опцией O_NONBLOCK). Для начала давайте определимся что такое чтение данных из сокетов и как нам это дело предоставляет операционная система. Упрощенно, когда мы создаем сокет, мы просто просим операционную систему предоставить оный. У каждого сокета есть буфер чтения и буфер записи. Если буфер записи полный - ОС начинает отправку данных пока буфер не опустеет (буфер записи нужен для организации проверки дошли ли пакеты и переотправки в случае чего, так же этот буфер замешан в выборе операционкой размеров пакетов и т.д. Это не особо важно в контексте вопроса). Когда данные приходят в сокет, сначала они помещаются в буфер чтения. Там они лежат пока их не попросят вернуть из кода. Так мы можем быть уверены в том, что данные не пропадут.

    Так вот... возьмем блокирующие сокеты и попробуем запросить 1024 байт данных из оного. Причем клиент в данный момент ничего не отправляет, буфер чтения пустой. И так допустим минут 10. Как только мы сделали запрос за данными, и оказалось что буфер чтения пустой, процесс выполнения блокируется пока не появятся данные.

    А теперь представим что проверять периодически наличие данных нам надо не в одном сокете а в десятке. Представим так же что 9 клиентов подключенных по нашим сокетам хорошие и присылают данные вовремя, а один не хороший и любит тупить по пол часа. Если бы мы пользовались блокирующими сокетами, то мы можем обрабатывать только одного клиента за раз. Причем если у него вдруг данных не оказалось - нам придется ждать, хотя в других сокетах уже вполне могли появиться данные какие для обработки. И если в случае с "хорошими" клиентами мы можем тратить на оных по пол секунды - секундочке, то наткнувшись на плохого клиента наш сервер замирает за те самые пол часа о которых мы договаривались. Сервер тупо ждет "плохого" клиента а хорошие в итоге не могут достучаться до сервера. Новых соединений мы так же не установим... короче все мертво.

    И тут на помощ к нам приходит опция O_NONBLOCK. В этом случае если у сокета пустой буфер чтения он сразу вернет выполнение не вернув нам ни капли данных не дожидаясь медлительных клиентов-тугодумов. В случае если буфер не пустой - все будет так же как и в случае с блокирующими сокетами - тупо вернет содержимое буфера и вернет управление. Так что мы можем в бесконечном цикле просто проверять по очереди все сокеты. В этом случае делей получения данных будет сведен к минимуму.

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

    Еще есть такая чудная штука, которую предоставляет операционная система как select или epol (в контексте php socket_select и stream_select). Данные функции позволяют нам скармливать массивы сокетов, за которыми вы следите (не сокетов, а их дескрипторов но не суть, и не один массив а три, массив дескрипторов что бы следить появились ли данные на чтение, записал ли сокет все и освободился ли буфер записи и третий отслеживает сокеты в которых произошли какие-то ошибки, например отвалилось соединение). Так же этой функции можно задавать таймаут, что очень удобно если мы сначала собираем данные с нескольких клиентов и если от них небыло вестей пару секунд, значит мы забрали все и можно начинать обработку.

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

    Но все что выше имеет смысл только с TCP/TLS, если бы у нас были UDP сокеты, то было бы еще веселее. Там нету никаких буферов. Не принял данные - потерял данные. Нету соединений. Нету блокировок. Есть только пакеты. Поэтому этот протокол используют (или используют как основу) для реализации реалтайм систем. Задержек нету, а если какой пает не дошел, велика вероятность что он уже не актуален. Правда если сеть не надежная и потери пакетов велики, то начинается боль и слезы и обычно все же для таких случаев дублируют все на TCP.
    Ответ написан
  • Как правильнее переопределить метод родительского класса?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    Что именно вам не понятно в фразе
    Declaration of User::isExists() should be compatible with that of GlobalClass::isExists()

    Ее можно трактовать как

    определение метода User::isExists() не должно отличаться от GlobalClass::isExists()

    то есть вы ломаете интерфейс, ваш метод у класса наследника делает явно что-то не то, что от него требуется.

    Учите принципы ООП и GRASP (можно по видио лекциям, тут нужно что бы объяснял кто-то).
    Ответ написан
    1 комментарий
  • Фриланс и счет в американском банке. Какие налоги и кому?

    Платить вы должны там, где физически работаете. Соответственно, в России. Если вы открыли счет в заграничном банке - вы обязаны уведомить об этом налоговые органы РФ. Вас могут поймать, а могут и не поймать - но лучше приучайтесь к ответственности и учитесь платить налоги
    Ответ написан
    2 комментария
  • Какой эмулятор электронных схем выбрать новичку?

    circuitlab
    Altium Designer.

    На сколько мне известно - Altium не имеет возможности проводить анализ температур, и, тем более, анализировать надежность элементов.

    На простом уровне довольно трудно столкнуться с деградацией элементов от температуры, электромагнитного воздействия, проникающей радиации... и т.д. Даже если вы собираетесь заниматься силовой электроникой. Так, что советую сосредоточиться на простых вещах.

    Слона нужно есть по частям.
    Описание
    Журнал на рутрекере
    Ответ написан
    1 комментарий
  • Как обойти данную "загвоздку" синтаксиса?

    hell0w0rd
    @hell0w0rd
    Просто разработчик
    var createSuccessHandler = function (i) {
        return function (data) {
            alert(i);
        };  
    };
    for(var id = 1; id != 10; id++)
    {
        $.ajax({
            type: "POST",
            data: {Id: id},
            url: "getname.php",
            dataType: "json",
            success: createSuccessHandler(i)
        })
    }

    По мотивам habrahabr.ru/company/mailru/blog/233553/, 6 пункт
    Ответ написан
    4 комментария
  • Как обойти данную "загвоздку" синтаксиса?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    async: false, но лучше так не делать.

    Вообще разберитесь может почему так выходит? МОжет потом вы поймете что это никакого отношения к синтаксису не имеет... Что функции в succsess отрабатывают когда цикл уже обошли давно... И лучше делать тогда уж так:
    var ids = []
    for(var id = 1; id < 10; id++) {
        ids.push(id);
    }
    
    ids.forEach(function (id) {
        // по скольку ссылка на нужный id будет сохранена всегда, пока живо замыкание
        // все будет ок.
        $.ajax({
    		type: "POST",
    		data: {Id: id},
    		url: "getname.php",
    		dataType: "json",
    		success: function(data){	
    			alert(id);
    		}
    	})
    }


    Что бы лучше понять эту "странность" почитайте про то, как работает js. В частности про event loop
    Ответ написан
    6 комментариев
  • Как реализовать цепочку функций?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    У вас хэш-мэпа с функциями, а не объект. То есть вам нужно из функции возвращать экземпляр вашего хэш мэпа или следить за тем что бы контекст вызова сохранялся
    Но лучше так:
    http://learn.javascript.ru/object-methods#функция-...
    function Human(x, y) {
        this.x = x;
        this.y = y;
    }
    Human.prototype = {
        goUp: function () {
            this.y++;
            return this;
        }
        goDown: function () {
            this.y--;
            return this;
        }
        // ...
    }


    Так же можно отDRY-ить код:
    function coordsChangerFactory(prop, direction) {
        
        return function () {
            // тут можно добавить валидацию, мол что бы не вылазить за пределы поля
            this[prop] += direction;
            return this;
        }
    }
    
    function Human(x, y) {
        this.x = x;
        this.y = y;
    }
    Human.prototype = {
        goUp: coordsChangerFactory('y', +1),
        goDown: coordsChangerFactory('y', -1),
        goLeft: coordsChangerFactory('x', -1),
        goRight: coordsChangerFactory('x', +1)
    }
    
    var man = new Human(4, 4);
    man.goDown().goRight();
    console.log('Coords is %dx%d', man.x, man.y); // Coords is 5x3
    Ответ написан
    8 комментариев
  • Почему прыгает контент и мигают картинки?

    Petroveg
    @Petroveg
    Миром правят маленькие с#@&ки
    Потому, что при наведении грузится другая картинка. При первом наведении её ещё нет в кеше и на время загрузки ничего не видно. Так давно не делают.

    Во-первых, есть спрайты и при наведении меняется лишь положение фона.
    Во-вторых, такие кнопки уже реализуются с помощью CSS без избражений.
    Ответ написан
  • Какие браузеры поддерживают новые семантические элементы?

    Petroveg
    @Petroveg
    Миром правят маленькие с#@&ки
    Как мы все прекрасно знаем, HTML5 не очень совместим со старыми браузерами.

    Ну это весьма туманное и далеко не совсем верное утверждение.

    Во-первых, нет чёткой грани между HTML5 и HTML4.
    Во-вторых, понятие HTML5 настолько широко, что включает в себя очень много вещей, которые не поддерживаются и очень современными браузерами.

    Так что ваш вопрос можно переформулировать так: «Какие браузеры поддерживают новые семантические элементы?»
    Ответ: все, кроме упомянутого FF2 и IE8 и ниже. Первый вы ни у кого уже не встретите, для IE достаточно в скрипте создать (даже не добавляя в документ) элементы с такими именами тэгов, а в CSS прописать нужный для них display, и проблемы нет. Обратите внимание на поддержку элемента main (наводите курсор на версии браузеров).

    Кстати, если вы решите разобраться с поддержкой появившихся полей формы и их атрибутов, новых API, да что там — простенького MathML, вы узнаете много интересного, и современные браузеры уже не будут казаться настолько уж современными:)
    Ответ написан
    3 комментария
  • Почему PhpExcel не работает на хостинге?

    @jkwe45 Автор вопроса
    Нашел простое решение :
    ob_end_clean();
    Ответ написан
    1 комментарий
  • Какой смысл имеет данная конструкция в JS?

    Petroveg
    @Petroveg
    Миром правят маленькие с#@&ки
    Это — метка. Как case: или default:, использующиеся в switch.
    Обычно в JS редко увидишь использование меток, поскольку единственная их цель — в случае нескольких вложенных циклов переходить из тела любого внутреннего цикла к отмеченному внешнему, невзирая на уровень вложенности.

    Для этого используются инструкции break и continue, которые без метки работают непосредственно с тем циклом, в теле которого указаны. Если добавить метку, происходит прерывание (break) помеченного цикла либо переход к его блоку изменений (continue).

    Там же написано:
    useful for nested loops

    Пример:

    var stop = 7;
    
    label:
    for (var i = 10; i--;) {
    	console.log('i:', i);
    	for (var j = 10; j--;) {
    		console.log('j:', j);
    		if (j == stop) {
    			console.log('stop');
    			break label;
    		}
    	}
    }
    console.log('stopped');
    Ответ написан
    2 комментария
  • Есть ли возможность в css \ js наложить цвет по форме изображения?

    @ultrbi4
    Если иконки на белом фоне можно использовать filter: grayscale(), если нет, то нужно использовать canvas
    Ответ написан
    Комментировать
  • Как понять данную запись say('Hello')('World') ?

    k12th
    @k12th
    console.log(`You're pulling my leg, right?`);
    В JS функции являются гражданами первого класса. Это значит, среди всего прочего, что их можно передавать в качестве аргументов в другие функции и возвращать в качестве результата.
    function say (str1) {
        return function (str2) {
            return str1 + str2;
        }
    }
    Ответ написан
    2 комментария
  • Принято ли в js выделять приватные свойства?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    В JS нету приватных свойст. Вообще.

    Можно добавлять символы в начале, например классический вариант с двумя нижними подчеркиваниями. Например в angular.js все приватные свойства начинаются с $$ и помечены в jsdoc как @ private. При этом, если включена нужная опция google closure compiller при минификации имя свойства поменяется на какое-нибудь короткое рандомное, так что вопрос с доступом к свойству в принципе решен так как с каждым билдом имя свойства скорее всего будет отличаться и это ограничит количество желающих с ним работать.

    По настоящему приватные свойства можно эмулировать завернув все это дело в замыкания. За счет того что наша переменная находится в своей области видимости, к которой имеет доступ только ваш код, можно чуть чуть себя обезапасить.
    Ответ написан
  • Почему не работает форма?

    DmitriyEntelis
    @DmitriyEntelis
    Думаю за деньги
    0. Из Вашего сообщения не очень понятно в чем заключается "не работает".
    Не отправляет письмо? Вы не получаете письмо?
    Что? :)

    Я не поленился и исполнил Ваш код на своей машине. Все работает.
    Уточните в чем проблема.

    1. Никогда не пишите спагетти код. Шаблоны всегда должны быть отделены от логики.
    Иначе это невозможно ни читать, не поддерживать.
    Почитайте про MVC например.

    2. Отправлять почту лучше всего с помощью какой нибудь библиотеки. например swiftmailer
    Ответ написан
    2 комментария
  • Почему в PHP 5.5 нельзя в классе создать свойство равное инстансу наследника?

    disc
    @disc
    веб-разработчик
    По-моему происходит зацикливание, т.к. в конструкторе у вас инициализируется new Brute()
    Ответ написан
    2 комментария
  • Что значит пакетная вставка данных?

    BuriK666
    @BuriK666
    Компьютерный псих
    как-то так
    INSERT INTO [dbo].[Main] ([ID_CHANNEL] ,[ID_RECDATE] ,[MESVALUE])
     VALUES (1 ,@d ,Item(ELIMS.ELIMSQUE.tVAL1)), (2 ,@d ,Item(ELIMS.ELIMSQUE.tVAL2))
    Ответ написан
    1 комментарий
  • Как заменить картинку на градиент посредством CSS?

    DeLaVega
    @DeLaVega
    Верстаю, фронтэндю =)
    .gradient {
    	background: -moz-linear-gradient(top, transparent 0%, #ffffff 100%);
    	background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, transparent), color-stop(100%, #ffffff));
    	background: -webkit-linear-gradient(top, transparent 0%, #ffffff 100%);
    	background: -o-linear-gradient(top, transparent 0%, #ffffff 100%);
    	background: -ms-linear-gradient(top, transparent 0%, #ffffff 100%);
    	background: linear-gradient(top, transparent 0%, #ffffff 100%);
    }
    Ответ написан
    4 комментария
  • Как в JQueryUI для autocomplete меню задать класс?

    qmax
    @qmax
    программер
    $('.ui-autocomplete.ui-menu').addClass(класс)
    Ответ написан
    Комментировать