Профиль пользователя заблокирован сроком с 10 апреля 2022 г. и навсегда по причине: систематические нарушения правил сервиса
Ответы пользователя по тегу PHP
  • Как лучше хранить спец цены если их 1000 для каждого клиента?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    каждая цена в отдельном поле
    это даже не обсуждается
    купи себе наконец учебник по базам данных
    Ответ написан
    Комментировать
  • Класс для работы с PDO?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Ну конкретно этот кривоват, и не реализует все возможности PDO.
    Навскидку:
    - exit('Error connecting to database: ' . $e->getMessage()); - это позор
    - self::$sth - бессмыслица
    - function getAll - делает обрезание оригинальному методу ПДО, который умеет возвращать данные в десятках различных форматов
    - function getValue - стыд, автор не знает что в ПДО есть готовая функция для этого.

    Если говорить о таких вот одностраничниках, то я бы рекомендовал попытаться напистаь своё.
    Но судя по всему, это для тебя задача неподъемная.
    В таком случае, на твоем месте я сначала поучился работать с ванильным PDO. Это реально важно. Это надо обязательно сделать перед тем как начинать использовать всякие обертки. чтобы понимать хотя бы примерно что они там внутри себя делают. А после этого все-таки писал бы свой класс.

    В крайнем случае, ограничился бы функцией-хелпером:

    function pdo($pdo, $sql, $args = NULL)
    {
        $stmt = $pdo->prepare($sql);
        $stmt->execute($args);
        return $stmt;
    }


    Ключевое слово здесь - return $stmt;. Оно позволяет работать с результатом запроса.

    // узнать количество строк
    $count = pdo($pdo, "SELECT count(*) FROM users WHERE role=?",[$role])->fetchColumn();
    
    // получить юзера по адресу
    $user = pdo($pdo, "SELECT * FROM users WHERE email=?", [$email])->fetch();
    
    // тупо запросить массив строк
    $data = pdo($pdo, "SELECT * FROM users WHERE salary > ?", [$salary])->fetchAll();
    
    // получить количество удаленных строк 
    $deleted = pdo($pdo, "DELETE FROM users WHERE id=?", [$id])->rowCount();
    
    // вставка
    pdo($pdo, "INSERT INTO users VALUES (null, ?,?,?)", [$name, $email, $password]);
    
    // получить массив строк в виде ключ-значение
    $indexed = pdo($pdo, "SELECT id, name FROM users")->fetchAll(PDO::FETCH_KEY_PAIR);


    Если же хочется чтобы прям как у больших пацанов, но не такое зубодробительно сложное, то https://github.com/auraphp/Aura.Sql
    Ответ написан
    Комментировать
  • Как спарсить из файла конкретную строку?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    "Конструкция if является одной из наиболее важных во многих языках программирования, в том числе и PHP."
    Ответ написан
    2 комментария
  • Как в переменную внести другую переменную и текст?

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

    И дальше уже всё просто: тупо пишешь свои переменные в строку
    $rez = 'Название';
    $year = '2007';
    $title = "$rez ($year)";
    Ответ написан
    Комментировать
  • Как убрать ошибки на РHP?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    $lang = $params['lang'] ?? $this->lang_id();
    Ответ написан
  • Можно-ли улучшить этот код?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    1. выкинуть все локейшены с ошибками. это дикость, ни один нормальный сайт так не делает. ошибки надо показывать либо сразу, либо через сессию. локейшены с ошибками встречаются только у дебилов, которые делают видео на ютубе для других дебилов. не надо так палиться сразу.
    2. выкинуть домен из ссылок. ты серьёзно собираешься переписывать все ссылки, когда у тебя сайт с временного домена переедет на постоянный? а потом обратно - когда надо будет потестить локально? header('Location: /AUTH-2/Sign_In/'); достаточно для единственного локейшена, который нужен в этом коде
    3. убрать всю эту лестницу иф-ов, делать все проверки на одном уровне. ошибки собирать в массив. перед вставкой в БД проверить массив на пустоту.
    4. if ($row->Email != $email) - масло масляное. ты УЖЕ проверил емейл в базе, зачем еще раз проверять?
    5. else if($row->Email == $email) { - это уже какой-то совсем адок. Ты УЖЕ проверил, что емейл не совпадает. причем два раза. В else мы попадём, если емейлы совпдают. Ещё раз проверять не надо. Два алкоголика садятся на трамвай, один спрашивает водителя - я этом номере до вокзала доеду? Водитель - нет. Второй алкаш - а я?
    6. внизу у тебя ссылка на password_verify, но хэшируешь ты все равно кривым алгоритмом. Не осилил?
    7. все эти куличики в песочнице с $client_Code $server_Code - это какой-то адок с точки зрения безопасности. Любой школьник, который не тупее дауна, поломает все твои "сессии" за 5 минут.
    8. setcookie("PHPSESSID", $_COOKIE['PHPSESSID'], 0, '/', '.tsecret.net'); - опять совершенно бессмысленная строчка. К чему она? Зачем? Что ты хотел тут сказать? И кому?
    9. Разбей это простыню хотя бы на функции. Никакой солид у тебя конечно не получится, как и у Георгий Котов который сам не понимает что это значит. Но хотя бы разделить проверки, запись в бд, и отправку емейла можно.

    В целом - из плюсов только нормальная работа с БД, в остальном на троечку, и местами - кол (за дыры в безопасности и отсутствие логики)
    Ответ написан
    5 комментариев
  • Почему не работает регистрация?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Скажи, а кто писал эти комментарии? Кто этот гений, который советует ставить символы "в начале строки или в середине"?
    Я думаю, это без шуток, самый важный вопрос, без ответа на который твою проблему не решить
    Ответ написан
    2 комментария
  • Зачем создавать переменные для подключения к БД?

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

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

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    в цикле
    все операции над массивами производятся в цикле
    для перебора массивов в РНР используется оператор foreach
    Ответ написан
    Комментировать
  • Как узнать с какой страницы (php-файла) данные html-формы попали в $_REQUEST?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Если "не изменяя", то будет ненадёжно.
    Так что если надо всегда знать с какой страницы, то лучше эту информацию передавать в форме.
    Ответ написан
    3 комментария
  • Как подключится к базе данных, через PDO или mysqli?

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

    Чисто ради буквального ответа на вопрос
    Как подключиться к Mysql через PDO
    Как подключиться к Mysql через mysqli
    Ответ написан
    Комментировать
  • Почему переменная в функции NULL?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Про null уже объяснили, а я напишу про другую глупость.
    из DB_query надо убрать try catch со всеми причиндалами.

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

    Поэтому метод должен выглядеть так
    function DB_query($DB_query, $params = null) { 
            $query = $this->pdo->prepare($DB_query);
            $query->execute($params);
            return $query;
        }

    больше ничего не нужно
    Ответ написан
    2 комментария
  • Где тут ошибка?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    То есть ты пишешь класс еггог, но при этом не умеешь включать элементарное отображение ошибок в РНР?

    Забудь про классы на годик или два, сотри этот класс и учи основы. Это не наезд - я серьёзно.
    Всё, что новички так старательно выписывают в своем коде, на самом деле уже есть РНР. Ничего от себя писать не надо. Особенно класс еггог.

    Всегда пиши в начале своего кода две строчки
    error_reporting(E_ALL);
    ini_set('display_errors', 1);

    на боевом сервере меняй 1 на 0.
    Это ВСЁ что нужно для обработки ошибок
    Ответ написан
    3 комментария
  • Почему Service Locator это зло и что использовать вместо?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Все эти страшные слова - они на самом деле всегда про одно и то же - про связность. Когда ты хардкодишь внутри класса вызов какого-то конкретного сервиса - ты намертво к нему привязываешься. И чтобы поменять сервис на другой, ты будешь вынужден поменять код класса. Окей, поменял. И тут же в другом месте, где этот же класс использовался, что-то сломалось! И что теперь? Делать два класса, которые различаются одной строчкой? Нет конечно. А как тогда использовать один и тот же класс для обработки разных входящих данных (или одних и тех же данных, но разными способами)? Сделать его поведение изменяемым. То есть сделать изменяемыми те инструменты, которыми он пользуется - т.е. его зависимости.

    Поэтому все зависимости обычно передаются через конструктор (и поэтому и называются инъекция зависимостей.)

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

    Но тут надо понимать, что всё это работает только при правильном применении ООП. А точнее просто при применении ООП. Потому что 98% "ООП" кода, который пишется на РНР - это голимая процедурщина, даже если она обёрнута в классы и методы. Если у тебя метод класса представляет из себя стену кода, которую ты тупо перенёс из файла, инклюдившегося в любимое похапешное спагетти - то это не ООП. Это та же процедурщина, вид сбоку. И смысл использования dependency injection ты с ним не почуствуешь. Будешь конечно применять, но в качестве карго культа - потому что тебе это на тостере написали.
    А вот когда твой код начнет становиться действительно объектным - тогда стразу станет понятнее.


    Похожим на сервис локатор является сервис- или DI-контейнер. Используемый вручную, он является тем же самым сервис локатором. Поэтому вручную его никогда не надо вызывать - что и запрещается в симфоневских конроллерах - а только для автоматического создания классов. В МВЦ у тебя ведь очень многие объекты создаются автоматом - сущности, контроллеры. И вот для того, чтобы при автоматическом создании экземпляра класса у тебя были на руках все требуемые сервисы - и нужен контейнер.

    Соотвтственно, ответ на вопрос "что использовать?" очень простой:
    - при ручном создании экземпляра объекта, все зависимости передавать в него через конструктор, а не получать "из воздуха" в коде.
    - при автоматическом создании экземпляра объекта, использовать dependency injection container

    В этим смысле очень полезно освоить Симфони - строгий фрейворк, в котором нет сервис локатора и в котором запрещено пользоваться контейнером напрямую.
    Ответ написан
    4 комментария
  • Не работает база данных в class'ах (выдает ошибку при выводе массива) PHP, что не так?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    подход в принципе ничего, но реализация - тихий ужас.
    вот так будет хотя бы немного похоже на "класс" плюс исправление очевидных ошибок и бессмысленностей.
    <?php
    class DataBase
    {
        const DB_HOST = 'localhost';
        const DB_USER = 'root';
        const DB_PASS = 'root';
        const DB_NAME = 'example_class_db';
        const DB_CHARSET = 'utf8mb4';
        public $mysqli;
    
        public function __construct()
        {
            try
            {
                mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
                $this->mysqli = new mysqli(self::DB_HOST, self::DB_USER, self::DB_PASS, self::DB_NAME);
                $this->set_charset(self::DB_CHARSET);
            }
            catch(mysqli_sql_exception $e)
            {
                throw new Exception($e->getMessage());
            }
    
        }
        public function preparedQuery($query)
        {
            $stmt = $this->mysqli->prepare($query);
            $stmt->bind_param(str_repeat("s", count($params)) , ...$params);
            $stmt->execute();
            return $stmt;
        }
        public function getResult($query, $params = [])
        {
            if (!$params)
            {
                return $this->mysqli->query($query);
            }
            return $this->preparedQuery($query, $params)->get_result();
        }
    
        public function getRow($query, $params = [])
        {
            return $this->getResult($query, $params)->fetch_assoc();
        }
    }
    Ответ написан
    Комментировать
  • С чего начать джуну в бэкэнде?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Хочешь стать программистом - учи сначала языки (PHP, SQL, плюс хотя бы базово JS, HTML), потом фреймворк
    Хочешь стать ремесленником, типа сапожника 100 лет назад - учи цмс.
    Ответ написан
    5 комментариев
  • Как лучше проверять приходящие данные PHP?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Это все полная бессмыслица.
    "типо от атак" никакие "проверки" вообще не нужны
    функция testInput - это вообще какаой-то ужас, который кочует из отного видео в другое

    Надо понимать две вещи

    1. "от атак" ничего никогда не проверяют. Нормально написанному коду никакие атаки не страшны. Поэтому надо просто писать нормальный код.
    2. проверять данные в принципе можно. Но не "от атак", а просто для удобства. Нормальное рест апи всегда скажет клиенту, если у него данные не в том формате. Только в случае, если проверка не прошла, надо не молча корёжить данные, а вежливо ответить что они не подходят. А сейчас у тебя код только тупо портит входящие данные.
    Ответ написан
    4 комментария