Задать вопрос
@gachkydxvbgd

Как безопаснее PDO?

echo $db->insert("INSERT INTO test (gaga) VALUES (:gaga)" , array('gaga'=>'test'));
        public function insert($query, $params){
            try{ 
                $stmt = $this->datab->prepare($query); 
				    while (list($key, $value) = each($params)) { 
                    unset($arr[$key + 1]); 
	                $stmt->bindValue(":$key", $value);
                } 
				$stmt->execute();
                return $this->datab->lastInsertId();
                }catch(PDOException $e){
                throw new Exception($e->getMessage());
            }
        }


или

$db->insert("INSERT INTO user (login, password, email) VALUES (?, ?, ?)", array($_POST['login'], $pw->gen($_POST['password']), $_POST['email']));
        public function insert($query, $params){
            try{ 
                $stmt = $this->datab->prepare($query); 
                $stmt->execute($params);
                return $this->datab->lastInsertId();

                }catch(PDOException $e){
                throw new Exception($e->getMessage());
            }
        }
  • Вопрос задан
  • 281 просмотр
Подписаться 2 Оценить 1 комментарий
Помогут разобраться в теме Все курсы
  • Skillbox
    Веб-разработчик на PHP
    9 месяцев
    Далее
  • Хекслет
    PHP-разработчик
    10 месяцев
    Далее
  • Нетология
    Веб-разработчик с нуля: профессия с выбором специализации
    14 месяцев
    Далее
Пригласить эксперта
Ответы на вопрос 2
index0h
@index0h
PHP, Golang. https://github.com/index0h
Ни первое, ни второе.

0. SQL запросу ну вот ни как не место в аргументах, это то, что должен делать ваш insert метод. Все что он должен получать - это аргументы которые будут вставляться в ваш запрос!
1. Вы не проверяете аргументы. Что произойдет, если я вызову insert:
$db->insert(new \Exception(), []);
Или так
$db->insert("DELETE FROM user", []);
Или так (тут lastInsertId вернет не id вставки)
$db->insert("SELECT CURRENT_TIMESTAMP", []);
2. Никогда, слышите? НИКОГДА! Не используйте при работе с БД суперглобальные переменные. Их удел - в самом начале index.php собрать объект Request, далее про их существование можно забыть.
3. datab обычно называются connection, либо по типу класса
4. В следующем коде нет смысла, от слова "совсем"
}catch(PDOException $e){
                throw new Exception($e->getMessage());

Вы просто обрубаете стектрейс, который далее стоит использовать для поиска ошибок.
5. У вас ключи строковые, зачем вот это?
unset($arr[$key + 1]);
6. Если в params передать [[]], как себя поведет ":$key"?
7. lastInsertId возвращает строку, кастовать в ваш тип не помешает.
8. Ради всего святого: прочитайте и следуйте PSR

Вот вам пример безопасного кода. Проверок в реальном коде должно быть на много больше:
* логин стоит прогнать по регулярке на допустимые символы
* почту стоит прогнать по регулярке, или через filter_var
* что пароль таки хэш (смотря какой алгоритм используете)
* если будут еще поля не строковых типов - их подключаем через bindValue с указанием типа
Тут сделано допущение, что подключение PDO уже настроен на бросание ошибок. В задачи репозитория не входит конфигурирование коннекшна.
По хорошему это дело еще и в транзакцию обернуть.
<?php
declare(strict_types = 1);

class UserRepository
{
    /** @var \PDO */
    private $pdo;

    /**
     * @param PDO $pdo
     */
    public function __construct(\PDO $pdo)
    {
        $this->pdo = $pdo;
    }

    /**
     * @param string $login
     * @param string $email
     * @param string $password
     * @return int
     * @throws \InvalidArgumentException
     * @throws \PDOException
     */
    public function insert(string $login, string $email, string $password): int
    {
        if (empty($login)) {
            throw new \InvalidArgumentException('Argument "$login" must be not empty');
        } elseif (empty($email)) {
            throw new \InvalidArgumentException('Argument "$email" must be not empty');
        } elseif (empty($password)) {
            throw new \InvalidArgumentException('Argument "$password" must be not empty');
        }

        $sql = '
        INSERT INTO `user`(
            `login`,
            `email`,
            `password`
        ) VALUES (
            :login,
            :email,
            :password
        )';

        $this->pdo->prepare($sql)->execute(
            [
                ':login' => $login,
                ':email' => $email,
                ':password' => $password
            ]
        );
        
        return (int) $this->pdo->lastInsertId();
    }
}
Ответ написан
Комментировать
@Jekshmek
кодер штродер
Могу добавить.Подготавливать запрос на каждую вставку не совсем экономично.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы
FoodSoul Калининград
от 180 000 до 250 000 ₽
IT-Spirit Москва
от 230 000 до 320 000 ₽
IT ATLAS Москва
от 250 000 до 500 000 ₽