Ответы пользователя по тегу PHP
  • Переподключение PHP к MySQL как правильно организовать?

    @Vitsliputsli
    Самый правильный вариант - отключаться, если соединение не используется. Правильно, т.к. не используем ресурсы для поддержания ненужного соединения, ни на клиенте, ни на сервере. И не ловим эксепшены.
    И только если ну никак нельзя это контролировать, тогда реконнект по эксепшену.
    Ответ написан
  • Как найти циклы в массиве?

    @Vitsliputsli
    Вариант с единственным чтением каждого элемента, если ссылок на кольцо много, оно все равно будет прочитано 1 раз, хотя кольцо храним в отдельном массиве.
    do {
        $path = [key($array), $link = current($array)];
        while (isset($array[$link2 = $link])) {
            $link = $array[$link2];
            unset($array[$link2]);
            $pathPos = array_search($link,$path); // более для понятности, для длинных колец эффективнее хранить только ключи и искать по ним
            if (false !== $pathPos) {
                var_export(array_slice($path,$pathPos));
                break;
            }
            $path[] = $link;
        }
    } while (false!==next($array));
    Ответ написан
    Комментировать
  • Как грамотно реализовать одно соединение с базой данных на все приложение, с помощью Dependency Injection Container?

    @Vitsliputsli
    Создать зависимость можно только 2 способами, получив объект изнутри или проведя инъекцию снаружи. Если изнутри, то так или иначе понадобится синглтон, если снаружи, то ктото снаружи должен контролировать передачу одного и того же объекта во все нуждающиеся объекты.

    1. Изнутри. Очевидно просто инстанцировать объект - это очень плохой вариант. Более менее нормальный вариант, это сервис локатор, с методом возвращающим нужный объект работающим как синглтон (т.е. не нужен прям класс синглтона, только метод который проверяет существует ли объект). Выглядит это не очень, синглтон и сервис локатор не считают хорошим решением. Из минусов статичное обращение к сервис локатору создаст проблемы для подмены объекта. Для разных подключений вы можете создать отдельные методы сервис локатора или разрулить в одном методе динамический выбор. Реальная проблема - тестирование, вы не сможете мокировать объект работы с БД. Но, можно это сделать ухищрениями, сделав ленивое подключение, и метод подмены объекта БД, хотя придется этот метод тащить в каждый класс. Как вариант, делать инъекцию объекта сервис локатора. Но остается другой большой минус, сервис локатор "гвоздями прибит" к большинству классов и вам придется его везде таскать, т.е. о красивых компонентах без странной зависимости от сервис локатора можно забыть.
    2. Снаружи. Оптимально, и считается трендом - инъекция нужного объекта в конструктор. Будет ли это делать DIC или чтото иное не имеет значения. Не нужно таскать какието дополнительные сервис локаторы. Но данное решение имеет тот же минус, что и п.1, вы не сможете подменить объект на другой при мокировании:
    public function __construct(PDO $db)
    внедряемый объект обязан быть классом PDO, если хочется чтобы мок просто подсовывал одни и те же значения нужно менять на интерфейс, тогда моку достаточно выполнять требования интерфейса. Но, если ваш DIC использует автоматическое определение требуемых объектов по структуре конструктора, то использовать интерфейс не получится.
    Ответ написан
    Комментировать
  • Как передать переменную?

    @Vitsliputsli
    Используйте prepared statements. И пересмотрите архитектуру, генерировать код нужно только для очень специфичных задач, и уж точно не для того, чтобы "показать новости". Посмотрите на свой код, вы там ничего не генерируете, у вас статичный код и просто меняются данные.
    Ответ написан
    Комментировать
  • Как парсер читает скрипт в случае асинхронных запросов?

    @Vitsliputsli
    Парсер просто последовательно читает текстовой файл, он ничего не знает о выполнении кода, но знает синтаксические правила языка. Если речь про интепретатор, то он выполняет код последовательно, но в нем есть команды перехода к различным участкам кода, от простейших условных и безусловных до функций и объектов с методами.
    Поддержки асинхронности из коробки в php нет, но есть специальные библиотеки для этого, например ReactPHP. Если же говорить про чистый php, то в нем есть несколько асинхронных функций (например multi_curl), но правильнее сказать, что они неблокирующие, а асинхронность придется воплощать вручную, периодически передовая управление этим функциям.
    Ответ написан
    Комментировать
  • Почему скрипт выполняется не до конца?

    @Vitsliputsli
    никаких ошибок не выдает... Там просто в моменте обрывается и всё

    Запускаете дебаггер и смотрите, что происходит. Если нельзя воспользоваться дебаггером, значит логируйте шаги выполнения, увеличивайте детализацию логирования пока не локализуете проблему.

    Без этой информации можно лишь гадать, варианты:
    1) скрипт выполняется корректно (например, у вас не 8к записей, читаете не из той БД, не с теми параметрами и т.п.);
    2) происходит ошибка, но мы ее не видим (смотрим не в тот лог, гдето присобачен обработчик, который перехватывает ошибки и подавляет их сообщения, и т.п.);
    3) скрипт действительно аварийно прерывается без каких либо сообщений об ошибках (значит чтото дает команду на это, если самовредительством не занимались, то остается только oom killer, но вряд ли у вас безлимит на память php, и то что закончилась память вы бы заметили, так что очень маловероятно);
    4) неведомая хрень (баги в php, в ОС и хз что еще, еще менее вероятно, чем п3).
    Ответ написан
  • Почему появляется Typed property must not be accessed before initialization?

    @Vitsliputsli
    1. Разве по умолчанию свойства не null?
    2. У меня 20-30 свойств. Для каждого что-ли делать так? Код какой-то не логичный и громоздкий.

    1. Нет, в данном случае у свойства нет значения, оно не инициализировано. Какое значение вы хотите получить из свойства, если у свойства нет значения? То, что php в некоторых случаях при отсутствии типов выполняет неявное приведение к null не распространяется на ситуации, когда вы явно указали типы, а значит хотите явного поведения.
    А вот Null - это уже значение, которое используется для передачи отсутствия значения как значение.

    2. Если заботитесь о качестве кода, то да. Все абсолютно логично, php подсказывает вам, что вы вероятно забыли инициализировать переменную, т.е. допустили ошибку, обратившись к переменной раньше, чем положили в нее значение.
    Здесь нет ничего "громоздкого", просто вы явно описываете поведение. Можете этого, конечно, не делать, например не использовать указание типов и расчитывать на то, что php сам что-нибудь подставит - но, очевидно, это ненадежный путь, ведущий к ошибкам.
    В идеале, вы должны задать свойству корректное значение, а затем его использовать. Т.е. использовать 1 единственный тип. Не всегда логика это позволяет и тогда нужно инициализировать переменную значением null.

    Хороший код тот, который очевиден и понятен с первого взгляда, а не в котором мало букв. Указывая типы вы всегда знаете что за тип лежит в конкретной переменной и вам не нужно продумывать обработку других типов. Даже когда вы пишете ?int, значит кроме целого числа там еще и null может быть, и это придется учитывать при всех манипуляцих с этой переменной. И вот это, и будет делать код более сложным. А если вы не сделаете обработку всех доступных типов, тогда поведение кода может стать непредсказуемым.
    Ответ написан
    Комментировать
  • Простой пример «замены» ключа массива через ArrayIterator?

    @Vitsliputsli
    Приведите, пожалуйста, простой пример, как, именно «заменить» ключ (числовой на строковый) в массиве.

    Если не вникая, на кой это нужно, то так:
    unset($array[1]);
    $array['first']=1;


    Для массивов есть итератор foreach и не только, зачем вам ArrayIterator?
    Ответ написан
    2 комментария
  • Как в PHP использовать в родителе константу или статическую переменную из потомка?

    @Vitsliputsli
    Если вопрос как правильно - то никак, а вредные советы уже предложили. Вы не должны обращаться из родителя к внутренностям потомков, это нарушает весь смысл наследования и создает циклически зависимые классы. Если вам нужно, чтобы какой-то объект управлял другими объектами - то наследование тут не нужно, управляющий и управляемые не родственные объекты (а если даже и родственные, то управление все равно никак не связано с родственными связями). А если нужно чтобы обобщенный метод родителя работал с данными или методами потомка - есть позднее статическое связывание.
    Ответ написан
    Комментировать
  • Как вытащить строку из текста?

    @Vitsliputsli
    Используйте регулярные выражения, в зависимости от вариативности текста, от обобщенного:
    /<b>(.*)<\/b>/
    до более узкого:
    /\(длина, ширина, высота\): <b>(\d+ x \d+ x \d+)<\/b> см. /
    Ответ написан
    Комментировать
  • Как распознавать в php слова (типо систем компьютерной алгебры)?

    @Vitsliputsli
    Берете транслятор, если на основе php, то например phplrt. И пишите грамматику вашего языка. Перед написанием рекомендую прочитать "книгу дракона", это прям библия компиляторов, как минимум главы про грамматику.
    Ответ написан
    Комментировать
  • Почему global не действует на переменную, инициализированную во внешней функции?

    @Vitsliputsli

    Почему следующий код на PHP печатает 7, а не 12?

    Потому что это не js. А global работает ровно так как описано в доке, по-другому никак, т.к. область видимости работает иначе в языке.
    А делать надо так, чтобы функция внутри себя не обращалась с произвольными данными извне, только с теми, которые вы заранее объявили. Только так можно контролировать код. А значит global не нужен.
    Ответ написан
    Комментировать
  • Как вынести запросы rest api на постоянное соединение?

    @Vitsliputsli
    Хочется вынести одно постоянно соединение api(или части запросов) на одно постоянное соединение. Остальной сайт и странички будут работать с множественными соединениями.

    Выделите для api отдельный пул php-fpm воркеров из 1 штуки.
    Ответ написан
    Комментировать
  • Как перехватить все существующие типы исключений?

    @Vitsliputsli
    Я их ловлю не для того, чтобы вывести, а чтобы отправить себе в телеграм.

    Тогда просто настройте парсинг логов. Держать такую логику в обработчике исключений сомнительная затея, не говоря уже о том, что ошибка может произойти до регистрации обработчика, или в самом обработчике.
    А лучше настройте нормальную визуализацию ошибок, например Elastic+Kibana, а там уже по создавайте алерты по которым будут кидаться сообщения в телеграм. В сообщении будет просто ссылка на лог в Кибане, где можно будет увидеть не только ошибку, но и что ей предшествовало.
    Ответ написан
  • Почему PHP не исполняется построчно, хотя он интерпретируемый?

    @Vitsliputsli

    Интерпретируемые языки исполняются построчно

    Неа, интерпретируемые языки это те, которые исполняются не машиной, а программой-интерпретатором.
    Работа php скрипта начинается с парсинга кода. Проводится лексический и грамматический анализ. Будет ли использоваться какой-либо промежуточный байткод здесь пока не важно.
    В вашем примере, php парсер обнаружил неизвестную продукцию и сразу же кинул ошибку. Можно было, конечно, выполнить код до последней корректно определенной продукции, но зачем? Php старается уходить от устойчивости к стабильности, т.е. от "отработать хоть както" к "отработать обязательно корректно". "Хоть както" все равно можно, но это должен быть сознательный выбор.
    И, хотя в php нет предварительной компиляции, тем не менее ошибки синтаксиса легко обнаруживаемы при запуске, поэтому логично о них сообщать сразу.
    Что касается, зачем анализировать весь код, а не построчно, то это тупо быстрее даже без байткода, и дает преимущества по оптимизации. Например, если вы объявили переменную и присвоили ей значение, а дальше в коде нигде ее не меняли, то php сделает ее константой.
    Ответ написан
  • В чем может быть причина разницы результатов запроса в PDO и SQL(разница формата дат)?

    @Vitsliputsli
    to_date(date_begin::text, 'DD.MM.YYYY'::text)

    т.е. у нас есть поле date_begin в формате datetime, а мы его кастуем в текст. Затем из текста по какому-то непонятному формату получаем дату.

    А все это работает скорее всего потому, что в php при подключении к БД используется формат даты 'DD.MM.YYYY', поэтому эта бредятина работает, а когда напрямую подключились к базе, там вероятно дефолтный 'YYYY-MM-DD' и получается чушь на выходе.

    В общем удалите эту дикость и посмотрите как в PostgreSQL нормально получить date без промежуточного преобразования в строку.
    Ответ написан
    1 комментарий
  • Как сокращенно записать условие в случае если значение не пустое?

    @Vitsliputsli
    Если someFunction возвращает bool, то
    if (someFunction(.....)) {
      doSomething();
    }

    Если не bool, то прописать условие.
    Ответ написан
    Комментировать
  • Ratchet WebSocket прошу посмотреть код с точки зрения нагрузки?

    @Vitsliputsli
    Проверьте, эмулируйте соединения.
    Скорее всего остановится в районе 1000. Тогда проверьте колво файловых дескрипторов на процесс. Либо увеличивайте их колво, либо запускайте несколько процессов, либо используйте другой язык.
    10к-20к - это много для одного процесса, если подразумевается, что они все одновременно ломанутся за подключением, то большинство будет долго ждать, и не секунды, а минуты.
    В коде логики практически нет, так что не должно из-за нее напрягаться. Хотя я особо не вчитывался, условия с неявными преобразованиями, ужасные названия переменных (типа $arrayCount[$items]) очень сильно мешают вникать.
    Ответ написан
    Комментировать
  • Почему возникает утечка памяти в php-fmp?

    @Vitsliputsli
    Утечка - это когда процесс не пользуется памятью, но и не высвобождает. По вашему описанию, php-fpm прекрасно использует память для других скриптов, а также высвобождает при необходимости. Т.е. это не утечка.

    Чтобы утечка проявила себя более явно установил memory_limit = 1G

    Выделение памяти операционкой это медленный процесс, поэтому при возможности выгоднее запросить побольше, вы выставили лимит в 1G, почему бы не зарезервировать сразу 18%.

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

    @Vitsliputsli
    Надим Закиров, никак, клиентские данные генерируются клиентом, а значит он может сгенерить все что ему вздумается. Если отправляемые данные будут генерироваться особым образом, то это лишь немного усложнит задачу, клиент сгенерирует и такие данные.
    Ответ написан