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

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    ооооооо! Очередной боретс с ужасными инъекциями применяет секретное хакерское кодирование.
    Ответ написан
  • Как поймать ошибку соединения MySQLi?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Запоминаем волшебную строчку для работы с mysqli:
    mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

    Писать перед коннектом.
    Отлавливает ошибки не только коннекта, но и запросов.

    А функцию error_handler() надо выкинуть - она вредная и ненужная.
    Равно как и идея писать ошибки БД в базу данных.
    Не надо выпендриваться. Пишите в лог как все.
    Ответ написан
    5 комментариев
  • Как узнать, выполнился ли запрос в PDO?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Я спрашивал уже, и спрошу снова: ЗАЧЕМ?

    Зачем ты хочешь проверять успешность выполнения запроса и что ты потом будешь с этим сакраментальным знанием делать?

    Кстати,
    (при UPDATE, INSERT и т.д.)

    Как я уже писал, при UPDATE, INSERT и т.д. твоя функция всегда будет выдавать ошибку. Можно даже не проверять
    Ответ написан
    Комментировать
  • Как сортировать многомерный массив в php?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    php.net/usort - функция для сортировки чего угодно как угодно.

    А вообще данные надо сортировать в базе.
    Ответ написан
  • Как заполнить форму на другом URL?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    нужен подобный «тестер»

    Не нужен. Это бессмысленная проверка.
    Без всякого теста и так очевидно, что бот зарегистрируется.
    Ответ написан
    Комментировать
  • Возможно ли изменить информацию о песне (mp3) PHP?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    google.com/search?q=php+mp3

    Во всех современных браузерах можно не писать адрес сайта а просто вбить в адресную строку два слова: php mp3
    Для более точноно поиска можно добавить третье слово, "запись"

    Не благодарите.
    Ответ написан
    Комментировать
  • Как трансформировать текст более коротко?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Задачу не понял от слова совсем, но если отталкиваться от условия "кодировать покороче", то можно сделать так:
    function incode($string) {
    	return $string;
    }

    вместо 108710881080108410771088 вернёт "пример" - в 2 раза короче.
    Ответ написан
  • Как в 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 комментарий
  • Где найти официльное описание display_template(ссылку бы)?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Спрашивать надо свой собственный код.
    Поиском по файлам подстроки "function display_template" найдется за пару секунд
    Ответ написан
    Комментировать
  • Книги по php с описанием работы с PDO и SQLite на русском языке?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    По SQLite не нужна книга, если планируется использовать PDO. Там, где есть PHP, всегда есть и нормальная база данных, и нет смысла пользоваться игрушечной.

    По PDO не нужна книга, поскольку это очень маленький API, буквально из 5 функций.
    Всё что нужно знать про PDO:

    1. Любые переменные должны попадать в запрос только через плейсхолдер. Поэтому все запросы, в которых участвуют переменные, должны выполняться через prepare/execute: сначала запрос подготавливается через prepare(), причем вместо переменных должны стоять плейсхолдеры, такие ? или такие :name. А переменные потом передаются через execute.
    $pdo  = new PDO ( ... );
    $stmt = $pdo->prepare("SELECT * FROM users WHERE id=?");
    $stmt->execute([$_GET['id']]);
    $user = $stmt->fetch();

    2. Для получения данных есть три функции
    - fetch() получает строку. аналог mysql_fetch_array()
    - fetchAll() получает массив строк. Синтаксический сахар для while ($row = mysql_fetch_array()) (эта функция, кстати - единственная, по которой стоит почитать мануал. у неё есть несколько интересных кунштюков)
    - fetchColumn() - синтаксический сахар для $row = mysql_fetch_row(); $flag = $row[0]

    3. Все остальные тонкости и нюансы описаны по-русски здесь: www.phpfaq.ru/pdo

    4. Особые надстройки над PDO не нужны, но иногда хочется исправить пару неудобных вещей. Например, с помощью www.phpfaq.ru/pdo_wrapper код из п.1 сократится до одной строчки (причем код будет работать отовсюду и сразу):
    $user = DB::run("SELECT * FROM users WHERE id=?", [$_GET['id']])->fetch();

    5. По любым другим вопросам можно спрашивать меня
    Ответ написан
    Комментировать
  • Как внести изменения записи в БД, на SQL PHP?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Покажи человеку, который писал этот код, вот эту ссылку: phpfaq.ru/debug
    Пусть прочтет и попытается понять.
    Ответ написан
  • Не работает подключение файлов в PHP. Как настроить?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Начинающим пользователям действительно бывает сложно понять концепцию файловой системы, иерархических каталогов, понятие текущего каталога и отличие относительного пути от абсолютного.
    Рекомендую почитать вот это: phpfaq.ru/paths

    Для данного случая может помочь путь
    $_SERVER['DOCUMENT_ROOT'].'/ext/mail/PHPMailerAutoload.php';

    впрочем, гарантировать нельзя, поскольку мы не знаем, где лежит папка ext

    Подсказка на будущее:
    Сообщение об ошибке надо приводить сразу. И целиком.
    Ответ написан
    Комментировать
  • Как посчитать количество запросов к базе данных?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Учитывая, что цифра совершенно бессмысленная, проще всего будет сделать
    echo rand(10, 15);
    Ответ написан
    3 комментария
  • Предотвратить SQL Injection без использования bindParam?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    С помощью небольшой магии и короткого синтаксиса код можно еще больше сократить
    $sql = 'SELECT * FROM users WHERE email = ?';
    $rows = $db->prepare($sql)->execute([$email])->fetchAll();
    Ответ написан
    Комментировать
  • Могут ли возникнуть дубли хешей?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Решение отвратительное. Это уже что-то из серии про архиватор Бабушкина.

    Ну разумеется, коллизии будут.

    Лучше оставить MD5 (у которого вероятность коллизий вполне в пределех допустимого), но перевести его из неэффективного base16 в более короткую форму. Base64 вполне подойдёт, поскольку кодировщик есть в пхп из коробки. Вот только оба не буквенно-цифровых символа там не подходят для передачи через урл - лучше их заменить:
    $base64 =  substr(strtr(base64_encode(hex2bin($md5)),'+/',"_-"),0,-2);

    Итого экономим 10 символов из 32-х. Конечно, 22 хуже чем 8, но тут надо выбирать - или достаточная длина, или коллизии и отсутствие безопасности вообще.
    Ответ написан
    Комментировать
  • PDO PHP как убрать экранирование в запросе?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    А теперь, по традиции, правильный ответ, от единственного здесь человека, который видел PDO, а не просто слышал краем уха, что пацаны на раёне рассказывали.

    $dbh = new PDO(
    	"mysql:host=$db_host;dbname=$db_name;charset=$db_charset",
    	$db_user,$db_pass, array(
    		PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    		PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_OBJ
    	));
    $sql  = "SELECT * FROM files WHERE name = '/var/www/test/1.txt'";
    $data = $dbh->query($sql)->fetchAll();

    при появлении ошибки - прочесть и исправить.

    Да - и, разумеется, никакого "экранирования" PDO в "запросах" не делает. И поэтому убирать ничего не нужно. Рекомендую применять фантазию при общении с противоположным полом. А в программировании старайтесь придерживаться фактов. И начинать избавляться от любого экранирования следует только после того, как увидели его собственными глазами.
    Ответ написан
    2 комментария
  • Почему не работает функция foreach c PDO?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Прекрасный, прекрасный пример того, что такое эти Q&A сайты.
    Ну неужели жалкий ручеек тафика, состоящего из убогих и ламеров всех мастей, стоит того, чтобы терпеть это позорище?

    Вопрос, который к ПДО имеет такое же отношение, как я - к балету, и - самое главное - ответы, прекрасно описываемые анекдотом про Вовочку "Я, конечно, не профессор..."

    Вопрос, код в котором принципиально не будет работать, поскольку аффтару надо либо крестик снять, либо трусики надеть, и опеределиться - нечеткое у него сравение (и добавить LIKE) или четкое (тогда убрать процентики).

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

    Ну и вишенка на торте - совершенно детская причина всех страданий - коварные переводы строк, возвращаемые file() по умолчанию.
    Ответ написан
    Комментировать
  • Как правильно проиндексировать longtext в mysql?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Ответ очевиден:

    Чтобы отсортировать числовые значения, их надо записывать в колонку числовогго типа.

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

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

    В этом случае БД для поддержания уникальности действительно не нужна, но вот для привязки картинок к сущностям писать всё-таки придётся.

    Я только не понял, при чем здесь кэширование
    Ответ написан
    Комментировать
  • Как правильно писать php вставки в tpl файлах?

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

    Единственный нормальный ответ здесь - от lexxpavlov, с которым я могу только согласиться по всем пунктам:
    - Oбъединять РНР операторы нельзя. Это нарушает сематическую корректность шаблона. Вместо простого и легко формализуемого синтаксиса мы получаем кашу.
    - Заменять ?= на php echo не нужно - это абсолютно бессмысленная трата символов.
    - поигравшись с native php следует перейти на twig, в котором одни только наследование и автоискейпинг заменят тонну говнокода на нативном пхп.

    Остальные же ответы здесь - воспалённые фантазии, не имеющие никакого отношения к реальности. Никаких проблем <?= тег не создаёт.
    Ответ написан
    1 комментарий