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

    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 комментария
  • Как реализовать debounce для поля ввода, чтобы ограничить количество вызовов API в JavaScript?

    ProgrammerForever
    @ProgrammerForever
    Учитель, автоэлектрик, программист, музыкант
    Отключать и ставить таймер на выполнение каждый вызов
    const input = document.getElementById("search");
    let searchdDebounceTimerHandler;
    
    input.addEventListener("input", (e) => {
        clearTimeout(searchdDebounceTimerHandler); // Если ввод быстрый, удаляем выполнение функции каждый раз
        searchdDebounceTimerHandler = setTimeout(() => {
            fetchSuggestions(e.target.value);
        }, 1000); // Сработает через секунду от последнего нажатия
    });
    Ответ написан
    Комментировать
  • Че с виндой моей происходит?

    @Drno
    похоже что Ваш диск умирает... я бы для начала перенёс инфу нужную
    Ответ написан
    Комментировать
  • Как разместить laravel в подпапке?

    pickHabr
    @pickHabr
    Костыльных дел мастер
    мне кажется тебе нужно не на уровне nginx это делать, а на уровне роутов ларавель. в ларавель есть роуты api, для этих маршрутов все идет черед префикс /api. нужно по аналогии реализовать /laravel (ну а все остальные варианты доступа убрать)

    Например вот такой провайдер (ну или можно в стандартном провайдере, но я бы там закоментил просто стандартный вариант, а кастом в новый провайдер унес)
    <?php
    
    namespace App\Providers;
    
    use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
    use Illuminate\Support\Facades\Route;
    
    class MyRouteServiceProvider extends ServiceProvider
    {
        /**
         * The path to your application's "home" route.
         *
         * Typically, users are redirected here after authentication.
         *
         * @var string
         */
        public const HOME = '/laravel/home';
    
        public function boot(): void
        {
            $this->routes(function () {
                Route::middleware('laravel')
                    ->prefix('laravel')
                    ->group(base_path('routes/laravel.php'));
            });
        }
    }


    и подключить его в config/app.php
    'providers' => ServiceProvider::defaultProviders()->merge([
            /*
             * Application Service Providers...
             */
    
            App\Providers\MyRouteServiceProvider::class,
        ])->toArray(),
    Ответ написан
    2 комментария
  • Почему не работает такая конструкция тернарного оператора в WP?

    Mike_Ro
    @Mike_Ro Куратор тега WordPress
    Python, JS, WordPress, SEO, Bots, Adversting
    <header class="<?php echo (is_front_page()) ? 'black_bg' : 'white_bg'; ?>">
    Ответ написан
    Комментировать
  • Как отфильтровать модель по наличию связи с другой моделью?

    delphinpro
    @delphinpro Куратор тега Laravel
    frontend developer
    Waste::whereHas('components', static fn($q) => $q->whereIn('id', [1,2,3]))
    Ответ написан
    Комментировать
  • Как отфильтровать модель по наличию связи с другой моделью?

    malinichevvv
    @malinichevvv
    Back-End PHP Developer
    $wastes = Waste::whereHas('components', function ($query) {
        $query->whereIn('waste_component_id', [1, 2, 3]);
    })->get();
    Ответ написан
    Комментировать
  • Как отфильтровать модель по наличию связи с другой моделью?

    alexey-m-ukolov
    @alexey-m-ukolov Куратор тега Laravel
    If you need even more power, you may use the whereHas and orWhereHas methods to define additional query constraints on your has queries, such as inspecting the content of a comment:

    use Illuminate\Database\Eloquent\Builder;
     
    // Retrieve posts with at least one comment containing words like code%...
    $posts = Post::whereHas('comments', function (Builder $query) {
        $query->where('content', 'like', 'code%');
    })->get();
     
    // Retrieve posts with at least ten comments containing words like code%...
    $posts = Post::whereHas('comments', function (Builder $query) {
        $query->where('content', 'like', 'code%');
    }, '>=', 10)->get();
    https://laravel.com/docs/11.x/eloquent-relationshi...
    Ответ написан
    7 комментариев
  • Можно сделать обычный шрифт моноширинным?

    SagePtr
    @SagePtr
    Еда - это святое
    Некоторые шрифты поддерживают стиль font-variant-numeric: tabular-nums;
    Ответ написан
    2 комментария
  • Пропала панель фильтрации из вкладки "Сеть" в DevTools, как вернуть?

    @psihacker
    Наверняка автор решил данную проблему. Я столкнулся с такой же. Оказывается под вкладками есть маленькие иконочки. Первая в виде красной точки или квадрата, вторая в виде зачеркнутого круга, третья воронка фильтра. Третья и отвечает за включение или отключения фильтрации. Скрин прилагаю. Не за что)
    657c5b0519419134642827.png
    Ответ написан
    Комментировать
  • Как сохранить функцию php при срабатывании скрипта js?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Ответ написан
    Комментировать
  • Какую CMS выбрать для возможности создания страниц с разным текстом?

    Mike_Ro
    @Mike_Ro
    Python, JS, WordPress, SEO, Bots, Adversting
    WP + Advanced Custom Fields (если предпочтителен WP).
    Strapi (если предпочтителен 1 ЯП (JS) на фронте и бэке).
    Ответ написан
    Комментировать
  • Что за фильтр используется?

    pozZzitiv
    @pozZzitiv Куратор тега Дизайн
    Дизайнер и перфекционист
    Это не фильтр и даже не фотография. Это векторное изображение, где каждый объект автор окрасил в желаемый цвет.
    https://www.shutterstock.com/ru/image-vector/horiz...

    Ну и дополню:
    • сделать/перекрасить такое же векторное изображение можно в любом векторном редакторе — Adobe Illustrator, Corel DRAW, Inkscape и др.;
    • обрабатывать растровые изображения (фото) можно в Adobe Photoshop, Lightroom, Corel Painter и др.

    Если вообще не знаете ничего, то поищите уроки по созданию желаемого эффекта и пробуйте повторить в той программе, которую использует автор.
    Ответ написан
    Комментировать
  • Почему browser-sync ломает кодировку?

    delphinpro
    @delphinpro Куратор тега HTML
    frontend developer
    Это давняя проблема. Решения я не находил.
    Но так как проблема только в отображении, а сами файлы в порядке, то ее можно просто игнорировать. К тому же этот глюк плавающий, он может проявляться или нет, а если и проявляется, то в разных местах.
    Ответ написан
    Комментировать
  • Composer не видит переменную PATH?

    @Dimon-zmey
    Все дело в использовании Open Server в котором уже установлен composer. Зайдите в \OpenServer\modules\php\ выберите версию php которую вы используете и удалите файлы composer.bat и composer.phar. После перезагрузки сервера команда composer сразу заработает.
    Ответ написан
    5 комментариев
  • Как перенести недоступный сайт?

    iDx
    @iDx
    Полностью скопируй папку с сайтом на новый хостинг, бэкап базы данных залей, отредактируй wp-config.php.
    в гугле ищется как "перенос сайта wordpress на новый домен"
    Ответ написан
    1 комментарий
  • Как создать папку для каждого обрабатываемого файла?

    delphinpro
    @delphinpro Куратор тега Gulp.js
    frontend developer
    передавайте в dest функцию, которая будет возвращать нужный путь
    https://gulpjs.com/docs/en/api/dest#parameters

    .pipe(gulp.dest(function(vinyl) {
      retun 'path_to....';
    }))
    Ответ написан
    1 комментарий
  • Как реализовать данную часть верстки?

    RAX7
    @RAX7
    Ответ написан
    Комментировать
  • Страница не видит $ при подключенном Jquery, в чем ошибка?

    ThunderCat
    @ThunderCat Куратор тега CSS
    {PHP, MySql, HTML, JS, CSS} developer
    1) Если вы хотите использовать jq в инлайновых скриптах, то подключать его надо в head разделе и без атрибута defer, но это во первых не самая лучшая практика (понятно что это съедает время загрузки страницы), во вторых все равно может не работать, если связь с цдн сервером сильно хуже чем с самим доменом. Можно скачать файл на свой хост, но опять же - это не гарантия и половинчатое решение.
    2) Все скрипты, использующие подгружаемые библиотеки в идеале должны выполняться по событию загрузки документа.
    document.addEventListener('DOMContentLoaded', function() {
    //тут уже есть возможность работать с jq
        console.log($('.footer'));
        alert("Усе готово, шеф!");
    });
    Ответ написан
    Комментировать
  • Курсор ввода в любом месте окна браузеров?

    @greg79
    В хроме та же F7
    Ответ написан
    Комментировать