Задать вопрос
  • Какие есть пакеты для генерации уникальных, числовых идентификаторов длиной 10 цифр?

    Vamp
    @Vamp
    Я не знаю какой конкретный алгоритм у телеграма, но в простой централизованный инкремент я не верю. Слишком очевидный ботлнэк.

    Я читал что подобные идентификаторы собираются из ДЦ + timestamp + счётчик в рамках текущей секунды + ещё что-то.
    - И гарантия уникальности в таком случае ~60 лет.
    Твиттер придумал такой алгоритм и назвал его snowflake id. Там используется timestamp + machine id + счетчик в рамках одной миллисекунды. Уверен, телеграм использует генератор с подобным алгоритмом. Он быстрый, не требует централизованного управления (кроме назначения machine id, но это делается один раз в момент введения машины в эксплуатацию и может делаться даже вручную) и генерирует идентификаторы размером 64 бита (влезает в mysql тип bigint).

    Есть парочка пакетов с реализацией этого алгоритма - snowflake-id, snowflakify.
    Ответ написан
  • Как вести историю работы с записями во всех таблицах для всех пользователей?

    Vamp
    @Vamp
    У себя на проекте я сделал по вашему второму варианту. Колонки date, user_id, ip, table, data. Где data - json структура вида {"field_name": {"old": "было", "new": "стало"}}

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

    Vamp
    @Vamp
    1. Верно. Такой подход называется event loop.
    2. Тоже верно. Настраивать роутер нужно один раз.
    3. Да. Только вместо mysqli_ping нужно использовать mysqli_change_user.

      Функция mysqli_ping помечена как deprecated и документация php настоятельно рекомендует её не использовать.

      Функция mysqli_change_user помимо того, что валидирует соединение, ещё очищает его от состояния, оставшегося от предыдущего http запроса - откатывает незавершённые транзакции, сбрасывает сессионные переменные, снимает разнообразные локи и т.д. Это довольно важный момент, который защитит вас от трудноуловимых ошибок, когда http запрос может оказывать влияние на следующий, казалось бы, независимый http запрос.
    Ответ написан
  • Будут ли вызваны в PHP 8.4 хуки свойств при создании объекта через PDO fetchObject?

    Vamp
    @Vamp
    1. Создаётся объект без вызова конструктора.
    2. В объекте ищется поле с именем, совпадающим с именем колонки.
      1. Если поле найдено, вызывается хук set. Даже если у поля область видимости private.
      2. Если поле найдено, а хука нет, в поле просто сетается значение. Даже если у поля область видимости private.
      3. Если не найдено, вызывается магический метод __set
      4. Если __set отсутствует, создаётся динамическое поле с именем колонки.

    3. Вызывается конструктор.


    PDO::FETCH_PROPS_LATE не работает совместно с методом fetchObject. Конструктор по-прежнему вызывается только в конце. Чтобы переставить вызов конструктора наверх, нужно вызывать методы setFetchMode и fetch:
    $stmt = $pdo->query('SELECT * FROM tbl_name');
    $stmt->setFetchMode(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, $class, $constructorArgs);
    $obj = $stmt->fetch();
    Ответ написан
    Комментировать
  • Как удалить крякнутую версию нашего приложения из Rustore?

    Vamp
    @Vamp
    1. Читаете пользовательское соглашение.
    2. Пишете досудебную претензию письменно через Почту России (можно электронно) на адрес компании, указанной в данном соглашении. В претензии пишете, что приложение нарушает пункт 4.2 пользовательского соглашения и требуете его удалить, а разместившего пользователя заблокировать.
    3. При отсутствии ответа в течение 30 дней (см. п. 11.1) подавайте в суд.
    Ответ написан
    Комментировать
  • GO + FYNE GUI как запустить скрипт после подтверждения в диалоговом окне dialog.ShowConfirm?

    Vamp
    @Vamp
    Вам нужно вынести парсинг в отдельную горутину, так как диалоговое окно закрывается только после завершения выполнения callback функции. А так как вы весь парсинг выполняете в ней, то диалог, соответственно, ждёт.

    testStart := widget.NewButtonWithIcon(" Test ", theme.InfoIcon(), func() {
    	dialog.ShowConfirm(
    		"Начать парсинг?",
    		fmt.Sprintf("Ссылки для парсинга получены"),
    		func(yes bool) {
    			if yes {
    				progress.Show() // Порказываем и запускаем прогрессбар
    				progress.Start()
    				fmt.Println("Start")
    				go doTheJob()
    			} else {
    				return
    			}
    		},
    		myWindow,
    	)
    })
    
    func doTheJob() {
    	qty, file_name := parsing(urls) // функция  - парсинг товаров по ссылкам
    	//time.Sleep(5 * time.Second)
    	// Обновление виджетов разрешено делать только из главной горутины,
    	// поэтому нужно шедулить обновление виджетов через fyne.Do
    	fyne.Do(func() {
    		progress.Stop()
    		dialog.NewInformation("Данные получены", "Все работает!", myWindow).Show()
    	})
    }
    Ответ написан
    1 комментарий
  • PHP обрезает ссылку после знака #?

    Vamp
    @Vamp
    Символ # является спецсимволом, который требуется кодировать как %23.
    По-хорошему ваша ссылка должна выглядеть вот так:
    http://site.ru/dw/?url=https%3A%2F%2Fmega.nz%2Ffile%2Fe8hzUIJS%23eE1Nb6VdmFmtF2YlgO8a25X09l_fa9uxtTOjNNBgIS

    В этом примере кодированы все спецсимволы, а не только #. Такой вид ссылки гарантированно будет работать так, как вы хотите.

    В php за подобное кодирование отвечает функция rawurlencode().
    Ответ написан
  • Как подключить все 4 вентиляторы в пк на один разьём 4 pin?

    Vamp
    @Vamp
    Прочитайте инструкцию к корпусу. Раздел "Controlling lighting modes".

    688617385bff4179886456.png

    У контроллера свое отдельное питание через sata коннектор, подключающийся напрямую к блоку питания. В разъёмы с 1 по 6 вставляете rgb коннекторы от кулеров. В разъемы 7-12 вставляете питание кулеров. Провод "4 Pin PWM fan connector" вставляете в материнскую плату в разъём SYS_FAN1. Провод "5V / 3 Pin Addressable RGB adapter" никуда не вставляете, раз материнка не поддерживает управление подсветкой. Управлять подсветкой можно будет через кнопку reset, если подключить её к контроллеру.

    В вашем корпусе в комплекте идёт 4 кулера. Почти наверняка они уже будут с завода воткнуты в контроллер как надо. Останется только контроллер подключить к материнке, sata питанию и кнопке reset.
    Ответ написан
    33 комментария
  • Определить стандартный пароль от API IP камер dahua DH-IPC-HFW2449SP-S-IL-0280B?

    Vamp
    @Vamp
    Новые камеры нужно сначала инициализировать через программу ConfigTool или мобильное приложение DMSS. В процессе инициализации можно будет установить свой пароль. Если у вас есть видеорегистратор dahua, то инициализацию можно сделать через него.

    Если камеры уже были ранее инициализированы, то их можно сбросить нажатием и удержанием кнопки reset на самой камере. Далее заново инициализировать по инструкции выше.
    Ответ написан
    2 комментария
  • Скачивание файла средствами php без ожидания загрузки файла?

    Vamp
    @Vamp
    Скорее всего дело в сессии. Попробуйте вставить вызов session_write_close() непосредственно перед выводом файла:
    header('Pragma: private');
    header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
    header('Content-Length: ' .filesize($file));
    session_write_close(); // <--- вот здесь         
    readfile($file);
    exit();
    Ответ написан
    Комментировать
  • Почему возникает deadlock?

    Vamp
    @Vamp
    У вас тут гонка, а не дедлок. Методы second и third не успевают встать в ожидание condition.

    Если визуализировать пошагово:
    1. first - захватил блокировку объекта lock
    2. second - захватить lock не может, так как он уже захвачен, поэтому встаёт в ожидание
    3. third - захватить lock не может, так как он уже захвачен, поэтому встаёт в ожидание
    4. first - пишет в консоль "first"
    5. first - сигналит condition1
    6. first - релизит lock
    7. second - просыпается и захватывает lock
    8. second - встаёт в ожидание condition1, которое будет бесконечным, потому что condition1 за всё время триггерится однократно и этот триггер уже отработал на 5 шаге

    Ваш код сможет успешно завершиться если подобрать нужный тайминг. Например, так:
    var c = new SomeClass();
    try (var t = Executors.newFixedThreadPool(3)) {
        t.submit(c::second);
        t.submit(c::third);
        Thread.sleep(100);
        t.submit(c::first);
    }
    Ответ написан
    3 комментария
  • Точь в точь ли маппятся поля json-сущности на поля в таблицах базы данных?

    Vamp
    @Vamp
    Опишу проблему: я не совсем понимаю связь между json-сущностями которые отгружаются rest-методом и таблицами в базе данных.

    А её и нету, связи этой.

    REST API - это одно. Там свои форматы, логика, модель данных. Все это оптимизировано для удобства взаимодействия клиента с сервером.

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

    Каждый ли ключ обязательно должен маппится с полем в какой-то таблице?

    Не должен.

    Так что же тогда нужно понимать под фразой "сущность отгружается полностью"?

    Где вы эту фразу услышали?

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

    Аналогично и схема REST API не обязана в точности соответствовать структуре базы.

    Мой вопрос больше про маппинг полей в json-объектах отгружаемых Postman/Devtools и полями в таблицах бд.

    Не припомню чтобы Postman/Devtools как-то относились к базам данных.
    Ответ написан
    2 комментария
  • Лишние переводы строк в ответе сервера (echo)?

    Vamp
    @Vamp
    Почти наверняка лишние переводы строк находятся перед <?php.

    Или после ?> в db.php
    Ответ написан
    1 комментарий
  • Как сейчас работать с CloudFlare?

    Vamp
    @Vamp
    Отключайте проксирование в настройках DNS, тогда CF будет работать как простой DNS сервер. Именно так используется CF у dtf и vc. Что касается фильтрации трафика, то vc использует сервис qrator. Dtf же сидит на ip адресах selectel. Возможно они фильтруют трафик и защищаются средствами самого селектела.

    или же переходить на аналоги ? bunny, к примеру

    Если речь только про хостинг DNS, то можно оставаться в cloudflare. Если хотите защиту от дудоса и фильтрацию трафика и при этом не страдать от блокировок, то лучше подоборать какую-нибудь альтернативу.
    Ответ написан
    Комментировать
  • Почему длина long int 4 байта?

    Vamp
    @Vamp
    Размер этого типа данных не специфицирован. У автора на 32-битном процессоре он оказался 4 байта. У вас же 64-битный процессор, поэтому показывает 8 байт.
    Ответ написан
    Комментировать
  • Как сделать нестандартную рамку?

    Vamp
    @Vamp
    Конкретно на этом сайте рамка отрисована картинкой и вставлена через css стиль background-image.

    https://videoexpress.ai/fbdeal/assets/images/banne...
    Ответ написан
    Комментировать
  • Почему PHP считает int числа после математических операций как float?

    Vamp
    @Vamp
    Все потому, что в операции деления у вас получается float, так как операнды не поделились друг на друга без остатка. Умножение int на float в дальнейшем тоже приводится к умножению float на float.
    Ответ написан
    Комментировать
  • Где хранить ключи api используемые для тестирования открытого по?

    Vamp
    @Vamp
    Стандартной практикой является коммит в репозиторий файла phpunit.xml.dist в который прописываются все настройки по умолчанию, кроме чувствительных к безопасности (api ключи, пароли и пр). Файл phpunit.xml добавляется в .gitignore. Таким образом, если пользователю нужно кастомизировать какие-то параметры, он просто копирует файл phpunit.xml.dist в phpunit.xml и добавляет свои секреты в последний. Это безопасно, так как phpunit.xml заигнорен.

    То что вы описываете - это уже не unit, а интеграционное тестирование. Скрипты для интеграционного тестирования обычно делают в отдельном testsuite и скипаются по умолчанию. Для запуска юнит тестов не должна требоваться какая-либо подготовка - только "склонировал репозиторий, запустил". Для интеграционных подготовка уже нужна. Например, юзер должен будет модифицировать phpunit.xml (не .dist!), вписав туда свой тестовый api ключ.

    Соответственно, для юнит тестов достаточно в тестируемый код передать мокнутого http клиента, который будет возвращать ответ, который вернуло бы реальное стороннее api (в guzzle это делается с помощью MockHandler). Поэтому если надо просто запустить юнит тест, то ничего делать не нужно - phpunit автоматически подхватит phpunit.xml.dist, если не найдет phpunit.xml. Если надо запустить интеграционные, то юзер должен будет скопировать phpunit.xml.dist в phpunit.xml и добавить туда api ключ.
    Ответ написан
    1 комментарий
  • Как хранить ключи в Python?

    Vamp
    @Vamp
    Храните свои ключи в SharedPreferences, EncryptedSharedPreferences (если sdk 23 и выше) или KeyChain.
    Ответ написан
    Комментировать
  • Как реализуются лицензии по ядрам?

    Vamp
    @Vamp
    определяется лицензия -> макс кол-во ядер и на основании этого создается пул потоков заданного размера
    Так оно и есть.
    Ответ написан
    Комментировать