Ответы пользователя по тегу PHP
  • Как правильно писать код, чтобы не было PHP Notice: Undefined index?

    @Vitsliputsli
    везде делать проверку на существование такого элемента с индексом?

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

    @Vitsliputsli
    При использовании ==, php перед сравнением выполнит неявные преобразования, если значения имеют разные типы, то одно из значений будет преобразовано к типу другого, и когда они будут иметь схожие типы будет выполнено сравнение. В мануле php вы можете найти правила преобразований.
    Ответ написан
  • Создание классов в цикле?

    @Vitsliputsli
    Код простейшего генератора:
    $className = 'Home';
    $classFileName = __DIR__ . '/home.php';
    
    $template = <<<'EOD'
    <?php
      class <<CLASS_NAME>> {        
        function __construct(public $name, public $age){}	 
       
        function show_values(){
        echo "$this->name <br> $this->age <br><br>"; 	 	 
        }	 	 	        
      }
    EOD;
    
    $classCode = str_replace('<<CLASS_NAME>>', $className, $template);
    file_put_contents($classFileName, $classCode);

    Хотя пока неизвестна истинная задача, может нужно не это.
    Ответ написан
    5 комментариев
  • Readonly и объект?

    @Vitsliputsli
    readonly не следит за изменением свойств объекта, если вам нужен иммутабельный объект - делайте специальный объект, либо создавайте его особым образом.
    Ответ написан
  • Добавление свойства без объявления свойства?

    @Vitsliputsli
    Это называется динамическое свойство, в php 8.2 признано устаревшим. Делать так не рекомендуется по очевидным причинам: мы описываем объекты классами для упорядочивания работы, чтобы точно знать, что и где лежит, когда в объекте свалено невесть что, работать с этим будет проблематично. И, к слову, напрямую в свойства тоже не рекомендуется писать.
    Ответ написан
    2 комментария
  • Что может содержать DTO?

    @Vitsliputsli
    1) Цель использования DTO - это передать данные между двумя подсистемами. Причем, либо между ними нельзя передать поведение, либо мы хотим, чтобы они были независимы, а передача поведения увеличит зацепление.
    2) DTO - это специфика Java, там, объединить разнородные данные можно только в объекте. Поэтому был введен данный механизм - объект с искусственным ограничением, только данные и никакого поведения. Но, php не Java, здесь разнородные данные можно легко объединить в обычном массиве. Вы можете, конечно, массив завернуть в объект, но смысла в этом нет, т.к. мы передаем данные между независимыми подсистемами, ни одна из них не должна быть зацеплена на объекты другой.
    3) Как уже написали, сам DTO и механизм его формирующий - это разные вещи, подсистемы могут вообще на разных языках быть написаны, и все будет прекрасно работать, т.к. мы передаем только данные, а не поведение. Если же хочется туда запихнуть валидацию или иное поведение, стоит задуматься, а зачем здесь DTO? Не проще ли тогда сразу передавать полноценный объект.
    Ответ написан
  • Почему условие не выполеяется?

    @Vitsliputsli
    empty($var) - это "синтаксический сахар", т.е. это краткая запись следующей конструкции:
    !isset($var) || $var == false
    т.е. кроме того же самого isset, там еще и сравнение с false, причем с преобразованием типов
    Ответ написан
    Комментировать
  • Зачем дублировать сеттер и геттер?

    @Vitsliputsli
    Если уж говорить об едином методе, то скорее так:
    function getSetAge(?int $age=null): int
    {
        if (!is_null($age)) {
            $this->age = $age;
        }
        return $this->age;
    }}

    Но, мы уже не сможем записать null, а получать значение, которые мы только что записали и вовсе не нужно.
    Даже так не делают, потому что, это логически совершенно разные операции и гораздо удобнее их разнести по разным методам. Если вы думаете, что упрощение - это меньше символов, то это не так. Упрощение - это разнесение независимых частей, а складывание всего в одну кучу только ухудшает чтение.
    Не говоря уже о том, что использование геттеров-сеттеров не очень хорошая практика, методы должны нести смысловую нагрузку, а не просто менять внутренние свойства, иначе это ничем не лучше публичных свойств. Хотя и тут тоже нужно без фанатизма.
    Ответ написан
    Комментировать
  • Как из текстового файла вывести 15 случайных строк?

    @Vitsliputsli
    Накидал вариант для поиска случайных строк в очень больших файлах. Это не совсем оптимально для конкртеного случая автора, но может быть будет кому-то интересно в других случаях.
    $fileName = '1.csv';
    $lineLength = 1024;
    $linesCount = 15;
    
    $handle = fopen($fileName, "r");
    $fileSize = filesize($fileName);
    $data = [];
    if ($fileSize !== 0) {
       for ($num = 1; $num <= $linesCount; $num++) {
           $rand = rand(0, $fileSize);
           fseek($handle, $rand);
           $firstPointer = null;
           do {
               fgets($handle); // trash
               $pointer = ftell($handle);
               if ($pointer === $fileSize) {
                   fseek($handle, 0);
                   $pointer = 0;
               }
               if ($pointer === $firstPointer) { // loop detect
                   continue 2;
               }
               $firstPointer = $firstPointer ?? $pointer;
           } while (array_key_exists($pointer, $data));
           $data[$pointer] = fgets($handle);
       }
    }
    ksort($data); // sort by order in file
    var_dump($data);

    Я здесь не делал защиты от ошибок файловых функций, в этом случае результат может быть неожиданным. Для защиты нужно обернуть все файловые функции и при ошибке выкидывать Exception, а не эти тупые php-шные false. Ну и помнить про ограничение длины строки в $lineLength.
    Ответ написан
    Комментировать
  • Можно ли взаимодействовать с функцией файла, не подключая ее?

    @Vitsliputsli
    Нет, нельзя.
    C# компилируемый язык, когда создаете новый файл, IDE подключает его в проект. При сборке файлы проекта известны и будут использоваться. PHP интерпретируемый язык, вы можете запустить на исполнение любой файл php, но он не имеет никакого понятия, что там было в IDE, поэтому использование require обязательно. На практике используют автолоадеры, стандартом в PHP считается автолоадер composer.
    Ответ написан
    Комментировать
  • Что не так в коде (можете сделать краткое код ревью)?

    @Vitsliputsli
    Про форматирование, конечно, верно пишут, но если про него забыть (очень оно не стандартное, но я бы не сказал, что прям какое-то нечитабельное), то просто беглым взглядом:
    1) Нет ООП (а это сейчас обязательный стандарт), попытка выдать за ООП набор статических классов делает только хуже, пишите уж лучше честно процедурно.
    2) SQL-инъекции! Да и весь блок работы с СУБД чтото ужасное. Куча бесполезного, реконнекты при каждом запросе...
    3) ТТУК, если конечно вообще подразумевался mvc, и контроллер это index.php.
    4) Вместо автолоадера просто подключение всего и вся. Хотя по факту в php сейчас стандарт - composer.
    Ответ написан
  • Какой есть быстрый способ сравнить многомерный массив?

    @Vitsliputsli
    Если весь массив умещается в память это уже хорошо. Как оптимизировать:
    1) Создайте массивы не ассоциативные, а с обычными числовыми ключами. Лучше так и хранить, будет отдельно массив url и массив cnt, связь по числовому ключу.
    2) Храните отсортированный массив, и используйте по нему, например, бинарный поиск.
    3) Дополнительно можно использовать массив фиксированной длины из SPL, а не стандартный на хеш-таблицах, на таких объемах от него будет толк.
    Ответ написан
    Комментировать
  • Почему PHP кэширует содержимое скрипта при запуске из sudo?

    @Vitsliputsli
    У вас включен файловый кеш (в том числе для cli), но отключена проверка валидности кеша (validate_timestamps). Поэтому пока вы вручную не сбросите кеш, он будет продолжать работать.
    Что касается sudo, при первом запуске скрипта, вы сделали это через sudo, был создан файл кеша от root, с правами запрещающими чтение другими пользователями. При запуске без sudo php не может его прочитать и записать (хрен его знает, почему он не кидает ошибку), в итоге sudo php работает с файловым кешем, а php от пользователя нет.
    Ответ написан
    Комментировать
  • Как улучшить код, который проверяет наличие элемента в массиве и его значение?

    @Vitsliputsli
    Не нужно ничего сокращать. Код вполне краток и понятен. Дальнейшие сокращения лишь ухудшат читаемость.
    Но если хочется поговнокодить можно взять empty.
    Ответ написан
    5 комментариев
  • Почему неправильно изменяется текст php?

    @Vitsliputsli
    ... выглядит примерно так: 01
    То есть 0 не убирается, как то исправить?

    А вы пробовали локализовать проблему? Т.е. посмотреть отдельные участки кода. Например, так:
    echo sprintf('%02d',1);
    И решить, если вам не нужны ведущие нули, зачем вы их требуете выводить?
    Ответ написан
    3 комментария
  • Хороша ли архитектура моего кода? Информация цепляется по API?

    @Vitsliputsli
    Все public, все доступно извне, нет сокрытия.
    Прям сам объект куда-то лезет по api, забирает данные, которые сам и предоставляет, обрабатывает ответ, явное нарушение SRP.
    Ответ написан
    Комментировать
  • Что быстрее поиск по файлу JSON в PHP или в базе посредством MySQL?

    @Vitsliputsli
    Если это обычный вопрос, что лучше, то храните в БД. Если реально пытаетесь выиграть несколько миллисекунд, то положите это все в redis.
    В принципе, хранение в массиве php скорее всего тоже будет достаточно быстрым, при условии использования php-fpm и без json.
    Если нужен поиск подстроки в строке, то на таких объемах тоже вполне быстро будет работать. На больших придется рассматривать, что-то вроде Elastic, т.к. СУБД это делают плохо, а MySQL очень плохо.
    Ответ написан
    Комментировать
  • Как правильно сделать типизацию объектов?

    @Vitsliputsli
    Вы можете воспользоваться контравариантностью (php>=7.4), т.е. указать в абстрактном классе родительский класс для User:
    abstract protected function mapToArray(Model $object ): array;
    
    ...
    
    class User extends Model

    Либо ввести DTO, чтобы mapper брал данные из него и вообще никак не обращался к бизнесовым сущностям.
    Ответ написан
    6 комментариев
  • Как в регулярных выражениях php заменить только символ?

    @Vitsliputsli
    Зачем здесь регулярка?
    str_replace(['*','x'],'R','2*10*30 2x10x30');

    Регулярка будет выглядить так: /\*|x/

    Если же, замена нужно только для конструкций из 3 чисел соединенных * или x, то можно написать так:
    preg_filter('/(\d+)[*x](\d+)[*x](\d+)/', '${1}R${2}R${3}', '2*10*30 2x10x30')
    Ответ написан
    2 комментария
  • Почему не работает curl в цикле?

    @Vitsliputsli
    У вас и во внешнем и во внутреннем цикле используется одна и та же переменная.
    Ответ написан
    Комментировать