Ответы пользователя по тегу PHP
  • Кто может дать комментарии по поводу кода PHP ООП (Code review)?

    @D3lphi
    Что-то многовато таких вопросов за последние пару дней. Часть замечаний к вашему коду есть в этом ответе. Повторюсь.

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

    но, тем не менее, этот класса делает все, что не лень:
    • Работает с этими самыми массивами
    • Соединяется с базой данных
    • Отправляет запросы к базе данных
    • Занимается обработкой данных

    Не многовато ли для одного класса?
    В итоге, мы получаем богообъект, который "умеет во всё".

    Что у вас за бред написан в методе getInstance()? Зачем бросать исключение, в случае, если инстанс уже был создан.

    if (self::$_instance === null) {
        self::$_instance = new self($id);
    } else {
        throw new Exception("Попытка повторного создания экземпляра Singleton класса");
    }
    return self::$_instance;


    То есть, у вас теряется весь смысл (анти)паттерна синглотон. Получается, я не смогу сделать так:

    $instance1 = treeData::getInstance();
    $instance2 = treeData::getInstance(); // Исключение!

    Есть логика? Я думаю, что нет.

    Почему вы храните данные для соединения с БД внутри метода? Не логично ли было бы передавать их в качестве аргументов к методам?

    Вы каждый раз повторяете строки с подготовкой запроса, биндингом параметров, отправкой запроса и тд. Не думали, что неплохо бы было написать какую-нибудь обертку и выполнять запросы как-нибудь так:
    $result = $wrapper->select("SELECT * FROM `tablename` WHERE `id` = :id", ['id' => 5]);

    ?


    Абстрактные исключения не бросаем! Создаем свои исключения и наследуемся от них. В своем коде используем только их, дабы можно было легко обработать нужные exception'ы. Текст исключения неплохо бы было писать на английском.

    Имена классов пишем с большой буквы! Скобки после методов и классов пишем на новой строке:
    function example() {
        // Не так
    }
    
    function example()
    {
        // А вот так
    }


    Предлагаю придерживаться общепринятым стандартам оформления кода.

    Старайтесь использовать синглтон в таком виде по минимуму (Или вообще не использовать). Тем более, в данном случае, он вообще не нужен.
    Ответ написан
    6 комментариев
  • Social NetWork | Как реализовать роутинг PHP?

    @D3lphi
    Чем маршрутизация для социальной сети принципиально отличается от маршрутизации интернет-магазина, например?

    Не нужно ничего реализовывать. Все уже сделали за вас. В интернете полно готовых роутеров. Вот, как вариант, "симфонический роутер".
    Ответ написан
    Комментировать
  • Насколько у меня правильный код ООП php?

    @D3lphi
    Здесь плохо всё, к сожалению.

    Начнем с того, что вы неверно наследуете классы. Почему у вас класс, отвечающий за подключение к базе данных является родителем класса, работающим с заказами? Наследование применяется, если можно сказать, что что-то является чем-то. Например, разработчик является работником; компьютер является устройством и тд. Здесь же у вас вообще близко такой логике не получится следовать. Вы должны передавать хотя бы объект для работы с бд через инъекцию, например, в конструктор. В идеале, нужно использовать паттерн репозиторий для работы с базой данных.

    Класс SearchOrder у вас не только выполняет запросы, но еще и работает с данными, хранит состояние этих самых данных, фильтрует данные (strip_tags()). Непорядок. Это все нужно разделять. У вас вообще получаются какие-то богообъекты, которые умеют во все.

    Вы каждый раз повторяете строки с подготовкой запроса, биндингом параметров, отправкой запроса и тд. Не думали, что неплохо бы было написать какую-нибудь обертку и выполнять запросы как-нибудь так:
    $result = $wrapper->select("SELECT * FROM `tablename` WHERE `id` = :id", ['id' => 5]);

    ?

    Вы вызываете connect() в методах. То есть, каждый вызов этого метода будет приводить к установке нового соединения с базой данных, даже если оно уже было установлено. Соединение с базой данных это достаточно дорогостоящая операция.

    Зачем вы используете свойства, если можно обойтись обычными локальными переменными:
    $this->orderID = (int) strip_tags($orderID);
    $this->column = (string) strip_tags($column);
    $this->value = (string) strip_tags($value);

    ?

    Почему вы стриппите тэги у идентификатора? вы настолько не уверены в том, что влетает в функцию:
    strip_tags($orderID);
    ?

    Если вы не используете php 7 и, как следствие, скалярный тайпхинтинг, то должны делать проверки на тип входящего аргумента. Если что-то не так с типом, бросаем исключение (А не приводим его к нужному)! Например:
    if (!is_string($arg)) {
        throw new InvalidArgumentTypeException('string', $arg);
    }

    Это в идеале. Вы не обязаны это делать, конечно же. Но вот такие проверки делают приложение безопаснее. Хотя, опять же, повторюсь, в 2017 нужно начинать новые проекты на php 7.1+.

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

    Кроме всего прочего, почитайте про стандарты оформления кода. Вы им не следуете.

    Вам пока рано писать такие велосипеды. Судя по всему, у вас нет опыта вообще. Посмотрите готовые решения: фреймворки, ORM, изучите их, хотя бы поверхностно разберитесь, как оно работает и уже потом пробуйте что-то сделать, исходя из полученных знаний.

    Желаю успехов!
    Ответ написан
    1 комментарий
  • Потоковый JSON парсер, какой использовать?

    @D3lphi
    Стесняюсь спросить, json_decode() вас чем не устраивает?
    У меня на ПК обработка json-файла размером в 130 мб занимает чуть больше секунды.
    Ответ написан
    Комментировать
  • Как вытащить число из строки на php?

    @D3lphi
    $json = json_decode("{\"response\":{\"post_id\":102}}", true);
    $result = $json['response']['post_id'];
    Ответ написан
    Комментировать
  • Как изменить длину от 8-и до бесконечности?

    @D3lphi
    (!preg_match('/^(?=.*\d)(?=.*[A-Z])(?=.*[a-z])[0-9A-Za-z_]{8,}$/', $_POST['password']))
    //                                                         /\ Не пишите конечное значение. Это будет означать "От 8 и до скольки угодно".
    Ответ написан
    Комментировать
  • Как проверить элементы массива через условие?

    @D3lphi
    Если я вас правильно понял:
    $flag = true;
    foreach($items as $item) {
        if ($item <= $val) { // $val - число, больше которого должны быть элементы массива.
            $flag = false;
            break;
        }
    }
    
    if ($flag) {
        // Делаем что-то
    }
    Ответ написан
  • Как обернуть цифры в тег регуляркой на php?

    @D3lphi
    $str = '23 сентября';
    $result = preg_replace('/([0-9]+)/', '<strong>$1</strong>', $str);


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

    @D3lphi
    Вспомогательный класс, которыей содержит методы со вспомогательной логикой не затрагивающие бизнес-логику


    Как я понял, в вашем понимании хэлпер - такой себе Божественный объект, который умеет во всё. Таких классов в программе быть не должно от слова "совсем". Такая функциональность группируется и выносится в отдельный класс. То есть, класс для resize'а изображений один, класс для преобразования данных - другой и тд. Старайтесь использовать статику только в самом крайнем случае.
    Ответ написан
  • Как вызвать класс как функцию?

    @D3lphi
    Определить метод __toString() в классе. При попытке преобразовать объект в строку будет возвращаться результат работы этого метода.

    class Example
    {
        public function __toString()
        {
            return "this is Example class.";
        }
    }
    
    $example = new Example();
    echo $example; // Выведет this is Example class.
    Ответ написан
    Комментировать
  • Что почитать про правильную архитектуру MVC?

    @D3lphi
    о-есть по идее интересна структура это, начиная с index.php который перенаправляет нас на класс роутера и т.д.


    То что вы хотите узнать выходить за границы ответственности MVC. MVC говорит нам о том, что в приложении следует выделять модель, представление и контроллер. О роутинге он ничего не знает.

    файл с автолоудом прописывается и один ли он для всех или должен иметь логику


    2017 год на дворе. Какой файл с автолоудом? Composer имеется, к счастью. Он производит автозагрузку классов самостоятельно.

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


    Берите не весь фреймворк, а его компоненты и изучайте по отдельности. Так, например, пройдитесь по компонентам symfony.

    В каком framework самая хорошая и правильная структура ООП


    Symfony позволяет писать наиболее правильный код.
    Ответ написан
    9 комментариев
  • Баг? Фича? Или я что-то не понимаю?

    @D3lphi
    А чего тут непонятного? У вас в Data::$data лежит массив с экземплярами классов stdClass. То бишь, объекты. А объекты в PHP как передаются? Правильно, по ссылке! Следовательно, изменение значения свойства этого объекта в одном месте, изменяет этот объект везде.

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

    @D3lphi
    Http basic auth.
    К php не имеет отношения, так как реализуется на уровне веб-сервера.
    Авторизоваться можно при помощи curl.
    Ответ написан
    Комментировать
  • Выделение памяти в PHP ООП?

    @D3lphi
    1) При создании экземпляра new Class() в память забираются все его методы - чем больше методов тем больше памяти надо, или там память на метод в момент его вызова метода выделяется?


    При подключении ЛЮБОГО php файла производится лексический анализ, лексер генерирует из исходного кода программы набор токенов, из которых строится синтаксические дерево. Отсюда следует то что, чем больше кода, тем больше памяти выделяется.

    Само по себе создание каждого последующего объекта также несет затраты.

    Значит ли всё это что наиболее нагруженную но простую часть системы лучше вынести в отдельный компактный класс содержащий только необходимое для её функционирования?


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

    @D3lphi
    Да сколько можно велосипеды писать? Composer есть, я же уже говорил вам!

    Используйте стандарт автозагрузки psr-4. Для этого следует использовать пространства имен (namespace'ы).
    Таким образом, класс с полным именем App\Controllers\DefaultController (Где App\Controllers - неймспейс, а DefaultController - имя класса) должен лежать в директории app/controllers и иметь имя DefaultController.php.
    Ответ написан
  • Как обработать ajax-запрос на php?

    @D3lphi
    А чем ajax-запрос отличается от любого другого? Правильно, ничем, поэтому обрабатывать его можно так же как и любой другой запрос. Самый примитивный вариант, отправлять вместе с запросом параметр, в зависимости от которого будут выполняться определенные действия.

    <?php
    $action = $_GET['action']; // Это для примера. Не забываем, что все входные данные нужно обрабатывать.
    
    switch($action) {
        case 'one':
             // Делаем что-то
            break;
         case 'two':
             // Делаем что-то
            break;
    }


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

    @D3lphi
    ведь даже если мы их подключим, но экземпляр не создадим, то ресурсы-то им всё равно не выделяться...

    На декларацию класса, функции тратятся ресурсы (Их же нужно где-то хранить). Код пропускается через лексический анализатор, для каждой лексемы создаются токены, а из токенов строится синтаксическое дерево. Так что, даже просто подключение файла потребляет ресурсы.

    А можно избавиться от строки $obj = new MyClass(); и создавать экземпляр автоматически?

    Нет, нельзя.

    В 2017 году принято использовать composer для автозагрузки, а не писать свои велосипеды.
    Ответ написан
  • Как увеличить PHP_INT_SIZE?

    @D3lphi
    У вас стоит x32 версия PHP. Вам нужно установить версию x64.
    Для работы с очень большими числами можно юзать BC Math, которая уже встроена в PHP.
    Ответ написан
    3 комментария
  • Как проверить если $_GET параметр начинается с 0?

    @D3lphi
    При помощи PHP:

    if ($_GET['object_id'][0] === '0') {
        // Отдаем 404
    }
    
    $object_id = intval($_GET['object_id']);


    Или при помощи настройки веб-сервера:

    RewriteRule ^object/([1-9][0-9]*)(/?)+$ index.php?do=object&object_id=$1&title=$2 [L]
    Ответ написан
    Комментировать
  • Почему не работает проверка майла?

    @D3lphi
    Вам нужно поставить логическое отрицание перед условием, так как вы проверяете то, что email некорректен.
    //\/ Здесь.
    if(!filter_var(trim($_POST['email']), FILTER_VALIDATE_EMAIL)){
          $errors[] = 'Вы ввели некорректный E-Mail';
    }
    Ответ написан
    Комментировать