Задать вопрос
  • Как объединить запросы в транзакцию?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Поскольку быстрым поиском готовый ответ на Тостере не находится, стоит написать канонический.

    Сначала общая информация:

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


    Самым простым вариантом будет заключить запросы между вызовами beginTransaction() и commit(), как показано например в документации к последнему.
    $db->beginTransaction();
    $db->prepare("UPDATE `tab1` SET `col` = ?")->execute($data1);
    $db->prepare("UPDATE `tab2` SET  `col` = ?")->execute($data2);
    $db->prepare("UPDATE `tab3` SET  `col` = ?")->execute($data3);
    $db->commit();

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

    Соответственно, при ошибке в любом из запросов транзакция автоматически откатится. А при успешном выполнении всех запросов транзакция, соответственно, закоммитится.

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

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


    Также желательно помнить, что в любом более-менее сложном коде очень быстро появляются вложенные транзакции, а PDO при попытке стартовать транзакцию при уже открытой, выбросит исключение, что, соответственно, приведёт к откату родительской (и это гораздо лучше поведения MySQL по умолчанию, которая автоматически коммитит старую). И имеет смысл накидать простой кодик, который считает вложенные транзакции, и не стартует, если уже был старт, а при коммите вычитает вложенность, а реально коммитит только если вложенности не осталось. Что-то вроде кода из комментариев к beginTransaction(), подравняв его напильником
    class \MyPDO extends \PDO
    {
        protected $transactionCounter = 0;
    
        public function beginTransaction()
        {
            if($this->transactionCounter++ === 0) {
                return parent::beginTransaction();
            }
        }
        public function commit()
        {
            $this->transactionCounter--;
            if($this->transactionCounter === 0) {
                return parent::commit();
            }
        }
        public function rollback()
        {
            $this->transactionCounter = 0;
            return parent::rollback();
        }
    }

    разместив его либо прямо в PDO, либо в своем враппере.
    Ответ написан
    3 комментария
  • Бд для дискорд бота?

    @Everything_is_bad
    А что именно ты там хранишь нам угадывать, да? Ок, хрустальный шар говорит, что надо сменить на нормальную sql базу.
    Ответ написан
    3 комментария
  • Разбивка на страницы?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Чтобы ограничить количество выводимых страниц требуется знание арифметики в пределах начальной школы.
    Чтобы вместо 1 и $num_pages использовать заранее рассчитанные значения, укладывающиеся в определённый интервал. Например 10 страниц.
    То есть надо всего лишь определить начальную и конечную цифры, которые подставлять в for вместо 1 и $num_pages.
    Например, если мы хотим выводить только 10 страниц, а текущую выводить посередине то для получения первой цифры надо отнять от текущей 4. Затем к ней надо прибавить 9 - так мы получим второе число.
    При этом, разумеется, надо проверить, чтобы первое не было меньше 1, а последнее - больше $num_pages.
    А дальше просто подставить их в for. Вот и всё.
    Ответ написан
    2 комментария
  • Как иправить ошибку обновления SNAP?

    @winlinweb
    Обновление с помощью терминала.
    Убедитесь, что работа центра приложений полностью завершена:
    killall snap-store
    Обновить все приложения можно командой:
    snap refresh
    Если обновлений доступных нет, выведет:
    Все пакеты актуальны.

    Дополнительно.
    Запросить список доступных обновлений:
    snap refresh --list
    Обновить доступное из списка приложение (например: snap-store) можно командой:
    snap refresh snap-store
    Ответ написан
    Комментировать
  • После включение Secure Boot тупит компьютер, что делать?

    yakovlev_13
    @yakovlev_13
    Шаманство, экзорцизм и некромантия.
    выключи Secure boot в биосе
    Ответ написан
    Комментировать
  • Возможно ли задать подсказку в phpstorme для возвращаемого типа?

    @Vitsliputsli
    Это не просто подсказки, это контроль типов. То, что зная какой тип возвращается Шторм может подсказать варианты это побочное удобство. Основное же должно быть то, что конкретная переменная имеет определенный тип, а значит не нужны дополнительные проверки и методы будут лаконичны и конкретны. У вас пока, то ли объект, то ли массив, то есть каждый раз нужно проверять что это. Лучше бы сделать объект-коллекцию.
    Чтобы указать Шторму, что в конкретной переменной лежит только этот тип используется хинт, типа такого:
    /** @var User $user */
    но разумеется, он должен быть только в том коде где в $user лежит обязательно объект класса User и ни что иное.
    Ответ написан
    1 комментарий
  • Чем frontend разработчик занят на реальных проектах?

    @Giperoglif
    Настройка тестов, CI/CD, OLAP CUBE, оптимизация запросов к БД
    - это важно для фронтенда знать, что такое просто есть) явно вас не тем загружают.
    Ответ написан
    2 комментария
  • Чем frontend разработчик занят на реальных проектах?

    С резким ростом популярности React Server Components и Next.js в последнее время происходит некий сдвиг в понимании, что такое фронтенд.
    BFF уже почти становится неотъемлемой частью "фронтенда", и становится обременительно разделять браузер и сервер на разные команды.
    На Западе, вообще, уже очень давно и макетами, и вёрсткой, и анимациями очень часто занимается один человек - дизайнер, фронтендеры занимаются связкой браузер + BFF, а бэкендеры занимаются более сложной бизнес-логикой.
    К тому же, джуниорам зачастую дают те задачи, которыми сами не хотят заниматься, и на что нет времени. Т.е. это что-то занудное, работа с legacy, передвижение кнопки на 5px влево и т.д. Крайне редко джуниорам дают интересные творческие задачи. Не факт, что вам на новом месте не дадут такие же неинтересные задачи.
    Вы можете либо молча сильно стараться в надежде, что вам потом дадут что-то интересное, заметив ваше рвение, либо, лучше всего, пообщаться по-человечески с коллегами и начальством, объяснив, что вы рветесь в бой, а вас в тылу держат. Попросите рассказать об их планах на ваш счёт.
    Не исключено, что у вас как раз хорошо получается "Настройка тестов, CI/CD, OLAP CUBE, оптимизация запросов к БД", и поэтому вам эти задачи и дают)
    В общем, человеческое общение с коллегами очень часто решает проблемы.
    Если же вы к ним придёте с открытой душой, а вас токсично отошьют, вот тогда подумайте о смене работы.
    Ответ написан
    7 комментариев
  • (фото) что если на материнке погнулось это?

    По-моему, это для плашки с аудиоразъёмами на передней части корпуса. Если у Вас такой плашки нет, то некритично.
    Рядом погнут штекер для подключения плашки с LPT портом - там то же самое.

    Если чем-то не пользуетесь, то главное, чтобы штекеры друг друга не касались, напрямую или через корпус.
    Ответ написан
    3 комментария
  • (фото) что если на материнке погнулось это?

    Можешь взять пинцет или шприц и выровнять, так как не встанет коннектор.
    Судя по маркировки это разъём для выхода наушников на переднюю панель
    Ответ написан
    2 комментария
  • Почему uasort игнорирует вложенный массив при сортировке?

    @kosta6832 Автор вопроса
    function cmp_sort($a, $b)
    {
    	if ($a['ncount'] == $b['ncount']) {
    		return 0;
    	}
    
    	return ($a['ncount'] > $b['ncount']) ? -1 : 1;
    }
    function arrSort(array &$arr)
    {
        uasort($arr, 'cmp_sort');
        foreach ($arr as $k => &$v) {
            if(isset($v['children'])){
                arrSort($v['children']);
            }
        }
    }
    arrSort($array);
    print_r($array);
    Ответ написан
    1 комментарий
  • Не понимаю какой php.ini загружается?

    alexey-m-ukolov
    @alexey-m-ukolov Куратор тега PHP
    У PHP разные файлы настроек для разных сред. Вы поменяли настройки для CLI (консоли), а нужно для FPM (скорее всего).
    Вы вывели вот phpinfo() — там указан файл, из которого берутся эти настройки. Поищите по странице «.ini» и увидите, где менять.
    Ответ написан
    Комментировать
  • Какие есть утилиты для автоматизированного проектирования БД?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Какие есть утилиты для автоматизированного проектирования БД?

    Зависит от того что понимать под термином "Проектирование БД".

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

    Возможно, в какой-то близкой перспективе до этого дошагают средства ИИ, но мне как-то сомнительно.

    =========================

    Но, поскольку вопрос учебный, то скорее всего имеются в виду средства, которые позволяют нарисовать ERD по выполненному анализу, а потом на основе построенной диаграммы сгенерировать SQL-код создания структуры БД. Если так, то товарищи уже накидали вариантов. Впрочем, следует отметить, что в случаях, когда выполненный анализ и выбранная архитектура/реализация требует существования в БД таких типов объектов, как, например, триггеры, хранимые процедуры, эвенты и пр., ни одно из уже перечисленных средств не справится.

    Но вот хрен знает, что на самом деле в мозгу у вашего препода.
    Ответ написан
    3 комментария
  • Совместима ли материнка и этот блок питания?

    @apppostol
    Совместимы.

    ps.
    Вообще конечно про совместимость надо думать ДО покупки)
    И там в компе есть еще другие штуки, которые тоже требуют внимания касаемо совместимости.
    Ответ написан
    9 комментариев
  • Как 1TB может записаться на 931Gb?

    @karminski
    Senior React.JS Developer
    GiB - это гибибайты
    TB - это терабайты

    Разные системы исчисления.
    https://www.translatorscafe.com/unit-converter/ru-...
    Ответ написан
    2 комментария
  • Не могу установить OC Kali Linux на click bios 5?

    15432
    @15432
    Системный программист ^_^
    У вас включен Secure Boot, который проверяет цифровую подпись загрузчика на носителе. У загрузчика на флешке подпись отсутствует, что UEFI и сообщает. Для корректного запуска нужно отключить Secure Boot в другом разделе настроек, либо записать на флешку дистрибутив системы с цифровой подписью, которую примет ваш ПК.
    Ответ написан
    Комментировать
  • Определение значений передаваемой в функцию переменной типа массив?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Это один из тех вопросов новичков, на который нельзя давать прямой ответ. Он превратится в пустое умствование и говнокод. Соглашусь с комментарием Дмитрий: тут просто не нужен массив. И тем более не нужно городить огород из абстракций. Тут явно нужен банальный VO/DTO, а автору надо перестать пытаться заворачивать привычные массивы в солидно выглядящие объекты, и начать использовать сами объекты.

    Если нам нужна конкретная структура, то и описываем её в конкретном классе, безо всяких интерфейсов:

    final readonly class Parameters
    {
        public function __construct(
            public string $key1,
            public int $key2,
            public DateTimeImmutable $key3,
        ) {}
    }
    public function execute(Parameters $parameters):


    В итоге у "стороннего разработчика" есть готовая документация - простое и понятное определение класса, экземпляр которого он должен передать в ваш метод. И уже на этапе создания этого объекта РНР надаёт разработчику по рукам, если хоть какое-то свойство не будет задано, или будет не того типа. При желании можно в конструктор добавить дополнительную валидацию, если просто типа недостаточно.

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

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

    Для этого есть либо стандартные валидаторы, когда на вход подаётся массив и набор правил, вот например как в ларавле, симфони или в десятке отдельно стоящих библиотек, а на выходе - или гарантированно валидная структура данных, или ошибка.

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

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

    @Joyz
    Возьмите дешевый роутер, в него воткните кабель с интернетом вместо компьютера, а дальше уже провод к компьютер.
    Ответ написан
    2 комментария
  • По порту 8080 php не работает?

    402d
    @402d
    начинал с бейсика на УКНЦ в 1988

    Файл php вложен в локальный web-сервер на Tomcat от одной СЭД (дабы не поднимать второй web-сервер в сети).

    Проще поднять второй сервер.
    Или перепишите на java скрипт.

    Googlиapache tomcat & php together
    Но фактически получиться схема.
    Проки(nginx или апач) за ним два бакенда (для JAVA-томкат и PHP)
    Ответ написан
    Комментировать
  • Как установить Ubuntu без флешки?

    @rPman
    Установить linux - это значит установить загрузчик (который запускает linux после bios) и собственно скопировать файлы.

    В современных реалиях на x86 машинах есть 3 способа загрузки:

    1. legacy dos (еще называют compatibility support mode или csm и т.п.)
    загрузчик прописывается на физическом диске в первом секторе раздела плюс рядом (для таблицы разделов mbr это первые сектора, для gpt специальный 1мб раздел bios boot)
    Соответственно для загрузки необходимо в биосе выбрать диск, с которого производить загрузку (или указать порядок).
    grub автоматически прописывает этот способ, если uefi не доступен

    2. UEFI
    Специальный раздел efi boot (формат fat32) примерно 100мб должен содержать файл xxx.efi который уже запускает систему соответственно своей логике.
    'Благодаря' майкрософту, информация о том, с какого диска нужно продолжать загрузку, прописывается в самом биосе, т.е. при изменении конфигурации (например замена диска), установки ОС и т.п. нужно прописать специальной программой в биосе загрузочную запись (и кстати на некоторых материнках производитель гвоздями прибил совместимость только к майкрософтовскому bcdboot.exe из режима восстановления, а остальные способы могут не работать, даже из windows), обычно grub при установке делает это автоматически
    Но главное, в режиме secure boot (который часто вообще нельзя отключить) файлы .efi должны быть подписаны майкрософтом (на дорогих моделях материнок можно свою подпись добавлять), т.е. linux вы запускаете так же с разрешения майкрософта.
    Единственный случай, когда запись о загрузчике в биосе может отсутствовать, это removable drives.
    На засыпку, никакие утилиты не имеют доступ к UEFI, если система не запущена в режиме UEFI, т.е. использовать флешку придется как минимум один раз.

    3. загрузка по сети, ее еще называют по технологии PXE
    p.s. ее есть что то у серверных ipmi ну и разные альтернативы removable drives

    Если достаточно использования legacy dos режима, то есть лайфхак, как установить систему из другой системы - использовать виртуальную машину (в новых windows 10 и старше не получится поставить загрузчик на системный диск, даже на другой раздел, типа защита, но можно на другой физический диск), просто пробросив физический диск в виртуалку и провести установку с виртульного cdrom а затем перезагрузить хост машину, указав в биосе этот диск как загрузочный.

    upd. оказывается в материнках может быть режим UEFI Network Stack (или аналогичный), это режим загрузки UEFI PXE, получается достаточно в локальной сети настроить соответствующий сервер, загрузиться в linux и прописать загрузочную запись UEFI, т.е. флешка не потребуется.
    Ответ написан
    Комментировать