Задать вопрос
Ответы пользователя по тегу PHP
  • Как увеличить скорость добавления данных в базу данных mysql?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Чтобы решить проблему, её надо сначала сформулировать.
    В данном случае никакой проблемы нет, есть невнятные страдания.
    Ни кода, ни внятного описания проблемы, ни даже пояснения, что имеется в виду под "добавлением" в вопросе нет.

    В простейшем случае либо делать один множественный запрос insert, либо заключить отдельные запросы insert в транзакцию
    Ответ написан
    6 комментариев
  • Есть ли список распространённых и общепринятых слов для именования переменных в PHP?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Нет, словаря нету. просто используются подходящие по смыслу английские слова.
    Собственно, и приведенный вами список для HTML - это именно что словарь. В смысле такой очень смешной англо-русский словарик. В котором приведены не какие-то особые "термины", а просто переводы русских слов на английский язык.

    Так что в целом можно сформулировать правило, что используется одно или несколько английских слов, подходящих по смыслу.
    С одним уточнением: в общем случае в качестве переменной используется подробное описание того, что в ней лежит. Но для очень часто используемых переменных обычно делается исключение, потому что стройные ряды какого-нибудь $userSelectQueryResult выглядят задротством.

    И в ваших примерах для PHP тоже просто переводы. Причем не очень удачные.
    link - звено - не слишком подходит по смыслу, и почти не используется.
    connect - это глагол, а в качестве имен переменных обычно используются существительные. connection подойдет лучше, но совсем длинно.
    con - хоть и является сокращением от connection, само по себе означает жульничество. Тоже так себе слово. Поэтому если уж сокращают, то обычно до conn.
    Но само по себе "соединение" малоинформативно. Соединение с чем?
    Поэтому я обычно рекомендую писать $db - сокращение от database. Тут и коротко, и сразу понятно, о чем речь.

    Причем если речь идет об объектах, то всегда можно использовать имя класса в качестве имени объекта.
    Например, если вы используете mysqli, то и называйте переменную $mysqli.
    Если используете PDO, то называйте переменную $pdo.

    $result - подходящее имя, от объекта mysqli_result.
    $response обычно употребляется в контексте НТТР., для базы данных не очень подходит.

    Причем от использования $result в коде надо уходить. Это промежуточная переменная, которая сама по себе вам не нужна, а требуется для получения реального результата запроса. Ну так вы вполне в состоянии написать функцию, которая сразу возвращает нужный результат, без колупания в промежуточных результатах.
    $user = db_get_row($mysqli, "SELECT * FROM users WHERE email=?", [$email]);

    и никаких мусорных $result, не говоря уже о том что кода в 5 раз меньше
    Ответ написан
    Комментировать
  • Почему PHP не исполняется построчно, хотя он интерпретируемый?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Изначально интерпретируемые языки преобразовывались в машинный код построчно, то есть каждая логическая строка компилировалась непосредственно перед выполнением. В результате каждая инструкция, заключенная в тело цикла и исполняемая несколько раз, столько же раз обрабатывалась транслятором. В настоящее время такие эффекты редки. Большинство интерпретируемых языков предварительно транслируются в промежуточное представление. Оно представляет собой байт-код. Это набор инструкций по вызову небольших фрагментов более низкоуровневого кода, эквивалентный нескольким командам ассемблера или командам виртуальной машины соответственно. Уже этот код исполняется интерпретатором или виртуальной машиной.
    Ответ написан
    5 комментариев
  • Почему не работает запись в базу данных?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    В целом, я считаю что основная причина здесь - это отборный говнокод в переменной $Functions. Я прямо на 100% уверен что каждую строчку оттуда можно помещать в палату мер и весов с пометками "вредные советы" и "дети, никогда так не делайте, за это вам нехороший дядя сделает а-та-та!" Уже за одно только наличие функций redirect() и getString() в одном классе надо автора возить лицом по клавиатуре, желательно механической.

    Но если говорить о записи в БД, то причин может быть две.
    1. Код вставки вообще не вызывается. Например, $Functions->redirect(); вызывается в случае, если $openid->validate() возвращает false. Хотя понять это можно, только скопировав это адово форматирование в нормальный редактор.
    2. Если при выполнении запроса произошла ошибка. Чтобы видеть ошибки mysqli в устаревших версиях РНР, надо добавлять при коннекте строчку
    mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

    и, чтобы два раза не вставать, заодно убрать бессмысленный говнокод try{ }catch(ErrorException $e){ echo $e->getMessage(); }

    Ах да, еще третий вариант. Запись о таком пользователе уже есть, и следуя логике кода, в этом случае в БД ничего и не должно добавляться
    Ответ написан
  • Зачем нужны объявления типов php?

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

    Многие новички этого не понимают, и думают, что это приставучий интерпретатор пишет какую-то ерунду, от которой надо избавляться любыми доступными способами.
    Но как только начинаешь понимать, что сообщения об ошибках придуманы чтобы помогать программисту, то все становится на свои места.

    Если объявить тип переменной, то если в функцию передать аргумент неподходящего типа, РНР сможет сообщить о проблеме раньше, чем код сломается, попытавшись ее использовать.
    Ответ написан
  • Взаимодействие между несколькими самостоятельными приложениями?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Не должно у вас изменение сущности в одном приложении влиять на сущность в другом.

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

    Какая проблема, чтобы Client сходил в Order, получил идентификатор созданного заказа и дернул Billing?
    Зачем во всех этих трех сервисах делать тройное дублирование сущностей?
    Ответ написан
    5 комментариев
  • Как сокращенно записать условие в случае если значение не пустое?

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

    Поэтому для приведенного кода ничего сокращать не нужно. Это приведет только к потере читабельности. Которая всегда важнее, чем экономия на строчках.
    И вариант с тернарным оператором, и предложенный в комментариях трюк с логическим оператором && только ухудшат читабельность.

    Использование конструкции if - это совершенно нормальная практика. И думать, что так пишут только "по-старинке" - это какая-то дурацкая фантазия.

    В принципе варианты сократить код всегда есть. Но для этого надо приводить конкретный пример.
    А для вот такого общего случая и ответ будет общий - все оставить как есть.
    Ответ написан
    Комментировать
  • Где правильно выполнять проверку try/catch для внешних api в Laravel?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Как вам правильно написали в комментариях, в общем случае ловить исключение надо конечно в сервисе.
    Иначе у ваших компонентов будет высокая связанность (copuling) компонентов, а надо чтобы она была наоборот - низкая. "Все, что случилось в Вегасе, осталось в Вегасе".

    Если ловить в контроллере, то вы увязываете вместе уже 4 разные сущности:
    - внешний сервис
    - Газл
    - сервис
    - ещё и контроллер
    Не многовато?
    Получается, что контроллер должен что-то там знать про всех троих предыдущих. А он по идее должен знать только про непосредственного собеседника - сервис.
    Так что ответ тут в общем случае очевиден.

    Также в комментариях вы пишете, что контроллер у вас общается с несколькими сервисами. Это понижает его связность (cohesion). А она наоборот, должна быть высокой. В смысле он должен делать что-то одно.
    Поэтому решение, опять же, очевидно - все эти пертурбации с передачей горячей картофелины из сервиса в сервис должны производиться еще одном сервисе. Потому что это безнис-логика. А в конроллере не должно быть бизнес-логики. Контроллер - это чисто брокер НТТР запросов. Принять данные, проверить их, и передать в модель. То есть туда, где пишется бизнес-логика - все эти "сходить в тот сервис, передать в другой и сообщить третьему".
    Ответ написан
    1 комментарий
  • Не работает бд в php?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Если вы считаете, что данные не заносятся в БД, то на это может быть две причины
    1. Ошибка при занесении.
    2. Все заносится, но вы просто не там смотрите.

    Чтобы исключить первый пункт, надо убедиться в том, что вы можете видеть все ошибки. Для этого на локальном сервере надо включить отображение ошибок на экран. Плюс настроить РНР, чтобы он не скрывал никакие ошибки
    <?php
    # Ошибки
    # Для локального сервера
    ini_set('display_errors', 1);
    # Всегда
    error_reporting(E_ALL);
    mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
    
    # дальше пишем сам код
    $login = trim(filter_input(INPUT_POST, 'login'));
    $password = filter_input(INPUT_POST, 'password');
    
    if (mb_strlen($login) < 4 || mb_strlen($login) > 15) {
      exit("Логин не должен быть короче 4 символов и больше 15");
    } else if (mb_strlen($password) < 8 || mb_strlen($password) > 100) {
      exit("Пароль не может быть короче 8 символов и больше 100");
    }
    $password = password_hash($password, PASSWORD_DEFAULT);
    
    $mysql = new mysqli('176.107.160.36', 'limbo', 'Fear333M', 'vanilla');
    
    $stmt = $mysql->prepare("INSERT INTO `sait` (`login`, `password`) VALUES (?, ?)");
    $stmt->bind_param("ss", $login, $password);
    $stmt->execute();

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

    Если же этот код выполняется и не выдает ошибок при этом, значит данные добавились. И надо просто открыть правильную базу данных
    Ответ написан
    Комментировать
  • Проверка на пустой файл в пост форме?

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

    При этом надо определиться - зачем загружается несколько файлов. Если речь об одном файле, то зачем делать 4 поля ввода? Если нужно несколько файлов, то почему проверяется только один? Проверять тогда надо все, в цикле.

    Вообще всегда полезно читать инструкцию перед тем как садиться что-то делать. Или хотя бы после того как ничего не заработало.
    Ответ написан
    2 комментария
  • Как к масиву подключить подгружать через file_get_contents файлы из папки?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    include.
    РНР файлы в РНР подключаются с помощью конструкции include.
    Ответ написан
  • Почему выскакивает эта ошибка при INSERT INTO?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Потому что одинарные кавычки имеют в программировании определенный смысл, и их надо писать только там, где надо, а не просто добавлять от балды в код?
    Ответ написан
    8 комментариев
  • Как прочитать webhook?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Загадочный webhook - это самый обычный РНР скрипт, который самым обычным образом принимает GET или POST запрос, точно так же, как если бы он был отправлен из браузера.
    То есть "проверить, что данные действительно приходят" точно так же: если это JSON POST, то через php://input, если обычный POST - то в $_POST
    Ответ написан
  • Как убрать повторяющиеся элементы из двумерного массива php?

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

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

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    insert into odna (col1, col2) select col1, col2 from drugaya;
    insert into odna (col1, col2) select col1, col2 from tretya;
    Ответ написан
    Комментировать
  • Как запустить python через php?

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

    Как минимум - в начало пхп скрипта и смотреть на ошибки
    ini_set('display_errors',1);
    error_reporting(E_ALL);
    Ответ написан
    4 комментария
  • Как узнать наличие записи в базе данных и получить нужные значения?

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

    Код у вас - для второго.
    А пытаетесь вы его использовать для первого.

    Чтобы проверить, цикл не нужен. Чтобы обработать - КАК вы обойдетесь без цикла?

    В принципе, я тут не вижу нужды проверять. Просто запросить, да обработать.
    Но если прям жить не можете без проверки, то можно например использовать переменную
    $found = false;
    foreach($result as $row){
        $found = true;
        $orderId = $row["orderId"];
        // делаете что хотите
    }
    if(!$found) {
        print 'нет';
    }


    Если запись может быть только одна, то еще проще

    $result = mysqli_query($mysqli, "SELECT * FROM `Order` WHERE status='NEW'");
    $row = $result->fetch_assoc();
    if ($row) {
        $orderId = $row["orderId"];
    } else {
        print 'нет';
    }
    Ответ написан
  • 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 комментария
  • Функции хелперы, что это и зачем они нужны если и без них всё работает?

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

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

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

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