Ответы пользователя по тегу PHP
  • Как сохранять клики и их время в кликере?

    @rPman
    вместо условных 100 кликов людям засчитывало ~40
    судя по sql у тебя количество сохраняемых кликов считается как сначала запросом получить текущее значение, затем сохранить его увеличенным... что естественно неправильно обсчитывается, если одновременно на бакэнд идут несколько запросов, и завершаются в разном порядке (т.е. первый, получил значение 1, затем его обогнал второй, получил то же значение 1, оба отправляют +1 значение, т.е. 2, вместо ожидаемого 3.

    Правильно: одним обновлением в базе нужно - проверять допустимость клика (проверить время последнего клика), обновить время последнего клика и увеличить количество кликов на 1... после чего бакэнд проверяет, сколько записей было обновлено, если 0 - значить выход за лимиты, если 1 - все ок.
    update set clicks=clicks+1, last_click_time=now() where last_click_time+:ALLOWED_CLICK_INTERVAL<now() and id=:current_id


    p.s. даже очень слабая машина позволит делать сотню запросов в секунду на обновление, а хорошая - десяток тысяч

    Можно больше, но тогда понадобится разнести таблицу аналитики и таблицу событий, в таблицу событий записывают события, но она без индексов, а в аналитику зааливать данные из всех собранных событий, в цикле
    Ответ написан
    Комментировать
  • Как упростить метод, выполняющий операции для всех других методов класса, если он получается слишком раздутым?

    @rPman
    Вам зачем нужна прослойка? Что бы заменить некрасивый синтаксис curl_xxx на свой некрасивый?

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

    Обычно не доходят до того, чтобы создать под каждый тип запроса свой метод, но как минимум нужно создать метод request, который под капотом будет:
    * обрабатывать авторизацию
    * обрабатывать ошибки сети и отслеживать лимиты сервиса и отправлять повторные запросы
    * выжидать необходимые таймауты
    * обрабатывать пакетные запросы, к примеру если сервис требует постранично работать с данными
    * регистрировать и обрабатывать обратные вызовы callback, если такие есть (само собой это уже другой метод)

    Не рекомендуется все данные собирать в аргументах одного вызова, наоборот, пусть перед выходом нужно будет сделать инициализацию полей этого класса, в которых собирается все необходимое и вот тут пусть класс следит, что все необходимые данные заданы. т.е. должен быть метод типа startPrepare, который очистит предыдущие значения, тут же можно установить вид запроса, и тут же можно описать, значения каких полей можно перенести с предыдущего запроса, что очень важно для использования. Либо на каждый тип запроса (метод на удаленном сервисе) пилить свой метод со своими порядками и аргументами, как говорил выше.
    Ответ написан
    Комментировать
  • Как вывести элементы списка через запятую?

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

    По коду ты пытаешься сформировать json строку, для этого лучше использовать json_encode, которая любой объект (строки, массивы, многоуровневые объекты) превратит в соответствующий json, ведь в строках например может понадобится экранировать всякие ковычки, слеши и другие непечатные символы
    Ответ написан
    6 комментариев
  • Как быть если две библиотеки начинают зависят друг от друга?

    @rPman
    а почему бы не объединить эти обе библиотеки в одну?
    зачем мельчить если они друг от друга зависят и так?
    Ответ написан
    Комментировать
  • Как правильно использовать python скрипт через PHP backend?

    @rPman
    В общем случае технологии называются Interprocess communication.

    Изначально предлагались (php/python) механизмы очереди сообщений, shared memory и semaphores, как минимум на их основе делают высокоуровневые библиотеки по работе с сообщениями (и используют именно их, а не низкоуровневые, но знать про них обязан каждый, чтобы понимать недостатки)

    Второе и самое логичное, использовать socket-ы, как unix socket или pipes, так и tcp. Многие не заморачиваются, а поднимают полноценный асинхронный http сервер и организуют общение между приложениями по http или лучше websocket протоколу, так как это позволяет распределить приложения уже не в пределах одного сервера, а в сети, что дает очень высокую гибкость, но ценой значительных накладных расходов на сериализацию.

    Правда если используются разные языки программирования, в которых разные форматы для структур данных, так же придется сериализовать структуры, т.е. память копировать и кодировать/декодировать.
    Ответ написан
    2 комментария
  • Как загрузить файл через API в диалог Claude?

    @rPman
    превышается максимальное количество токенов

    Никак, придется делать что то с файлом, что бы он влез в контексте окно.

    Человек точно так же не сможет переварить за один раз большой объем информации, llm-ки тут наследовали эту ограниченность и невнимательность.

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

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

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

    Метод/класс/файл это не 'или', собирать информацию нужно параллельно на всех уровнях.

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

    @rPman
    Например, проверяй, чтобы ссылка на видео содержала параметр, результат целочисленного деления текущего времени timestamp на количество секунд в требуемом сроке (24*3600*7).

    А что бы не было возможности это подделать, можно хранить не само значение а его хеш какой-нибудь не сильно слабой хешфункции (md5 считают слабой но для ее взлома требуется прилично ресурсов, если доступ к видео этого не стоит то хватит) плюс секретное значение (его называют 'соль')
    if(@$_GET['hash']==md5(SECRET_SALT.(time()/(24*3600*7))))
    {
      // разрешить доступ к видео
    }

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

    Путь к видео в этом случае будет выглядеть как: https://example.com/hash/filename.ext
    для веб сервера hash это каталог, а скрипт должен просто создавать эту ссылку на диске на настоящее место размещения файла (в не публичном каталоге естественно).
    Ответ написан
    4 комментария
  • Может ли, во время чтения файла одним скриптом, другой скрипт начать записывать в этот файл новые данные?

    @rPman
    первым, кто открывает файл, должен использовать функцию flock над идентификатором файла fopen
    $file = fopen('filename.txt', 'r');
    // пробуем установить эксклюзивную блокировку
    if (flock($file, LOCK_EX)) {
        // выполнение операций чтения
        // ...
        
        // освобождаем блокировку
        flock($file, LOCK_UN);
    } else {
        echo "Не удалось установить блокировку на файл.\n";
    }
    fclose($file);


    это системная фича posix, не привязанная к языку программирования

    p.s. аналогичные механизмы есть у windows, при открытии файла указывается тип блокировки shared...
    Ответ написан
    5 комментариев
  • Какую кодировку выбрать для бд чтобы хранить фото?

    @rPman
    бинарные типы данных binary, varbinary или blob потому и бинарные, что к ним не применяются правила символьной трансляции (charset), т.е. к примеру их нельзя сортировать по алфавиту.

    p.s. настоятельно рекомендую трижды подумать, зачем тебе нужно хранить изображения в базе данных, и с высокой вероятностью лучше их хранить в файлах на диске а в базе только имя файла (а можно и имена файлов привести к идентификаторам базы).
    Ответ написан
    Комментировать
  • Есть ли в PHP готовый инструмент для получения элемента массива вложенность которого хранится в другом массиве?

    @rPman
    С академической точки зрения, если это не в продакшен и только похвастаться, можно воспользоваться eval:
    $myfunc = eval('return function($x) { return $x['.implode('][',array_map('json_encode',$path)).']; };');
    echo json_encode($myfunc($ar)); // {"v":{"a":123,"b":321}}

    Тут array_map('json_encode',$path)) экранирует всякие ковычки и слеши, преобразуя значения в код для их получения
    Затем полученный массив с помощью implode('][',... превращается в последовательный вызов элементов этого многомерного массива.
    А eval('return function($x) { return $x[...]]; };'); формирует строку функции для вызова этой конструкции и помещает ее в переменную.
    Затем остается только вызвать это $myfunc($ar);

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

    p.s. если структура $path неизменна для проекта, я бы рекомендовал генерацию кода перед запуском (т.е. прямо .php файлы генерировать) а не во время, это будет еще быстрее и эффективнее, да и поддерживать этот бред будет понятнее.
    Ответ написан
  • Как запретить скачивание файл по прямой ссылке?

    @rPman
    Я помню реализовывал очень простой механизм разграничения доступа к статическим файлам без привязки к особенностям веб серверов (там есть плагины на авторизацию) и при этом чтобы файлы для веб сервера оставались статикой.

    Файлы размещаются в каталоге, недоступном веб серверу а в конфиге веб сервера включается поддержка симлинков (например apache - Options FollowSymLinks). Затем, модуль авторизации создает на каталог с файлами, к которым нужен доступ для пользователя символическую ссылку в публично доступном каталоге, с именем, равным идентификатору сессии пользователя session_id() а по завершению сеанса, симлинк удаляется (если сеанс должен завершаться автоматически, придется использовать какой то работающий демон или периодический по крону для проверки всех сессий на завершение). Таким образом ссылка на скачивание будет формироваться из сессии пользователя и будет оставаться статичной (т.е. веб сервер будет отдавать этот файл сам, максимально эффективно), но доступ к ней будет только у авторизованного.

    Код для этого дела - несколько строчек.

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

    @rPman
    Не понятно причем тут php, но у apache есть режим отображения содержимого каталога как html, в виде списка файлов в табличном виде (имя, размер, дата модификации...), и имя файла будет ссылкой на этот файл, если кликнуть на файлы изображений или любых других файлов, типы которых зарегистрированы в браузере - они будут отображены внутри, иначе будет диалог загрузки файла.
    <Directory /var/www/html>
            Options +Indexes
            AllowOverride None
            Require all granted
        </Directory>

    тут +Indexes делает именно это - генерацию html

    p.s. если же нужно на php генерировать список файлов по своей логике то добавляешь поддержку php в apache (модуль mod_php или php-fpm) и index.php:
    foreach (scandir('.') as $file)
    {
        if ($file == '.' || $file == '..') continue;
        echo '<a href="' . htmlspecialchars($file) . '">' . htmlspecialchars($file) . '</a> - ' . filesize($file) . '<br>';
    }
    Ответ написан
  • Как можно использовать результат запроса из другого файла?

    @rPman
    Предпологаю что речь идет о веб бакэнде - приложении, запускаемом на веб сервере по запросу из браузера. И главное, предполагаю что используется cgi подход, когда на каждый запрос из браузера запускается отдельный процесс php (даже если это модуль веб сервера, он конечно оптимизируется до асинхронных потоков) но содержимое памяти каждый раз пустое.

    Если у тебя mainpage.php и poisk.php это разные запросы, то через глобальные переменные данные между ними не передать.

    Нужна какая-нибудь база данных, чем бы она не являлась, например:
    * хранить в специальных заголовках запроса - cookies, эти данные как мяч будут автоматически передаваться между клиентом и сервером, т.е. все запросы от клиента будут содержать копию всех установленных cookies, до истечения их времени жизни
    * переменные сессии (используются cookies автоматически)
    сессия доступна сразу после session_start() а данные через ассоциативный массив $_SESSION (автоматически сохраняется по окончанию скрипта, учти это при параллельных запросах), идентификатор сессии автоматически поддерживается в заголовках запроса (сессия стартует когда пользователь открывает сайт, и единая для других окон, адже после перезапуска браузера, время жизни опция cookie_lifetime)
    Очень часто идентификаторы сессии или специально созданное значение в ней используется как идентификатор для поиска данных в других местах (например БД)
    * можно использовать файлы, в которых данные хранятся в сериализованном виде, в php штатно работает var_export/eval, serialize/unserialize, json_encode/json_decode - текстовые и бинарный igbinary_serialize/igbinary_unserialize (очень эффективный формат) или свой собственный, по желанию
    * можно использовать базу данных, начиная с sqlite (размещается в файле но работа с помощью sql), настоятельно рекомендую PDO - универсальная прослойка для работы с реляционными БД
    * есть еще всякие memcache, apcu, или к примеру самописный сервер данных (на сокетах и не только) но применимость - отдельный разговор

    p.s. есть иной подход, когда на php пишется полноценный веб сервер, принимающий http запросы (его напрямую редко пускают в интернет, обычно ставят еще какой-нибудь nginx для поддержки ssl и других тонкостей), в этом случае php приложение скорее всего - один инстанс (один процесс), который не завершается по завершению запроса, обрабатывает запросы клиентов асинхронно, в этом случае глобальные переменные будут доступны между запросами.
    Ответ написан
    3 комментария
  • Какую архитектуру парсинга маркетплейса выбрать?

    @rPman
    100к событий в секунду с торговой платформы это сюр, такое практически нереально, (ну может в самый первый раз когда база пустая).

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

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

    Отсюда архитектура - отдельно дубовые парсеры-загрузчики (их можно размещать буквально где угодно, они получают команду на загрузку и молотят, выдавая json-чики пакетами в виде результата), отдельно узлы-обработчики, которые на каждый пакет данных от загрузчиков делает нужные запросы в базу данных (или заранее кеширует в памяти, но тут нужно считать, что дешевле - апгрейдить сервер базы данных или держать на дисках кеш-дампы запросов и обновлять их параллельно БД, в этом случае кстати БД остается как конечное хранилище и аналитики). Ну и про базу данных, они на запись медленные только если там индексы распиханы по максимуму, хороший способ, если загрузка в базу редкая (например раз в сутки длится час) то можно отключить на это время индексы, провести загрузку, вернуть индексы - это кратно ускоряет процесс ЗАГРУЗКИ но не проверки целостности и поиск данных, т.е. подходит именно когда анализ проводится не в БД.

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

    p.s. у меня крутился сервис, годами собирающий терабайты данных на скорости 4к-10к событий в секунду (time series), хранить это в классической базе я не стал, а организовал хранилище на файлах, поверх которых в базе данных собирается аггрегированная выжимка и индексы.

    Это было оправдано, так как разработка аналитического сервиса шла уже в процессе загрузки и это была суть работы, т.е. нельзя заранее определить, что из этих данных и как может понадобиться, база данных строилась каждый раз под задачу, проходом по всем данным (больше времени занимала их распаковка - json с упаковкой zstd)
    Ответ написан
    Комментировать
  • Где PHP хранит кэш на "отдачу"?

    @rPman
    Отдает nextcloud, значит настройки его смотреть.

    Попробуй в /var/www/nextcloud/config/config.php (путь может немного другим быть, например home, смотри настройки веб сервера) и там настройка
    'tempdirectory' => '/tmp/nextcloudtemp',
    Ответ написан
  • Как в PHP использовать в родителе константу или статическую переменную из потомка?

    @rPman
    Имя_класса::имя_пременной
    Так же ключевое слово parent - имя предка, self - текущего класса
    например parent::CONST_NAME
    p.s. опс, не то.


    Чтобы уж ответить на вопрос, в php нет метода получения списка потомков класса, но есть функция get_declared_classes() - возвращает массив имен всех классов, и функция is_subclass_of("объект или имя класса","имя проверяемого класса") вернет true если первый класс является потомком второго. Так всех перебрав можно будет получить список потомков, ну а затем нужному по имени из переменной - $var_class_name::static_member и даже по имени мембера в переменной $var_class_name::$$static_member_name
    Ответ написан
  • Как сделать globbing строки в php?

    @rPman
    Ответ - регулярные выражения, синтаксис чуть сложнее чем * и ? но возможности выше
    preg_replace для однобайтовых кодировок или mb_ereg_replace для любых.

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

    upd. совсем забыл, preg_replace с модификатором /u понимает utf8 строки
    Ответ написан
    4 комментария
  • Какая конструкция у кода должна быть без goto?

    @rPman
    Если объединить все твои последовательные if в непрерывную конструкцию
    if () {} elseif () {} elseif.... else {}
    то goto или return Rsa97 не понадобятся
    Ответ написан
    Комментировать
  • Как получать динамические значения из таблицы Excel через php?

    @rPman
    excel таблица залитая на google docs

    минимум 100 запросов в секунду

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

    Если убрать из списка google, то можно самостоятельно хостить headless excel (майкрософтовский офис, приложение на чем угодно, работа с activex из того же .asp) либо libreoffice, вот пример на питоне но идею я надеюсь ты понял...

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

    @rPman
    Мда, математику бы вам подучить.

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

    $foo = [1, 2, 3, 6];
    
    $n=end($foo);
    $asum=((1+$n)*$n)/2;
    echo $asum-array_sum($foo);
    Ответ написан
    4 комментария