• Call to undefined function checkFields(), как исправить?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Возможно, речь идет о коде, который я как-то на ходу сочинял здесь для кого-то.
    Только понятное дело, весь смысл давно улетучился, и остался голимый, эталонный карго-культ, самолеты из соломы.

    Там шла речь о примитивном ORM по паттерну Table Gateway, чтобы упростить и обезопасить базовые CRUD операции.

    abstract class BasicTableGateway
    {
        protected $db;
        protected $table;
        protected $fields;
        protected $primary = 'id';
    
        public function __construct(\PDO $db)
        {
            $this->db = $db;
        }
        public function read($id): ?array
        {
            $stmt = $this->db->prepare("SELECT * FROM `$this->table` WHERE `$this->primary`=?");
            $stmt->execute([$id]);
            return $stmt->fetcn();
        }
        public function insert($data): int
        {
            $this->checkFields($data);
    
            $fields = '`'.implode("`,`", array_keys($data)).'`';
            $placeholders = str_repeat('?,', count($data) - 1) . '?';
    
            $sql = "INSERT INTO `$this->table` ($fields) VALUES ($placeholders)";
            $this->db->prepare($sql)->execute(array_values($data));
    
            return $this->db->lastInsertId();
    
        }
        // и так далее
        protected function checkFields($data)
        {
            $diff = array_diff(array_keys($data), $this->fields);
            if ($diff) {
                throw new \InvalidArgumentException("Unknown field(s): ". implode($diff));
            }
        }
    }


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

    class UserGateway extends BasicTableGateway {
        protected $table = 'gw_users';
        protected $fields = ['email', 'password', 'name', 'birthday'];
    }
    $userGateway = new UserGateway($pdo);
    
    $data = [
        'email' => 'foo@bar.com',
        'password' => 123,
        'name' => 'Fooster',
    ];
    $id = $userGateway->insert($data);


    Получается быстро удобно и безопасно.

    Но в текущем варианте удобство, осмысленность и безопасность улетучились, остались только какие-то невнятные идеи.
    Ответ написан
    2 комментария
  • Как при работе с MongoDB стандартизировать коллекции?

    ipatiev
    @ipatiev
    Потомок старинного рода Ипатьевых-Колотитьевых
    Да, принято. Без этого, фактически, с Монгой вообще работать невозможно.
    Больше того, учитывая, что (в отличие от нормальных баз данных) имена ячеек всегда хранятся вместе с данными (то есть дублируются столько раз, сколько документов хранится базе), то у монгеров принято давать ключам имена из одной-двух букв для экономии памяти. И эти сокращения тоже надо потом транслировать в человеческие имена. То есть база данных для работы с базой данных становится не прихотью, а жизненной необходимостью.

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

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

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

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Пользовательские функции в языках программирования служат для двух целей:
    - для того чтобы избежать дублирования кода при частом повторении одних и тех же операций
    - для того чтобы код был лучше структурирован, и как следствие - легче читался и его было удобно поддерживать. Когда у нас внутри условия if написано 50 строк кода, это неудобно читать и сложно редактировать. Когда внутри этого же условия всего один вызов функции, то это легко читается, и легко можно заменить на другую функцию.

    Функции-хелперы обычно относятся к первой категории. Их традиционно пишут в отдельном файле, который подключается к коду проекта.
    Ответ написан
    Комментировать
  • Как бороться с рекламой в письмах при отправке формы?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Голова дана человеку не только для того, чтобы в неё есть.
    А код рекаптчи надо не просто добавить в файл, но ещё и как-то использовать

    В своем коде вы получаете $response, но никак не используете. Не останавливаете отправку письма при неверном вводе капчи. А просто продолжаете выполнение кода, который отправляет письмо в любом случае.
    Ответ написан
    Комментировать
  • Как изменить названия файлов на нормальные после распаковки архива?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    В общем если я правильно понимаю, вам приходят как архивы, как сделанные под виндоус, с именами файлов в кодировке 1251 - и они распаковываются под виндоус правильно, так и сделанные под нормальными операционными системами, и в них имена закодированы в утф-8
    Если у вас есть возможность определять, где был сделан файл, то можно использовать эту информацию при перекодировании.

    Ну или тупо в лоб - искать в имени файлов русские буквы в той или иной кодировке, например 1251. То есть символы с кодами B0-EF. Если не встретились - перекодировать из утф в 1251
    Ответ написан
  • Как устранить Undefined array key после назначения переменных через explode()?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    На "западном аналогичном этому сайте" только что случайно наткнулся на красивое решение.
    $arrdata = array_pad(explode('|', $file[0]), 666, '');

    где 666 - это количество колонок, которое должно быть после explode.
    array_pad добьёт их пустыми строками. можно поставить нули при желании.
    Ответ написан
    22 комментария
  • Генератор случайного числа с отправкой на почту?

    ipatiev
    @ipatiev
    Потомок старинного рода Ипатьевых-Колотитьевых
    У вас вопрос буквально уровня
    "Надо в понедельник пойти на алгебру, во вторник на литературу, а по пятницам на обж. Может кто сталкивался с таким???"
    Никаких "вариантов" тут встречать не надо. Если человек в принципе умеет ходить, и знает что такое алгебра с литературой.

    Вы вообще в состоянии понять, что это три разных действия, а не одно?
    Сгенерировать число, отправить письмо, и наладить регулярный запуск. Все три совершенно примитивные, и по каждому есть миллиарды примеров в интернете.
    Какая проблема взять пример для каждого и соединить?
    Ответ написан
    Комментировать
  • Как исправить Fatal error: Uncaught Error: Call to undefined function mysql_fetch_assoc()?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    поменять на mysqli_fetch_assoc
    а, не
    поменять на какое-то $obj_sql->FetchAssoc()
    Ответ написан
    Комментировать
  • Как сформировать запрос?

    ipatiev
    @ipatiev
    Потомок старинного рода Ипатьевых-Колотитьевых
    У меня получилось как-то так
    select sum(o.sum), sum(fsum) from orders o left join 
    (select order_id, sum(price) fsum from foodcost where order_id in (1,2) group by order_id) t
    on o.id=t.order_id 
    where o.id in (1,2);

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

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    ;charset=utf8mb4 в DSN
    Ответ написан
    Комментировать
  • Можно ли индексировать varchar в mysql?

    ipatiev
    @ipatiev
    Потомок старинного рода Ипатьевых-Колотитьевых
    Можно
    Ответ написан
    Комментировать
  • Поиск строк в большом файле?

    ipatiev
    @ipatiev
    Потомок старинного рода Ипатьевых-Колотитьевых
    В данном случае искать быстрейшее решение будет заведомо дольше, чем просто использовать самое простое. Пока будешь бегать по инету, оно уже 10 раз все найдет.

    Чем не устроило сделать просто в лоб grep -f search.txt gigaz.log ?
    Ответ написан
    Комментировать
  • Чистый php, если нет Бд, то можно ли её создать?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Можно, но код, который создает БД при ошибке - это глупость.
    Так не делают.

    Можно создать отдельный скрипт для настройки окружения, который создаст БД и таблицы например.
    В этом скрипте просто не указывать 4-й параметр в mysqli_connect.
    И дальше просто написать mysqli_query() c запросом создания таблицы.

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

    spoiler
    И отучайтесь уже писать этот говнокод, or die("Ошибка соединения с БД." . mysqli_error($link));
    он и так-то всегда был признаком профнепригодности, а в современном РНР уже и вовсе не имеет смысла
    Ответ написан
    5 комментариев
  • Как сделать безопасный "Запомнить меня" на сайте?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Сгенерировать сильно уникальный токен, что-нибудь вроде random_bytes(16), положить его в БД и в куки

    > Как предотвратить несанкционированную авторизацию на случи, если у пользователя украдут cookie?

    Никак. В принципе, вся безопасность современного веба завязана на предположении, что куки не украдут. В супер-важных приложениях, типа банковских, можно дополнительно проверять IP адрес, его подделать невозможно. И при смене адреса просить перелогиниться. Но в обычном приложении это будет скорее неудобством.

    > Как идентифицировать его, что куки используется не на другом устройстве?

    Ну можно по идее запоминать устройство, по user agent. Но это придется отдельно хранить авторизации на всех устройствах. Но если покрадут куки, то уведут и юзер агент.

    Причем все это относится и к обычной авторизации, без функции "Запомнить меня". Так что если эти вопросы до сих пор вас не волновали, то и сейчас по идее не должны.
    Ответ написан
    1 комментарий
  • В запросе SQL в php условия в кавычках как?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Никогда не понимал любителей ломать пальцы обо все эти точечки-кавычечки-запяточечки. Это же надо так запариться, старательно после каждого слова выписывая пунктуацию. Есть же нормальные двойные кавычки.
    "mysqldump -u$user -p$password --single-transaction --force --opt --where 'ENTITY_FIELD = STATUS_ID AND ASSIGNED_BY_ID >0' $database $table > relations.sql"
    Ответ написан
  • Как перейти на другой сайт с POST запросом?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Это называется Межсайтовая подделка запросов и ни один нормальный банк не даст ее сделать.
    А так -то отправлять форму яваскриптом, ничего экстраординарного.
    Ответ написан
  • Нужна ли математика Python,Java программисту?

    ipatiev
    @ipatiev
    Потомок старинного рода Ипатьевых-Колотитьевых
    Нужна ли математика Python,Java программисту?

    Сама по себе может не понадобиться, но тот факт что вы задаете этот вопрос, говорит о том что программист из вас скорее всего получится никудышный

    мелкий опыт в Питоне смогу ли я с такими стеком знаний получить работу Python или Java разработчик?

    Нет, разумеется
    Ответ написан
    Комментировать
  • В чем разница обычного импорта и обращение с косой чертой?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Комментировать
  • Как типизировать ключ и значение массива?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Типизировать ключи особого смысла нет, а для значений/структуры массива нативного решения нет, надо делать руками.
    Если под "типизацией ключей" имеется строго определенный набор ключей, то это называется DTO/ValueObject. То есть тупо вместо массива используется объект, в котором структура его свойств может быть четко определена.

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

    ipatiev
    @ipatiev
    Потомок старинного рода Ипатьевых-Колотитьевых
    Я тоже долго тупил, но потом понял. Скорее всего, человеку требуется аналог fetch_assoc в РНР. То есть словарь, в котором уже есть имена полей, которые не нужно будет писать руками.
    sqlite_connection = sqlite3.connect('sqlite_python.db')
    sqlite_connection.row_factory = sqlite3.Row
    cursor = sqlite_connection.cursor()
    sqlite_select_query = """SELECT * from sqlitedb_developers"""
    cursor.execute(sqlite_select_query)
    records = cursor.fetchall()
    records = [dict(row) for row in records]
    print(records)

    В итоге получится это самое загадочное "все получить одним returnprint" без цикла.
    Ответ написан