• Как передать ссылку через $_GET?

    Через $_GET можно даже файл передать. Если отправить в коде заголовка его base64 :D
  • Как расположить 8 блоков текста в две колонны?

    Чтобы видеть в чем заключалась ваша ошибка вы должны приложить не заказанный вам дизайн, а ваш код, в котором вы не можете разобраться.
    Попытка "сделайте за меня" хорошая, но... облом.
  • Можно ли в PHP передать управление в другой класс?

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

    Шел год в котором для установки брокера сообщений с хранением истории событий рекомендовалось 384 гигабайта оперативной памяти. Оставались люди, которым дорого купить 50гигабайт жесткого диска.
  • Когда стоит начинать учить фреймворки?

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

    Bonifase, да, добавляем "выпилить старый код" или "найти того кто помнит как он там работает"
  • Какие главы важнее всего почитать в книге Дмитрия и Игоря php7 наиболее полное руководство?

    Я думаю самое важное - это купить эту книгу. Лучше сразу 10 копий. А потом можете не читать.
    Мне кажется хабр довольно давно грешит ботами-продвиженцами, просто думалось, что это странные люди.
    Но в сегодняшних условиях странные люди заняты баблом, а не поиском ответа "какие главы читать".
    Так что вывод напрашивается сам.
  • В каких случаях fread/fwrite для стрима (сокета) разумнее сделать чанками? А когда наоборот - обязательно завершить чтение/запись?

    gzhegow
    @gzhegow Автор вопроса
    VoidVolker, так в том то и веселуха, что я не пытаюсь "написать", я пытаюсь понять как в этой штуке работать.

    Вот кейз например.

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

    1. Отправляю команду
    2. Пишу "читай пока не встретишь 200 OK"
    3а) 200 ОК пришел сразу же
    3б) 200 ОК вообще не пришел. Кроме того сам брокер выдает это только если реально все хорошо, если что-то не так - ничего не выдает.
    3в) 200 ОК пришел, но перед ним были другие сообщения. Их нужно начать процессить в пуле, но это пол-беды. Результатом процессинга может быть ответ, который добавится в очередь (поток) на запись. Запись в свою очередь может породить уже свои собственные 200 ОК и возврщаемся в начала этого списка.
    3г) я отправлял несколько комманд и пришло несколько 200 ОК и там не написано какое подтверждение к какой команде

    Таймаут? Не выход, можно недополучить.
    Фильтр входящих с подсчетом? Все так же - подтверждение может вообще не прийти.

    Приходят мысли только на очередь ожидания подтверждения, и как приходит ожидаемое сообщение из очереди первый вынимается. Но от такой очереди мало толку, ведь если подтверждения не придет - то очередь будет копиться и резолвится как сама хочет. Отправил 3 команды, на вторую не пришло подтверждение, но она зарезолвилась потому что пришло на третью и третья думает что это она не завершилась.
  • В каких случаях fread/fwrite для стрима (сокета) разумнее сделать чанками? А когда наоборот - обязательно завершить чтение/запись?

    gzhegow
    @gzhegow Автор вопроса
    Я прочел всё до запятой, и даже понял про что написано, но мои вопросы никуда не делись. Абстрактно то это всё понятно, но конкретика ломает.

    Сейчас я написал несколько функций, которые сами по себе блокирующие (как и любые другие - пока они выполняются - простаиваем), но представляющие собой некое атоморное действие - т.е. блокирующее на очень малое время. Если их соединить в бесконечном цикле в логику - имею несколько точек выхода (т.н. стримов), и оно в общем-то пашет.

    Чтение ведется через стрим чтения. Парсинг - либо наличие разделителя \n в стриме говорит о том, что "до него = команда" либо если команда состоит из её и бади - то в её теле есть число байт и пока число байт нед остигнуто парсинг не производится, а только продолжается чтение.

    Запись ведется через стрим записи, все что записать в шаге не удалось возвращается назад в стрим записи. Вот тут есть вопрос - насколько адекватно стрим записи делить на "текущая команда" и "оставшийся буфер" (потому что работает и без этого). То есть я в стрим сейчас просто контент сую, после записи из него выгрызаю столько байт сколько в чанке, если записалось меньше, возвращаю кусочек обратно с помощью buffer.concat(rest, buffer), что вроде верно, с другой стороны не укладывается в идею что писать нужно строго так, как приказывали, то есть если команда не до конца отдана на запись, то нужно повторять команду, а не пару символов из нее которые не дослали. Опять же - имею дело с сокетом, ему в теории пофиг, пока не пришлю разделитель - ничего сделано не будет. С другой стороны к моменту записи мог произойти дисконнект, который по-хорошему означает очистить все стримы, или есть кейзы когда так нельзя (в очередях сообщений бывает такое?). Также есть кейз отправки сообщения с бадиком, в котором, если мы не дошлем бадик сообщения, но отправим команду "новое сообщение" - то сервер (наверное) вызовет операцию на кривом сообщении т.е. сообщение нужно писать "блокирующим способом" - или целиком или не отсылать совсем? Опять же, решает походу разделитель, т.е. кусок сообщения не содержит завершающего разделителя, а значит не является "кривым сообщением".

    В итоге на текущий момент сообщения парсятся и кладутся в стрим с сообщениями.

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

    В старой библиотеке было, что можно просто добавить обработчик подписки, колбэк пропихивали и когда сообщение приходит - вызывали. Если колбэк тяжелый - операция блокировала поток чтения далее. Мне это совсем не нравилось, чессговоря я не знаю правильно ли так вообще делать - приостанавливать весь поток чтения пока сообщение не будет обработано. Ведь в этом случае даже PING/PONG обмен не идет, и сервер через N секунд вообще соединение закроет и будет пофиг на ответы.

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

    Или другой вариант - вообще не делать обработку, но позволять вычитывать сообщения по нескольку штук, то есть какую-то операцию вроде readBatch(min, max), которая выдаст сообщения, как захотел - обработал, и вызвал на клиенте действия "ответить" хоть через час, если соединение еще живое. В редисе например так, хочешь обработать - делаешь lpop/lmove, а не ждешь пока колбэк завершится.

    Второй вариант как-то грамотнее смотрится (особенно учитывая что консольный клиент ничего не обрабатывал, его задача была ПЕРЕДАТЬ сообщение, а не ОБРАБОТАТЬ его), но что-то я не ловлю до какой степени упарываться в фильтрах чтения. Ведь блокирующую операцию вычитывания можно остановить: по времени, по числу байт, по ручному вызову в обработчике, по числу сообщений в стриме - и это самое интересное что "число сообщений" - это вообще фильтр "и или", что-то вроде WHERE LIMIT OFFSET и это вроде все здорово смотрится, только какая-то сложная дичь, а не клиент для очереди получится.

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

    Что тут скажете?
  • Насчет экспорта таблицы MySQL в Excel средствами PHP?

    Делаешь CSV, потом сохраняешь руками в XLS (если разово)

    Хочешь выводить XLS чтоб поддерживались все штуки экселя (раскраски, объединение ячеек) - долго играешься с PhpSpreadsheet.
    Но второе нужно только тогда, когда от тебя хотят например прайс лист клиенту сделать. Объединить пару ячеек, подвести итоги, раскрасить, воткнуть логотип.

    Если это отчет из MYSQL без группировок, но надо чтоб экселем открывался, то ты делаешь ерунду. CSV тебе хватит с головой.

    Без импорта не открывает, потому что кодировку кривую создаешь, гугли смену кодировки. И потом, показывает окошко "импортировать", где одна кнопка "ОК", тяжело нажать?
  • В каких случаях fread/fwrite для стрима (сокета) разумнее сделать чанками? А когда наоборот - обязательно завершить чтение/запись?

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

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

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

    Выглядит то разумно. Но остаются вопросы.

    1. Чтобы восстановить потерянное соединение, нужно подключиться, потом считать, и потом написать ответ. Без этого система попросту не будет получать дальнейшие сообщения. И здесь задействованы все три исполнителя, оно разве не повлияет на остальные вызвав какие-то простои? Или это мне кажется, на самом деле в простое будет только то соединение, которое просто ожидает, когда процесс пройдет по его собственному пути, остальные будут продолжать себе работать?

    2. Еще остается вопрос с большими сообщениями. В протоколе указано число байт в теле сообщения при его чтении. Но ведь если я на одном из соединений вызову условный "читай 1 гигабайт пока не закончишь", то система сожрет всю сетку только на чтение а заодно подвесит поток. Значит ли это что здоровенные файлы нужно продолжать равномерно читать допустим по 1килобайту на соединение за шаг цикла чтения и складывать это в буффер пока все данные не будут получены? Или здесь нужен какой-то умный балансировщик который еще и учитывает что если мы знаем заранее известное число байт, то он пропорционально отдает больше сети тому, у кого впереди скачка целого гигабайта? Понимаете, как это на коде будет выглядеть - цикл бесконечный, в котором мы пробегаемся по соединениям и на каждом вызываем чтение. Если вызвать чтение гигабайта, то шаг цикла закончится минут через 10 (добавляем сюда возможный обрыв интернета и тогда = никогда), остальные будут терпеливо ждать. Либо я всем жестко ставлю качай по 1 килобайту, и тогда все будет равномерно, но скорее всего гиг будет качаться куда больше часов чем мне хотелось бы, потому что даже те соединения где читать в данный момент нечего все равно будут пытаться подключиться, чтобы убедится, что там ничего нет. Где баланс?
  • В каких случаях fread/fwrite для стрима (сокета) разумнее сделать чанками? А когда наоборот - обязательно завершить чтение/запись?

    gzhegow
    @gzhegow Автор вопроса
    ага кажется в общем идею начинаю вдуплять

    тогда добавлю инфу что в моем случае утилизация железа недоступна. я не могу управлять раздельно памятью и процессором и пытаюсь применить утилизацию чтение и запись к нескольким подключениям в сети стараясь обеспечить равномерную их нагрузку вместо полной утилизации каждого по очереди. при этомимею некоторые действия требующие загрузить процессор работой но при этом избежать простоя сети. основных таких действий тут два. авторизация при старте требующая почитать одно соединение чтобы продолжить писать и важно что в случае потери связи такое же действие придется выполнить не останавливая те соединения где все ок и обработка входящих которые сами по себе могут занимать большое время изза навешанных действий но результат мне нужно отправить в поток записи то есть одно соединение должно висеть обмениваясь пинг понг пока выполняется операция
  • В каких случаях fread/fwrite для стрима (сокета) разумнее сделать чанками? А когда наоборот - обязательно завершить чтение/запись?

    gzhegow
    @gzhegow Автор вопроса
    VoidVolker, понимаю вас, но с момента появления в php консоли - это уже давно не так. Он умеет все то же что и другие языки - и подымать скрипты-демоны, и делать асинхронно задачи. Меня интересует принципиально подход для чего блокирующее чтение и не-блокирующее, язык для меня вторичен.

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

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

    Правильно ли я понимаю, что если протокол сервер-клиент такой, что после коннекта нужно дождаться ответа, а затем ответить, авторизовавшись, то эта часть должна быть блокирующей, тогда как слушание пула соединений в блокирующем виде превратится в слушание одного соединения.
  • В каких случаях fread/fwrite для стрима (сокета) разумнее сделать чанками? А когда наоборот - обязательно завершить чтение/запись?

    gzhegow
    @gzhegow Автор вопроса
    Я понимаю что чтение бывает блокирующее и не-блокирующее, я лишь хочу понять в каких случаях - какое.

    Так например клиент на открытие соединения отвечает настройками сервера, и ожидает что получив их, я выполню авторизацию.

    В данном случае мне вроде как нужно блокирующее чтение до конца всего сообщения с этой информацией. Значит я должен запустить чтение циклом с ограничением "команда считана или пинг превышен". С другой стороны, когда я соберу соединения в пул, то заблокировать пул пока кто-то из них читает тож нельзя получается.
  • В каких случаях fread/fwrite для стрима (сокета) разумнее сделать чанками? А когда наоборот - обязательно завершить чтение/запись?

    gzhegow
    @gzhegow Автор вопроса
    VoidVolker, это клиент для очереди сообщений с подписками на них (PUB/SUB) и режимом запрос-ответ (REQUEST/REPLY). Сервер будет слать на клиент входящие, когда посчитает нужным. А клиент - отвечать на них, если это требуется, опять же - как посчитает нужным.

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

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

    И в пыхе есть функции
    считать
    вписать
    проверить_окончание_потока (там нету "скока байт, есть только - поток все еще открыт на той стороне?")
    открыть_соединение
    закрыть_соединение
    и функция stream_select() (которая по сути foreach только с таймаутом - перебирает по очереди список потоков и дает им время что-то прочитать или написать туда, после чего переходит к следующему).

    И что-то мне подсказывает, что точно такие же функции есть и в других языках, и других быть не может, просто кто-то уже выполнил ту задачу что делаю я, и красиво их обернул, чтобы они "были в другом инструменте"
  • В каких случаях fread/fwrite для стрима (сокета) разумнее сделать чанками? А когда наоборот - обязательно завершить чтение/запись?

    gzhegow
    @gzhegow Автор вопроса
    Вы имеете в виду, что очередь в итоге одна для всех соединений, вместо того, чтобы держать по очереди на соединение?

    пс. в пхп не знаю функции "сколько там накопилось в сокете для чтения". предполагаю что нужно читать N байт и процессить по мере чтения и останавливать по какому-то критерию, ведь конца сокета пока его на той стороне не закроют - нету

    пс.2. даже если узнаю, то вопрос вешать ли все потоки пока все не считаю - открыт и пока не понят мной. любая параллелька, будь то async/await в яваскрипте или pcntl_fork имеет начало и конец, и логика в том, чтобы начав параллель в какой-то момент опросить завершенность процесса, чтобы закрыть потомков. если воркеры начинают выполнять действие в параллели, но чтение должно продолжаться, то вопрос подвешивания и ожидания пока "все потомки закончат" (он же Promise.all()) остановит чтение, стало быть ожидалки быть не должно, просто запускаю параллель и в каждом опросе потоков уточняю что закончилось и можно закрыть, и только после закрытия имею столько-то команд на запись в ответ что "я всё прочел, спасибо".

    ===

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

    и еще вот это вызывает вопросы "а так же номер блока и общее их число", в пхп есть fread() которая вернет мне столько то байт, разбиение по блокам откуда берется?

    ====

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

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

    безусловно можно открывать новое соединение на каждый чих, но мне кажется такая система недолго проживет.
  • Как лучше работать в postgresql и php с временными зонами?

    Shurik, ну обычно настраивают в конфиге, но бывает что забывают, поэтому я на всякий случай ставлю в коде тоже, но есть люди кто на это ругается. И вроде правильно делает, ведь он может потом передать через env, а приложение перезапишет настройку и будут беды.

    Это вопрос связи между профессионалами, на которую лиды и управленцы всегда забивают, хотя это их единственная работа.
  • Как правильно указать путь к контроллёру в web laravel?

    Он в канализации под агропромом. А в чистом небе в пещере с насосной станцией у Долга.
  • Как задать условие "если url начинается с my.site/me/*, то..." в php?

    оно же

    if (0 === strpos($url, $needle)) {
      // doSome
    }


    Дичь только в том, что в урла сайта сегодня такой домен завтра другой домен, и функция может поломаться при переезде, если в $needle не зашить переменную окружения с доменом.
  • Как работать в Vite + Laravel без JS-фреймворков?

    Вячеслав Липатов, Я открыл документацию Vite и вижу то же самое как и везде. Глобальная функция defineConfig которая тянется из пакета vite которая неизвестно как работает и такая же глобальная функция laravel() оборачивающая плугины для Vite или для вебпак, снова какие-то непонятки. Такие же непонятки были и в Миксе, связанные с тем, что им тяжело прочитать refactoring.guru и сделать два билдера, условные "конфиг вити" и "конфиг вебпака".

    В этом плане у симфони-энкора билдер наиболее близкий к вебпаку и с минимальным функционалом для manifest.json-а, и он просто работает. И он как раз то, что работает без JS фреймворков, ты просто поставил энкор, написал класс для манифеста и втыкаешь вызовы в голую PHP, и все потом работает так, как будто ты на js фреймворке, привычным и понятным для верстальщика способом.

    А вот Витя это очередная попытка типа схватить хайп. Микс вышел тулзой которая требует взгляда "наоборот", они переделывают его на Витю, который такой же. Это бред. Бред с точки зрения "хочу сделать то-то, как - непонятно, в доке - пусто". Это RIP. Единственный способ сделать сборщик лучше - применить паттерн билдер заставив IDE помогать программисту. Они этого не сделали. Просто снова хайпанули.

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

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

    Пишите телегу будем разбирать энкор.