Профиль пользователя заблокирован сроком с 26 октября 2019 г. и навсегда по причине: систематические нарушения правил Сервиса
  • Как в PDO значение LIMIT при запросе сделать INT?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Хороший вопрос. Как раз показывает убогость стандартной системы плейсхолдеров.
    В моей библиотеке для работы c MySQL тип указывается самым простым и эффективным способом - прямо в плейсхолдере:
    //первый запрос (лимит здесь не нужен)
    $id = $db->getOne("SELECT id FROM users WHERE mail = ?s AND pass = ?s", $mail, $pass);
    // второй запрос
    $sql  = "SELECT id, name FROM news WHERE category = ?s AND subcategory = ?s LIMIT ?i";
    $news = $db->getIndCol('id', $sql, $cat, $subcat, $limit);

    Как видно из этих примеров, тип ставится в самом плейсхолдере и все входящие данные обрабатываются корректно.

    Вернемся теперь к несчастному PDO.
    Цикл с подстановкой в bindParam?

    Цикл, увы, не поможет. Потому что мы не знаем, какой тип использовать для привязки. То есть, все сведется к дефолтному PARAM_STR и в итоге мы получим то же самое execute() с массивом, только в профиль.
    Если вдруг возникнет идея определять тип по составу переменной, то делать это НИ В КОЕМ СЛУЧАЕ НЕЛЬЗЯ. Если бы мог, я бы выделил ещё большим шрифтом и красным цветом. Потому что практически каждый продвинутый пользователь похапе рано или поздно наступает на эти грабли. Если число, хранящееся в MySQL, всегда можно безопасно сравнивать со строкой, то наоборот - это будет катастрофа: MySQL будет пытаться привести содержимое поля к числу. То есть, если взять пример из вопроса, и пытаться определить тип привязки по содержимому переменной, то при введенном пароле 12345 ctype_digit() скажет нам использовать INT и в итоге пароль 12345 подойдет к любому паролю вида "12345буквы".
    Так что цикл - не вариант.

    Я читал, что можно еще отключить режим эмуляции, но я не знаю, как это повлияет на безопасность

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

    Так что либо в параметрах DSN, либо с помощью
    $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, FALSE);

    отключаем эмуляцию и наслаждается лимитом (правда, в этом случае перестанет работать такая фича, как несколько именованных плейсхолдеров с одним и тем же именем, но тут уж приходится выбирать).

    И последнее замечание.
    Функцию для выполнения запросов писать в общем-то нет смысла. PDO достаточно лаконичен и сам по себе. Единственное, что мешает писать однострочники - это дурацкая execute(), которая возвращает не себя, а булево значение. Но это легко исправить, и в итоге код получится ненамного длиннее, чем при вызове функции, но гораздо более гибким (ненавижу скроллинг, поэтому выношу параметры на другие строчки):
    // с функцией
    $sql   = 'SELECT `user_pass` FROM `users` WHERE `user_mail` = :mail LIMIT :lim';
    $param = array(':mail' => 'vlad-dub1994@mail.ru', ':lim' => 1);
    $data  = select($sql,$data);
    // с патченым PDO
    $data = DB::prepare($sql)->execute($data)->fetch();
    
    // или другой вариант записи
    $data = DB::prepare('SELECT user_pass FROM users WHERE user_mail = :mail LIMIT :lim')
    	->execute([':mail' => 'vlad-dub1994@mail.ru', ':lim' => 1])
    	->fetch();

    Всего на пару слов больше, но зато можно исполнять любые запросы (INSERT к примеру):
    $sql   = 'INSERT INTO users VALUES(?,?,?)';
    $param = array(NULL, 'vlad-dub1994@mail.ru', 'pass');
    DB::prepare($sql)->execute($data); //OK
    select($sql,$data); // ошибка из-за fetch()

    и использовать любые варианты получения данных, которые поддерживает PDO:
    $sql = 'SELECT id FROM tree WHERE parent_id=?';
    $subcat = DB::prepare($sql)->execute([$parent])->fetchAll(PDO::FETCH_COLUMN);
    Ответ написан
    1 комментарий
  • Для чего нужно использовать парметр PDO::PARAM_INT в функции bindParam() ?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Для начала ответим на вопрос буквально:

    конечно же, в настройках соединения прописано
    PDO::ATTR_EMULATE_PREPARES => false
    В этом случае - вообще незачем.
    Если эмуляция отключена, то можно вообще никогда не указывать тип.

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

    И вот если эмуляцию включить, то как раз и возникнет единственный случай, когда придется биндить с указанием типа: если у тебя в запросе передаются параметры в LIMIT. Если в запросе есть оператор LIMIT и в него передаются параметры, то их надо обязательно биндить через PDO::PARAM_INT - иначе запрос выдаст ошибку.
    Мало того - передаваемые данные надо самостоятельно привести к типу int - PDO это за тебя делать не будет!

    Теперь ответим в общем, объясняя твои многочисленные заблуждения:

    1. Как тебе уже объяснили выше, инъекция - это не про сохранение в базе. Это именно про выполнение запроса. Так что тип поля в БД не имеет значения.
    2. Инъекцию через PDO провести нельзя только если на 100% соблюдается условие "любые данные попадают в запрос только через плейсхолдеры" - просто самим фактом своего присутствия PDO ничего ни от кого не защищает. Кстати, соблюдение этого правила не так просто, как кажется. Решение для большинства нетривиальных случаев можно посмотреть здесь: phpfaq.ru/pdo
    3. Самое важное: если мы используем плейсхолдеры, то все остальное уже неважно. Указывай какой хочешь тип, или не указывай вовсе - инъекции не будет. То есть, к безопасности твой вопрос про указание типа отношения не имеет.
    4. Если ты не указал тип, то по умолчанию берется PDO::PARAM_STR. Это очень удобно, поскольку БД (по крайней мере - mysql) всегда корректно обработает любые данные, если они переданы, как строки

    Так что, я думаю, что ты теперь и сам можешь ответить на вопрос, "зачем указывать тип".
    И будешь писать просто
    $sth = $dbh->prepare('SELECT * FROM fruit WHERE calories < ? AND colour = ?');
    $sth->execute([$_POST['calories'],$_POST['colour']]);
    Ответ написан
    1 комментарий
  • Как сделать проверку хэш пароля (password_hash) с базы данных?

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

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

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    А вы цвета различаете? Даже здесь в тексте вопроса ошибка хорошо выделяется - во второй строке не закрыты кавычка и скобка.
    Ответ написан
    5 комментариев
  • Flexbox vs float?

    dom1n1k
    @dom1n1k
    По поводу того, что flex лучше всегда - это конечно чушь. Есть много простых ситуаций, когда он не дает никакого профита, тогда как старый добрый float решает проблему целиком. Флекс, конечно, тоже решит - но с побочными эффектами в виде неполной кроссбраузерности.
    Предложения при этом делать фоллбеки на флоатах умиляют - если всё равно их делать, так не проще ли ими и ограничиться?!

    В итоге, ответ на вопрос очень простой - flex нужно использовать там, где он дает конкретные преимущества. Самое очевидное - нужно автораспределение ширины блоков с подстройкой к ширине контента. Или вам нужно менять порядок блоков (свойство order).
    Если ничего этого не планируется - flex не нужен! Сейчас уже наплодили сеток и "фреймворков", где flex используется фактически для имитации float-ов! Ну типа же стильно, модно, молодежно. Я ж крутой разработчег, не хухры-мухры.

    При верстке каждого блока нужно задавать себе вопрос: "я использую flexbox, чтобы что?" Если на вопрос есть четкий ответ - да, нужно использовать. Если только бла-бла типа "ну это современно, прогрессивно и пр" - использовать старые железобетонные приёмы.
    Ответ написан
    7 комментариев
  • Что за марка ip-видеокамер на фото?

    NeiroNx
    @NeiroNx
    Программист
    С проводками - HikVision DS-T251
    без проводков HikVision DS-2CD2443G0-IW
    Ответ написан
    1 комментарий
  • Где выгоднее регистрировать ИТ-организацию в России, чтобы не сильно попадать под налог?

    SagePtr
    @SagePtr
    Еда - это святое
    За пределами РФ. И себя тоже лучше всего эвакуировать подальше от РФ.
    Ответ написан
    1 комментарий
  • Как переделать этот код?

    @archelon
    возьмите кнопки лайкли
    https://ilyabirman.ru/projects/likely/
    их несложно темизировать под себя
    Ответ написан
    1 комментарий
  • Какую CMS выбрать для интернет-магазина с 5к товарами с дальнейшими возможностями расширения?

    Sanes
    @Sanes
    Битрикс конечно. Если вам работать надо, а не страдать с велосипедами. Я бы еще посмотрел CS-Cart.
    Ответ написан
    Комментировать
  • Чем больше пользуетесь при разработке приложения под андроид - эмулятором или реальным телефоном?

    zagayevskiy
    @zagayevskiy Куратор тега Android
    Android developer at Yandex
    Эмулятором пользуюсь только в крайнем случае. Тормозит, грузит систему, тупит. Реальный девайс лучше. То что говорят про версии апи и прочий булшит - фигня. Эмулятор почти никогда не выявит реальных проблем, тк они чаще не апи-специфичные, а производителе- и девайсо-специфичные.
    Ответ написан
    Комментировать
  • Где найти эту иллюстрацию?

    pozZzitiv
    @pozZzitiv Куратор тега Дизайн
    Дизайнер и перфекционист
    Данная иллюстрация, скорее всего, была заказана какому-то конкретному иллюстратору с передачей прав (фрилансеру или штатному в офисе). Такое в принципе дешевле для производителя, чем покупка на стоках, где количество тиража напрямую влияет на стоимость лицензии.
    Точно также работают производители всего, на чем можно напечатать изображение — постельное, покрывала и прочие ткани, посуда и т.п. Это просто экономически выгоднее когда сделанное сразу принадлежит только тебе.

    По стилистике работы тоже похоже на ассортимент магазина "все для дома". Ну и тот факт, что на стоках его не нашли (я тоже попытался поискать через сервисы и Гугл) добавляет плюсов к моей версии. То что есть десятки сайтов по продаже картин говорит о том, что сайты в итоге обращаются к одному печатнику, который по заказу печатает и передает (вы же не думаете, что у каждого сайта там своя типография и производство, правда?).

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

    @IceJOKER
    Web/Android developer
    Ответ на все ваши вопросы - Услуги фрилансера, готовьте $$

    Это сайт, где задают конкретный вопрос, а не просят за вас что-то делать! Для этого дела заказываете услуги программиста за $$ или обращаетесь на форму, или сами учите!
    Ответ написан
    3 комментария
  • Где найти команду для разработки?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Нигде.
    Никогда.
    Деда Мороза и Зубной феи тоже не существует. Это мама тебе покупает подарки под ёлку и за выпавший зуб.
    Ответ написан
    Комментировать
  • Как сделать из обычного фото вот такое на css?

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

    php666
    @php666
    PHP-макака
    гради буч объектно-ориентированный анализ и проектирование скачать бесплатно
    Ответ написан
    Комментировать
  • Правильно ли написана ли функция mail()?

    opium
    @opium
    Просто люблю качественно работать
    Так просто запустите и проверьте это по секунд займет, вы вопрос писали дольше
    Ответ написан
    Комментировать
  • Как понять что я гов*окодер?

    SilenceOfWinter
    @SilenceOfWinter
    та еще зажигалка...
    ты говнокодер судя по куче слов и 0 кода
    Ответ написан
    6 комментариев