Профиль пользователя заблокирован сроком с 10 апреля 2022 г. и навсегда по причине: систематические нарушения правил сервиса
Ответы пользователя по тегу MySQL
  • Что почитать по составлению безопасных sql запросов?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Базовые принципы на то и базовые, что не меняются со временем. Я бы только переформулировал немного по-другому,
    • Данные подставляем в запрос только через плейсхолдеры
    • Все остальное - только после проверки через белые списки

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

    Если же говорить о тенденциях, то с чистым SQL сейчас никто практически не работает. 95% запросов выполняются через ORM. Т.е. вместо
    $stmt = $pdo->prepare("SELECT * FROM user where id = ?");
    $stmt->execute([$id]);
    $user = $stmt->fetch();

    пишем просто
    $user = User::find($id);
    при этом защита уже вшита у ORM внутри и думать о ней не надо

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

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Работа с БД идет в репозиториях.

    То есть иерархия такая:

    - простейшие операции с БД делаются через ORM в Entity.
    - сложные зпросы, группировка данных из нескольких запросов, квери билдеры - в репозитории
    - весь остальной код бизнес-логики, который работает с полученными из БД данными - в хелпере.

    При этом надо обязательно помнить, что кроме работы с БД из контроллера надо убрать и всю остальную бизнес-логику. В сервис/хелпер.

    Для проверки правильности разделения безнес-логики надо сделать консольную коменду, которая делает то же самое, что и экшен контроллера. Если в команде не дублируется код из экшена (за исключением вызова хелпера) - значит разделение получилось успешно
    Ответ написан
    Комментировать
  • Почему во всех innodb рекомендуют явно задавать PRIMARY KEY?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Зачем явно создавать колонку с первичным ключом, если она так и так будет создана?

    Если говорить конкретно об этом, то вот Jeremy Cole доходчиво объясняет:

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

    Опять же, первичный ключ может быть только один, то есть если потом мы спохватимся и захотим добавить, то уже не получится.
    Ответ написан
    Комментировать
  • Есть ли свод правил для добавления данных в БД?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Нет, при добавлении в БД никакого "свода правил" нет.
    Больше того, все твои существующие обработки к добавлению в БД не имеют ни малейшего отношения.
    Базе данных абсолютно все равно, какие данные хранить.

    Единственное правило, которое действительно нужно для БД, ты и так уже применяешь - используешь подготовленные вопросы.

    Если же говорить не о БД, а о фильтрации данных "вообще", то ответить на этот вопрос невозможно. Точно так же как невозможно ответить на вопрос, "Есть ли список болезней, от которых мне надо лечиться?". Все зависит от того, чем ты болеешь. Если тебе важно првоерять ссылки, то проверяй ссылки. Неважно? Не проверяй. Нельзя пропускать теги? Используй strip_tags. Нужно пропускать теги? Не используй strip_tags. И так далее - все зависит от задачи. Универсального правила или "свода правил", этакой волшебой палочки, которой махнул 1 раз и забыл про валидацию денных, нет и быть не может.
    Ответ написан
    Комментировать
  • Как исправить проблему с INSERT INTO?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Читаем phpfaq.ru/pdo
    Включаем для PDO вывод ошибок
    Меняем это ужас с переменными прямо в коде запроса на подготовленные выражения
    Ответ написан
    Комментировать
  • Как закрыть PDO соединение mysql?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Немедленно выкинуть на помойку этот ад кромешный, извращающий все принципы программирования. Использовать оригинальный ПДО. Прочитать Error reporting basics.
    Сделать обработку ошибок общую для всего РНР.

    Заодно пропадет и проблема с закрытием соединения.
    Ответ написан
    Комментировать
  • Как убедиться что запрос к БД выполнен?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Не надо ни в чем убеждаться.

    Эти бессмысленные телодвижения, которые так любят пользователи похапе - тяжелое наследие царского режима и видеокурсов "Начни грести бабло за 3 урока".

    Ни одна нормальная программа не занимается такой ерундой, как проверка каждого несчастного запроса на ошибки, и не начинает причитать "ой, у нас такой-то запрос сломался" если ошибка произошла.

    Не надо ни в чем убеждаться. Не надо смотреть ни на какие ошибки запросов.
    Надо ПРОСТО сказать пользователю, что все хорошо, без всяких условий. Ошибки, если будут, обрабатываются совсем в другом месте.
    Ответ написан
    Комментировать
  • PDO Почему не откатываются транзакции?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Скорее всего движок БД не поддерживает транзакции. Надо поменять у таблиц engine с myisam на innodb

    Напомню, что необходмо ловить \Exception, а не PDOException. Нам без разницы, какая именно ошибка прервала выполнение транзакции, откатываться надо в любом случае.

    Плюс никогда нельзя забывать о логировании ошибок. То есть, вместо return false;, которое совсем ни о чем, лучше перевыбросить исключение, чтобы оно могло быть обработкно стандартным образом. В общем, читайте правильные мануалы, там все есть :)
    Ответ написан
    3 комментария
  • Как одним запросом в базу получить все записи с разными критериями?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Если $users приходит из БД, то получать пользователей тем же запросом, используя JOIN.

    Ecли же приходит со стороны, делать как в ответе Arris , но только не пихать айдишники прямо в SQL, а использовать параметризованный запрос, https://phpdelusions.net/pdo#in
    Ответ написан
  • Чего не хватает моим функциям?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Ну, то что это адова жесть, уже все сказали.
    Но я логики понять не могу. В чем профит?
    Сравниваем код на этом адском поделии
    $allData=$Kernel->getRecords($GLOBAL->Table,array(
      "where"=>"`Type`='Some' AND`Status`='Y'",
      "order"=>"`Position`",
      "sort"=>"Id"
    ));

    И код на чистом PDO/SQL
    $allData = $pdo
        ->query("SELECT * FROM $GLOBAL->Table WHERE `Type`='Some' AND `Status`='Y' ORDER BY `Position`")
        ->fetchAll();

    В ЧЕМ ПРОФИТ?
    Какой смысл разбивать SQL на массив и писать по отдельности, когда можно просто сразу написать нормальный SQL?

    Ну и про безопасность тут уже все сказали. Я не знаю, за какой "безопасности" тут речь, но вот тут
    $Kernel->query($GLOBAL->Table,array(
      "type"=>"insert",
      "set"=>"`Variable1`='{$data1}',`Variable2`={$data2}"
    ));

    инъекция на инъекции и инъекцией погоняет.

    Интересно, что, функция твоего начальника не так плоха. Он только не умеет пользоваться PDO и не знает что эту функцию можно сделать в 100 раз проще, без кучи ненужных параметров. Но в целом она довольно осмысленная и безопасная. И в ней нет global. В отличие от твоего собственного кода.

    Вот твой второй запрос с использованием его функции:

    $Database->Query("INSERT INTO $GLOBAL->Table SET `Variable1`=?',`Variable2`=?", [$data1, $data2]);


    это четкий, ясный и безопасный код.
    Внимание, снова вопрос: НАФИГА?
    ЗАЧЕМ ты нагородил вот это вот всё, если оно в 100 раз хуже чем было?
    Ответ написан
    6 комментариев
  • Создание отдельной таблицы для каждого пользователя. Правильно ли?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Практика - критерий истины.

    Сделай такую таблицу, а потом попробуй вывести все комментарии под статьей или ленту последних постов на сайте.
    Ответ написан
    Комментировать
  • Как посчитать все строки в запросе с SELECT > JOIN > SELECT и LIMIT?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Запрос - какая-то адская фантасмагория. Нахрена здесь джойн, если из а берется только ид, который равен b.meta_value? Я уже не говорю про джойн с селектом и груп бай.
    Такое ощущение, что запрос писал сумасшедший под веществами в состоянии белой горячки.

    все что здесь нужно - это

    SELECT SQL_CALC_FOUND_ROWS b.id, b.meta_name, b.meta_value
    FROM b WHERE b.meta_name = '***'
    ORDER BY b.meta_value DESC
    LIMIT 0, 20;
    SELECT FOUND_ROWS()


    После объяснений в комментах стало понятно, что нам нужен подзапрос

    SELECT SQL_CALC_FOUND_ROWS a.id, 
    (SELECT b.meta_value from b where b.meta_name=a.id order by b.id limit 1) as lastprice
    FROM a LIMIT 0, 20
    Ответ написан
  • RedBeanPHP или PDO для манипуляций с базой данных?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Изучать - сначала PDO, потом RedBean
    Использовать - сразу RedBean
    Ответ написан
    Комментировать
  • Возможно ли создать колонку внутри которой только одна ячейка имеет права содержать в себе значение?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Нельзя.

    В mysqli нет никаких колонок вообще. Это API, набор функций PHP. Его используют самые необучаемые пхпшники, которых отлучили от mysql_query, и которые не сумели освоить ничего более прогрессивного.

    Колонки же есть в БД, которая называется mysql.
    Ответ написан
  • Как запустить межбазовый SQL запрос PHP / PDO?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Объясняю:
    Это не "PDO имеет подключение", а пользователь БД имеет доступ.
    Если указанный при подключении пользователь имеет доступ к некоторой БД, то мы можем выполнять запросы к ней.

    Отсюда можно сделать вывод: Если указанный при подключении пользователь имеет доступ к обеим БД, то такой запрос никакой не извращение, а совершенно стандартный SQL.
    Если же доступ есть к только одной БД, то запрос не пройдет. Опять же, не из-за своей нестандартности, а по банальной причине отсутствия доступа.

    А уж чрез PDO ли мы подключаемся, или через консоль - это уже без разницы.
    Ответ написан
    Комментировать
  • Скорость записи в бд?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Как всегда, милилон ответов, все не в кассу.

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

    mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
    $link->begin_transaction();
    $stmt = $link->prepare("UPDATE `price` SET `price`=? WHERE `name`=?");
    $stmt->bind_param("ss", $price, $name);
    foreach ($jsondate as $k => $value) {
        foreach ($value as $bo) {
            $name = $bo['name'];
            $price = $bo['price'];
            $stmt->execute();
        }
    }
    $link->commit();
    Ответ написан
  • Где взять легковесный Query Builder?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    https://github.com/auraphp/Aura.SqlQuery
    www.notorm.com
    тысячи их

    Для mysqli порекомендую свою SafeMysql
    Если запрос не надо собирать динамически, то код получается куда проще , читабельнее и гибче, чем с любым билдером. Попробуйте к примеру выполнить через fluenpdo запрос insert ignore или on duplicate
    Ответ написан
    3 комментария
  • Правильное написание sql запроса?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Мда, тостер уже не торт.
    Сначала хотел пожурить автора вопроса, но потом увидел, ответы на его предыдущий вопрос...
    Он ведь спрашивал, как защищаться от инъекций. Но в ответ получил только глубокомысленные рассуждения о том, что SQL инъекция без XSS невозможна(!!!).

    В общем используй prepared statements и будет тебе счастье.
    Ответ написан
    2 комментария
  • Почему очень долго выполняеться запрос к БД?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    > Если этот же запрос сделать в phpmyadmin:

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

    Во-первых, phpmyadmin подставляет limit для твоего запроса, и запрашивает всего 20 строк из твоих 100 тысяч. Попробуй запросить все, и посмотри, сколько времени будет выполняться. Если вообще выполнится.
    Во-вторых, даже для запроса с лимитом, 0.0002 -это мало. Результат явно идет из квери кеша. Один раз выполнил, дальше запрос закэшировался, и радостро выдает тупо результат.
    В-третьих, как тут уже все сказхали, делать таблицу на сто тыщ строк - это совсем за пределами осмысленности. Кто будет это читать? Даже если делаешь XLS.

    В общем, сначала изменить, сколкьо времени выполняется запрос ЦЕЛИКОМ, а потом сократить количество запрашиваемых строк до разумных значений.
    Ответ написан
  • Как переменной присвоить столбец?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Такой ерундой никто не занимается.

    Во-первых, $zapros в запросе - это готовая инъекция.
    Во-вторых, распихивать результат по отдельным массивам, это какой-то детский сад. В этом нет ни малейшего смысла, поскольку к любой колонке можно обратиться из единого массива
    foreach ($all as $row) echo $row['Type'];
    foreach ($all as $row) echo $row['Field'];

    В-третьих, если надо получить только один столбец, то тут mysqli как всегда проигрывает PDO:
    $stolbets = $pdo->($query)->fetchAll(PDO::FETCH_COLUMN);
    Ответ написан