Ответы пользователя по тегу PHP
  • PHP как передавать POST большие файлы быстро?

    @mantyr
    Пишу много Golang кода с удовольствием:)
    Что бы не упираться в ограничения:
    • разбивать файл на чанки равной длины
    • загружать чанки параллельно на несколько разных суб.доменов (st1.example.com, st2.example.com ... stN.example.com)
    • использовать http2 соединение
    • передавать файлы (и чанки в том числе) в бинарном виде


    Если количество входных точек меньше чем количество чанков то на некоторые адреса будет несколько отправлений, желательно не переустанавливать соединение, а держать хотя бы keep-alive, а ещё лучше разобраться как передать данные после текущей отправки в текущее соединение.

    Замерять скорость:
    • сети между серверами и клиентом
    • пропускную способность веб-сервера
    • общую нагрузку на сервер
    • io диска куда складываются данные


    Возможно есть проблема:
    • со скоростью работы диска, может быть он сбоит и потерял 80% своей скорости
    • с загрузкой канала между сервером и клиентом
    • слишком много запросов к веб-серверу и он просто блокируется постоянно
    • браузер перегружен плагинами или слишком много js кода который убивает отзывчивость


    Так же попробуйте отправить файл на другой сервер похожим образом и сравнить.

    Более подробно про отправку файла чанками:
    sendFile: function(file) {
                if (file.size > this.maxFileSize) {
                    this.alert('Файл слишком большой!');
                    return false;
                }
    
                var fd = new FormData();
                      fd.append("file", file);
    
                // Создаем запрос
                var xhr = new XMLHttpRequest();
                xhr.upload.addEventListener('progress', context({obj: this}, this.uploadProgress), false);
                xhr.onreadystatechange = context({obj: this, html: html}, obj.uploadFinish);
                xhr.open('POST', this.handler);
                xhr.send(fd);
            },


    Тут мы видим xhr.send(fd), теперь идём в один из примеров, например https://learn.javascript.ru/xhr-resume и видим вариант с отправкой части файла:
    var slice = file.slice(10, 100); // прочитать байты с 10-го по 99-й включительно
    xhr.send(slice); // ... и отправить эти байты в запросе.


    Если у вас получится сделать механизм многопоточной загрузки то можете контрибьютить в этот репозитарий: https://github.com/mantyr/js-drag-n-drop-file-uplo... так как он чуть более объектный чем классический dropzone
    Ответ написан
    2 комментария
  • Как отправить текст на почту?

    @mantyr
    Пишу много Golang кода с удовольствием:)
    Всё что до секции
    <?php
    нее выполняется в PHP, а значит у вас нет переменной outArray, тем более вы не можете написать так:
    $work=(outArray);
    .

    Сверху у вас javascript который выполняется в браузере, снизу у вас PHP который выполняется на сервере (до того как страница доберётся до браузера). Дальше сами.
    Ответ написан
    Комментировать
  • Как на php запретить различным процессам одновременно читать файл?

    @mantyr
    Пишу много Golang кода с удовольствием:)
    Почитайте про блокировку файлов. php.net/manual/ru/function.flock.php

    Пример из документации
    <?php
    $fp = fopen("/tmp/lock.txt", "r+");
    
    if (flock($fp, LOCK_EX)) { // выполняем эксклюзивную блокировку
        ftruncate($fp, 0); // очищаем файл
        fwrite($fp, "Что-нибудь пишем сюда\n");
        fflush($fp);        // очищаем вывод перед отменой блокировки
        flock($fp, LOCK_UN); // отпираем файл
    } else {
        echo "Не удалось получить блокировку !";
    }
    fclose($fp);
    ?>
    Ответ написан
    Комментировать
  • Как кешировать однотипные MYSQL UPDATE?

    @mantyr
    Пишу много Golang кода с удовольствием:)
    Накапливайте в памяти. Вы не указали язык программирования на котором такая задача.

    PHP - можно сделать in-memory таблицу в MySQL и делать туда всё теже UPDATE `news` SET `views`=`views`+1, раз в N минут обновлять основную таблицу данными из in-memory (добавлением, а не заменой значения, иначе при рестарте сервера при очередном обновлении потеряются часть показателей)
    Golang - хранить количество просмотров в памяти с RWMutex защитой, раз в N минут сохранять все накопленные изменения в MySQL базу

    Так же можно использовать Memcache, shared memory, любые другие базы данных, исходя из:
    • языка программирования
    • доступного инструментария


    Так же можно вынести views поле в отдельную таблицу или даже на другой MySQL сервер:
    • либо отдельно views
    • либо сделать копию таблицы news

    При этом можно добавить очередь (RedisMQ или что-либо другое) для асинхронного увеличения news.views, принцип следующий:
    • пользователь запросил страницу - сделалось SELECT
    • сделали задание в очередь на обновление статистики
    • пользователь получил страницу
    • через какое-то время задание по обновлению количества просмотров выполнилось и пользователь ничего не ждал
    Ответ написан
  • Вопрос по подключению системы кэширования?

    @mantyr
    Пишу много Golang кода с удовольствием:)
    Почитайте, optimization.guide и вот вам немного теории:

    Кешировать можно:
    • целиком всю страницу (для каждой страницы своя запись в кеше)
    • отдельные части сайта


    Кешировать можно в файлах:
    • генераруя готового html
    • генерируя html+php, так работают smarty и прочие шаблонизаторы собирая множество шаблонов в один
    • в виде бинарного содержимого, сюда и готовый html и готовые значения вычислений и прочее
    • в виде сериализованного массива с чем угодно, от предыдущего пункта отличается только форматом хранения


    Кешировать можно в базе:
    • в mysql/postgresql и прочих SQL - будет храниться на диске и горячие данные в памяти
    • в mysql/postgresql и прочих SQL в in-memory таблицах - будет храниться в оперативке, но без дополнительных усилий кеш пропадёт при рестарте сервера
    • в in-memory базах данных, часто это memcache, redis и прочее - опять таки выключили сервер - данные пропали
    • в in-memory базах данных с сохранением на диск, это Tarantool, memcachedb и прочие если там заявлена такая функциональность


    Так же можно:
    • кешировать всё кроме вставок динамики
    • кешировать куски вставляя их в динамику

    Это два противоположных подхода которые при особом желании можно смешивать в рамках одного проекта.

    Обновлять кеш можно:
    • при каждом запросе проверяя что старый кеш устарел
    • предкеширование - отдельным кроном/демоном/сервисом генерировать кеш раз в N минут
    • по мере изменения данных сбрасывать кеш и следующий запрос сгенерирует новый
    • по мере изменения данных сбрасывать кеш путём генерации сразу нового и замены старого на новый


    Кеш можно хранить:
    • на том же сервере что и сайт - нет задержек в сети, но зато ресурсы теже, CPU, диск, оперативная память
    • на внешнем сервере - задержки в сети, зато ресурсы отдельно


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

    Если используете CMS/CMF - посмотрите готовые плагины для кеширования. Если у вас не sharing-хостинг с мини-сайтом - озаботтесь профилированием (xhproof) и мониторингом, это поможет понять где и что кешировать.

    Так же стоит рассмотреть кэширование байт-кода:
    • OpCache
    • APC
    • XCache

    Стоит прочитать вот эту статью:
    Сравнение скорости исполнения кода Drupal для PHP 5.3-5.6 и 7.0. «Битва оптимизаторов кода» apc vs xcache vs opcache https://habrahabr.ru/post/264775/

    Так же стоит:
    • увеличить буферы в MySQL (если памяти много)
    • потюнить другие системы, например поставить nginx вместо apache, раздавать статику с другого хоста
    • и конечно же - посмотреть как долго работают SQL запросы и по возможности их облегчить


    Кеширование в MySQL с использованием HandlerSocket:
    • данные хранятся в MySQL innodb базе, а значит чтение и запись можно делать как по старинке через SQL так и через HandlerSocket
    • можно сделать любое количество колонок, лишь бы это позволял MySQL
    • быстрая вставка
    • быстрая выборка
    • бинарный протокол передачи данных
    • есть несколько библиотек для PHP, как относительно новых так и старых
    • в Percona Server (форк MySQL) HandlerSocket.so есть в поставке по умолчанию, разве что нужно включить
    • в MySQL необходимо собрать HandlerSocket самостоятельно и включить в MySQL


    Можно почитать вот тут:
    Ответ написан
    3 комментария
  • Как сделать функционал привязки домена?

    @mantyr
    Пишу много Golang кода с удовольствием:)
    На стороне dns-сервера:
    • поставить bind и настроить его работу на MySQL или любую другую SQL базу данных
    • генерировать текстовые конфиги для bind (или любого другого dns-сервера)
    • сделать конфиг где в любых случаях всех кто запросит любой домен с этого DNS отправлять на список IP принадлежащих сервису.


    Во всех трёх случаях slave сервера нужно будет настроить так же как master. Тоесть вряд ли у вас будет связка где master вы будете генерировать, а slave будут более глупыми и забирать зоны у master не зная их списка.

    На стороне веб-сервера:
    Если речь о vps/vds/collocation/dedication сервере то можно:
    • генерировать nginx конфиги виртуальных хостов
    • генерировать apache конфиги виртуальных хостов
    • сделать настройку по умолчанию на некий скрипт и уже в скрипте инклудить каталог с доменом
    • поискать в настройках nginx/apache (или какой вы там веб-сервер используете) возможность включить хост в адрес пути - уверен там такое должно быть


    Уверен можно придумать ещё два-три кейса на эту тему.
    Ответ написан
    Комментировать
  • Как вывести баннер посередине статьи?

    @mantyr
    Пишу много Golang кода с удовольствием:)
    $arr = explode("\n", $text); 
       $centr = round(count($arr)/2); 
       $arr[$centr] = "<a href='http://site.ru/banner.gif'>Привет, это баннер</a>\r\n".$arr[$centr];
       return implode("\n", $text);

    Не идеальный код... не красивый код... зато простой.
    Ответ написан
    1 комментарий
  • Почему DateTime некорректно отрабатывает?

    @mantyr
    Пишу много Golang кода с удовольствием:)
    Не надо передавать в new DateTime() timestamp, туда нужно отправлять обычный текстовый вариант даты.

    <?php
    $timezone = new DateTimeZone("Europe/Moscow");
    
    $start = new DateTime("01-10-2014 00:00:00", $timezone);
    $stop  = new DateTime("10-10-2014 24:00:00", $timezone);
    
    $interval = new DateInterval('P1D');
    $daterange = new DatePeriod($start, $interval ,$stop);
    
    foreach($daterange as $date){
        var_dump($date->format("d.m.Y"));
    }


    string(10) "01.10.2014"
    string(10) "02.10.2014"
    string(10) "03.10.2014"
    string(10) "04.10.2014"
    string(10) "05.10.2014"
    string(10) "06.10.2014"
    string(10) "07.10.2014"
    string(10) "08.10.2014"
    string(10) "09.10.2014"
    string(10) "10.10.2014"


    При этом обратите внимание на вторую дату, там время 24:00:00 для того что бы весь день учитывался, иначе дату 10.10.2014 получить было бы нельзя, впрочем, достаточно указать даже одну секунду что бы день засчитался (10-10-2014 00:00:01)
    Ответ написан
    Комментировать
  • Как вывести шесть нулей (000000) и прогнать их через цикл (000001, 000002 ...)?

    @mantyr
    Пишу много Golang кода с удовольствием:)
    <?php
    $value = 0;
    for($i = $value; $i < 999999; $i++){
        echo sprintf("%06d", $i) . '<br>';
    }


    Искать в Google: "php вывод числа с ведущим нулём", "php число с ведущим нулём".
    Ответ написан
    2 комментария
  • Как заставить демона работать постоянно, а не только во время SSH сессии?

    @mantyr
    Пишу много Golang кода с удовольствием:)
    user@server ~ $ nohup ./program

    Так же можно использовать


    Если задача запустить и потом лишь перезапускать то лучше supervisor, пример из adw0rd.com/2012/11/2/python-supervisor :
    [program:<project>_uwsgi]
    ; Имя программы в supervisor, например будет выводится в supervisorctl
    process_name=%(program_name)s
    ; Вы можете указать сколько таких процессов надо запустить, по умолчанию 1
    numprocs=1
    ; Путь до проекта (chdir)
    directory=/<project>
    ; Команда для запуска программы
    command=/<project>/venv/bin/uwsgi /<project>/uwsgi/production.ini
    ; Из под какого пользователя запускать программу
    user=<username>
    ; При загрузке самого supervisor запускать программу
    autostart=true
    ; Если программа аварийно завершилась, то перезапускать её
    autorestart=true
    ; Перенаправляет пришедший STDERR в ответ supervisor'у в STDOUT (эквивалент /the/program 2>&1)
    redirect_stderr=true
    ; Таймаут в секундах, после которого supervisor пошлет SIGKILL процессу,
    ; которому до этого посылал SIGCHLD
    stopwaitsecs=60
    ; Какой сигнал посылать для остановки программы
    stopsignal=INT
    ; Путь до error-лога
    stderr_logfile=/var/log/<project>/wsgi_err.log
    ; Путь до output-лога
    stdout_logfile=/var/log/<project>/wsgi_out.log
    ; Максимальный размер файла output-лога, после чего будет "rotate"
    stdout_logfile_maxbytes=100MB
    ; Количество файлов output-лога
    stdout_logfile_backups=30
    ; Размер буфера для output-лога
    stdout_capture_maxbytes=1MB
    Ответ написан
    Комментировать
  • Как сделать случайные отзывы на php?

    @mantyr
    Пишу много Golang кода с удовольствием:)
    Всегда отделяйте алгоритмы от шаблонов, иначе потом эту кашу замучаетесь править и проверять.

    У вас что все комментарии одинаковые что фотографии и заголовки можно тасовать как заблагорассудится?

    Предложу так: 3 не ассоциативные массивы, rand(0, count($array_title)-1) для получения индекса.
    <?php
        $array_title = ...
        $array_body = ...
        $array_photo = ...
    
        $title_id = rand(0, count($array_title)-1);
        $body_id = rand(0, count($array_body)-1);
        $photo_id = rand(0, count($array_photo)-1);
    
        $title = $array_title[$title_id];
        $body = $array_body[$body_id];
        $photo = $array_photo[$photo_id];
    
    ... передача этого всего в шаблон

    Но лучше всего когда комментарии живые (написанные человеком) и тогда по сути один массив каждый объект которого хранит в себе и заголовок и сообщение и фотографию... и тогда rand() нужен уже один.

    Хранить при этом можно как угодно. Например в CSV виде в обычном текстовом файле:)
    Ответ написан
  • Можно ли писать server-side на нескольких языках одновременно?

    @mantyr
    Пишу много Golang кода с удовольствием:)
    Попробуйте микросервисы на обоих языках, а связь по REST API или net/rpc, протобуфер есть скорее всего под оба языка программирования.

    В продакшине наблюдаю в разных сочетаниях Golang/PHP/Node.JS/Bash/Си/Python и ничего, нормально.
    Ответ написан
    Комментировать
  • Будет ли польза в такой затеи?

    @mantyr
    Пишу много Golang кода с удовольствием:)
    Постепенно собираю свой архив решений на все случаи жизни, у меня для этого отдельный репозитарий на github.com/mantyr/runner и вообще прочие не связанные с Golang вещи тут imagick.metlan.ru плюс ребята знакомые пишут как минимум два проекта с подсказками по программированию в виде каталогов (но Golang там врядли будет в ближайшее время). Так же не плохи ресурсы stackoverflow.com и https://www.socketloop.com/tutorials/

    По Golang же самые лучшие ресурсы: godoc.org https://golang.org/pkg/ 4gophers.ru

    В любом случае ваш проект - это ваш опыт, как программирования так и поиска и сбора информации, её представления публике. Учитесь и всё получится. И поделитесь ссылкой когда будете готовы.
    Ответ написан
  • Как правильнее записывать данные в 2 связанных таблицах?

    @mantyr
    Пишу много Golang кода с удовольствием:)
    Если я вас правильно понял то вы:
    1. на входе имеете массив тегов $tags = array("tag1", "tag2", "tag3")
    2. хотите сохранить новые в базу
    3. хотите получить id всех тегов и присвоить их к некоторому посту

    Попробуйте сделать так:
    1. INSERT IGNORE INTO `tags` (title) для всех тегов, те что есть проигнорируются
    2. SELECT id FROM `tags` WHERE `title` IN (...) для всех тегов что вам нужно
    3. INSERT IGNORE INTO `post_tags` для всех id полученных из второго запроса

    По крайней мере это уменьшит количество кода и упростит понимание.
    + добавьте слой кеширования для хранения тегов которые уже добавлены в базу (их ведь особо много явно не будет)
    Ответ написан
  • "Разработка cms" как тема диплома?

    @mantyr
    Пишу много Golang кода с удовольствием:)
    Дипломная работа предполагает некоторое исследование, некий поставленный вопрос и процесс получения на него ответа. Научная работа, одним словом. Если хотите сделать разработку CMS дипломным проектом то и подходите к ней как к диплому, со всеми вытекающими от сюда особенностями.

    Придумайте методику, подкрепите её знаниями и исследованиями, проведите ряд экспериментов, а там глядишь и диплом будет с чего писать.
    Ответ написан
    5 комментариев
  • Скрипт удаления картинок старше 2 дней с сервера это возможно на php?

    @mantyr
    Пишу много Golang кода с удовольствием:)
    Давайте попробуем разобраться.
    1. вам нужно научиться удалять конкретный файл по конкретному адресу
    2. вам нужно научиться получать список файлов конкретного каталога
    3. вам нужно научиться либо проверять конкретный адрес файла на дату создания файла и выбирать те что старше 2 дней либо научиться в пункте 2 получать список только тех файлов которые уже старше 2 дней
    4. вам нужно научиться запускать скрипт каждую неделю через cron

    Вот когда пройдётесь по этому списку, подтяните знания тогда всё и получится.
    Ответ написан
    1 комментарий
  • Как сделать serialize?

    @mantyr
    Пишу много Golang кода с удовольствием:)
    <?php
        $a = array(
            0 => 53,
            1 => 55,
            2 => 56
        );
    
        $b = serialize($a);
        echo $b; # a:3:{i:0;i:53;i:1;i:55;i:2;i:56;}

    А у вас что-то странное. Может кто-то и знает.
    Ответ написан
    2 комментария
  • SQLite в лендингах?

    @mantyr
    Пишу много Golang кода с удовольствием:)
    Научитесь генерировать статические файлы:) А исходники для генерации можно хранить где угодно, хоть в SQLite хоть в ini файлах, хоть в BerkeleyDB если уж сильно хочется... На хостинге нет MySQL?
    Ответ написан
    Комментировать
  • Какой php WebSockets server вы используете?

    @mantyr
    Пишу много Golang кода с удовольствием:)
    Перешёл на Golang и сделал WebSockets сервер для себя на нём. Есть в планах модуль-интерфейс для PHP. и если вам такое нужно - можете мне написать, обсудим. skype: mantyr
    Ответ написан
    Комментировать