Профиль пользователя заблокирован сроком с 10 апреля 2022 г. и навсегда по причине: систематические нарушения правил сервиса
  • Что почитать по составлению безопасных 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.
    - сложные зпросы, группировка данных из нескольких запросов, квери билдеры - в репозитории
    - весь остальной код бизнес-логики, который работает с полученными из БД данными - в хелпере.

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

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

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Смысл этой рекомендации довольно простой - не создавать бандлы просто ради самих себя. Бендл - это самостоятельный модуль, который может использоваться отдельно от других, либо сам по себе, либо как часть различных приложений.

    Соответственно, здесь ключевая фраза - "не могут работать раздельно". То есть это сразу красный свет попыткам разделить. Надо делать все в одном.

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

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    public static function getComments(){
        return DB::getConnection()->query('SELECT * FROM comments')->fetchAll(PDO::FETCH_UNIQUE);
    }
    Ответ написан
    Комментировать
  • Как использовать bind_param в цикле?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Самым простым решением будет переместить заполнение $aStmt в конструктор.

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

    Плюс сам код можно значительно упростить.
    foreach($this->aStmt AS $name => $param){
        $this->aStmt[$name]['stmt'] = $this->oDB->prepare($param['query']);
        $this->aStmt[$name]['stmt']->bind_param($param['paramType']), ...$param['params']);
    }
    Ответ написан
    Комментировать
  • Почему не работает запрос на php + PDO?

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

    > я всегда делаю, чтобы сначала работало, а потом делаю защиту и "секьюрность".

    Придется избавляться от этой дурацкой привычки. Во-первых, это дорога в никуда. С такими идеями твой код всегда будет кривым. Во-вторых, это тупо двойная работа - сначала говнокодить, а потом переписывать набело. И в-третьих, нормальный код проще и удобнее говнокода. Поэтому если не умеешь работать с ПДО - надо учиться. СНАЧАЛА учиться, а потом пытаться что-то писать.

    Файл соединения:
    <?php 
    $serverName = "localhost";
    $userName = "root";
    $password = "";
    $dataBase = "matrix";
    $pdo = new PDO ("mysql:host=$serverName; dbname=$dataBase", $userName, $password);
    $pdo->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );


    "Движок" берем отсюда, https://phpdelusions.net/pdo_examples/password_hash

    $stmt = $pdo->prepare("SELECT login, password, otdel FROM `user_s` WHERE login=?");
    $stmt->execute([$_POST['login']]);
    $user = $stmt->fetch();
    
    if ($user && password_verify($_POST['password'], $user['password']))
    {
        echo "valid!";
    } else {
        echo "invalid";
    }


    Не забыв предварительно хэшировать все пароли перед записью в БД через password_hash.

    А ответ на вопрос, почему у тебя не работает сейчас, можешь прочесть в документации по exec(). Там написано.
    Ответ написан
    1 комментарий
  • Логирование ошибок в файл в веб-приложении -- нормальная практика?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Логировать ошибки вообще - абсолютно нормально.

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

    Не знаю как в ноде, но в РНР движок сам в состоянии находить в коде ошибки и логировать их и без участия программиста. То есть мы пишем просто call function, а РНР сам видит что аргумент не определен, и пишет об этом в лог.

    Код получается ЗНАЧИТЕЛЬНО короче.
    Ответ написан
    Комментировать
  • Почему во всех innodb рекомендуют явно задавать PRIMARY KEY?

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

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

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

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

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Я же давал в прошлом ответе ссылку на чеклист, в котором написано, как правильно работать с транзакциями.

    1. PDO error reporting надо установить на PDO::ERRMODE_EXCEPTION иначе ловить будет нечего
    2. ловить надо Exception, а не PDOException
    3. после отката исключение надо перевыбросить
    4. убедиться что движок БД поддерживает транзакции (например InnoDB)
    5. среди запросов нет такого, который модифицирует стркутуру БД

    Ну и убедись, что в БД у тебя не лежат уже обновленные данные. Потому что в этом случае $Changed законно будет нулем.
    Ответ написан
    2 комментария
  • While не перебирает первый элемент массива php?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Ответ очевиден - перед while ты где то делаешь лишний fetch
    Ответ написан
    Комментировать
  • Как правильно сделать транзакцию PDO в этом случае?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Да, почти все нормально.
    Разумеется все транзакции изолированы друг от друга, в этом их смысл.
    prepare к транзакциям никакого отношения не имеет, и никак на них не влияет.

    Единственное замечание, которое можно сделать,
    echo "Ошибка: " . $e->getMessage();
    выглядит очень по-деревенски.

    Чтобы нормальным образом обработать исключение, его надо перевыбросить, то есть написать
    throw $e;

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

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

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

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

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    > Почему не работает вставка в PDO?

    Этого не знает никто. Кроме твоей БД.
    Поэтому надо спрашивать надо не посторонних людей, а свою базу данных.
    Добавь после коннекта строчку

    $this->link->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );


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

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    $stmt = $pdo->prepare("SELECT 1 FROM table WHERE field=?");
    $stmt->execute($_POST['field']);
    $found = $stmt->fetchColumn();
    if ($found) {
    ...
    Ответ написан
    Комментировать
  • На чем делать бету сайта?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Symfony, только, разумеется, не 2 a 3
    Ответ написан
    Комментировать
  • Как построить сайт с админ панелью на PHP?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Symfony + Sonata Admin
    Ответ написан
    Комментировать
  • Как исправить проблему с INSERT INTO?

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

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

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

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Заканчивалась вторая декада 21 века, а пользователи похапе так и лепили в своем коде тупейшую SQL инъекцию...

    query выкидываем на помойку, вместо этого используем prepare с параметрами, а все переменные отправляем в execute.
    Ответ написан
    Комментировать