Профиль пользователя заблокирован сроком с 10 апреля 2022 г. и навсегда по причине: систематические нарушения правил сервиса
  • Азы программирования с чего начать?

    saboteur_kiev
    @saboteur_kiev Куратор тега IT-образование
    software engineer
    Изучением как работают поисковые системы, как в них находить нужную информацию.

    Информация не просто есть, ее слишком много, поэтому да, сейчас искать сложнее, чем 10-20 лет назад.
    Сейчас полно спама, полно текста состоящего из воды.

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

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

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

    @MaLuTkA_UA
    Раз вы начали работать с workerman нужно было почитать документацию как и что там делать, и зайти на гит и почитать ответы разработчика на вопросы, там много полезного. Увы ваша реализация на сколько я понял не правильна, так как если запустить воркерман в несколько потоков у вас будут проблемы с поиском соединения, также для того чтобы отправить данные в сокет вам нужно в каждом процессе открыть TCP соединение через которое и будет происходить отправка сообщений, это тоже есть в их документации.
    Ответ написан
    Комментировать
  • Почему пользователь Симфони (или Докера?) называется 82?

    glaphire
    @glaphire
    PHP developer
    Это пространство системы, симфони тут ни при чем)
    82 это айди юзера www-data в alpine.
    Ответ написан
    4 комментария
  • Попинайте 2. Удалось ли исправить устаревший код, который забраковал работодатель?

    @Flying
    Согласен с FanatPHP по поводу того что изменения, по сравнению с предыдущим вариантом, просто колоссальные, поздравляю!

    Однако сразу видны те направления движения которые стоит рассматривать в первую очередь:

    1. Вам стоит лучше изучить возможности языка. PHP развивается очень динамично и в 7-й версии было добавлено огромное количество вкусных возможностей, про них стоит знать и ими стоит пользоваться
    2. Необходимо лучше изучить имеющуюся на данный момент экосистему готовых пакетов, это позволит вам использовать готовые, проверенные решения вместо изобретения своих велосипедов. Подключение Twig - первый шаг, но далеко не последний
    3. Вам обязательно стоит посвятить время изучению кода популярных проектов. Это многое может рассказать вам о подходах к решениям, паттернах и т.п. Конечно, параллельно нужно будет выяснять значения массы используемых терминов чтобы лучше понимать происходящее, это тоже пойдёт вам на пользу.
    4. Смотрите как развиваются другие технологии, которые вы используете, таблицами сейчас не верстают :)
    5. Рекомендую рассмотреть вариант использования для написания кода нормальной IDE, к примеру PHPStorm, это существенно улучшит вашу производительность и убережёт от массы ошибок


    Теперь более предметно:

    Оформление кода:

    Вы утверждаете что код соответствует PSR-2 (кстати, актуальный - PSR-12), однако есть мелкие огрехи (раздел 2.2).

    Оформление composer.json:

    Лучше указывать требования к платформе, в вашем случае - как минимум версию PHP т.к. platform requirements проверяются Composer'ом при установке.

    Поскольку ваш проект - не библиотека, то composer.lock тоже должен быть частью репозитория.

    Про настройки autoload'а вам уже сказали, обращу только внимание на то что сейчас структура репозитория отражает PSR-0, а не актуальный PSR-4, при использовании PSR-4 ваш код проекта лежал бы в src.

    Организация репозитория

    Код проекта должен лежать за пределами web root, поэтому вам явно не хватает папки public с единственным index.php

    Конфигурация

    Конфигурирование через константы - весьма устаревший подход. К примеру представьте что вы разворачиваете этот код на production сервере и вам нужно сменить данные для подключения к базе данных не создавая локальных изменений в рабочей копии. Сейчас у вас это не получится. Выход: читаем про
    12 factor app и, в частности, раздел config, а затем подключаем в проект, к примеру, vlucas/phpdotenv или symfony/dotenv

    Сервисы

    Использование bootstrap.php - хорошо, но для организации работы с сервисами сейчас как правило используются dependency injection контейнеры, даже PSR-11 для них есть. В текущем виде ваш подход слабо расширяем, а передача сервисов через глобальные переменные - так себе идея по многим причинам.

    Понятно что вворачивать DI container для примера на три файлика - overkill, но с самим подходом вам следует ознакомиться. Из реализаций самая популярная сейчас - symfony/dependency-injection, но есть и альтернативы.

    Автолоадер

    Про autoload.php вам уже сказали, вместо него стоит корректно конфигурировать автозагрузку в composer.json и полагаться на то что Composer вам сгенерирует. Он ведь умеет всё это и оптимизировать при необходимости.

    Внешние пакеты

    Для новых проектов рекомендуется выбирать актуальные и поддерживаемые версии пакетов. Хотя Twig 1.x ещё поддерживается, тем не менее актуальная версия - 3.x.

    Обработка ошибок

    Попробовать сделать это самостоятельно, безусловно, полезно чтобы лучше разобраться как это работает, но для реальной работы лучше полагаться на проверенные решения, к примеру filp/whoops или symfony/error-handler

    Типы данных

    Важно помнить что PHP с версии 7.0 поддерживает указание скалярных типов для аргументов и
    возвращаемых значений, с 7.1 - nullable типы и class constant visibility, а с 7.4 - типизированные свойства. Всё это гораздо надёжнее чем описание типов через аннотации и этим стоит пользоваться.

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

    Data Objects

    Сейчас Place и PlaceFilter по сути являются data объектами т.е. они не содержат самостоятельной логики, а просто переносят некие данные. При этом оба этих класса имеют пустые конструкторы (которые, кстати, лучше убирать), а загрузка данных организована через setter методы. Это позволяет изменить данные в них в произвольные моменты времени что вряд ли является желаемым поведением. Вместо этого подобные объекты лучше организовывать в виде immutable объектов (статья с примерами) чтобы не позволять ненужного нарушения целостности данных. Альтернативно, к примеру, для PlaceFilter может лучше подходить использование паттерна
    Builder
    , хотя в википедии не самый лучший пример.

    Именование

    Все мы, надеюсь, помним про две сложные проблемы, здесь как раз проявляется вторая из них. PlaceFactory ну никак не является реализацией одноимённого паттерна.

    Оптимизации

    Понятно что это мелочи, но явно видно что компиляцию запросов (1, 2) можно кэшировать вместо того чтобы перекомпилировать каждый раз.

    References

    PDOStatement::bindParam() принимает аргумент $variable как reference, а в коде в этот аргумент передаётся выражение что недопустимо.

    Английский язык

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

    @Vitsliputsli
    Или в операциях == и != что-то не так?

    Используйте операторы сравнения === и !==, и сравнивайте с учетом типа переменных.
    0 не равен false, но при динамичской типизации, будет произведено приведение типов и затем сравнение.
    Чтобы не возникало вопросов, таких как у вас сейчас, сравнивайте однотипные данные, а не предполагая, что будет после динамического приведения типов.
    Ответ написан
    7 комментариев
  • Почему файл не подключаеться через require?

    SilenceOfWinter
    @SilenceOfWinter Куратор тега PHP
    та еще зажигалка...
    ты должен на сервере
    1. создать composer.json с sdk в require секции
    2. закачать composer.phar
    3. запустить консоль и выполнить установку
    Ответ написан
  • Что делать если json свойство начинается с цифры?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    $data = '{"1st_half": 55}';
    $data = json_decode($data);
    
    var_dump($data->{'1st_half'});
    Ответ написан
    Комментировать
  • Почему не работает require?

    toxa82
    @toxa82
    require у вас работает, иначе ругалось бы на нём. Вы вызываете $pdf=new FPDF(); находясь в нэймспэйме app\models, надо вызывать так $pdf=new \FPDF(); или указать название класса FPDF с нэймспэйсами если у него они есть
    Ответ написан
    Комментировать
  • Чем плохо выносить повторяющиеся элементы дизайна в отдельные файлы и подключать их потом с помощью PHP?

    delphinpro
    @delphinpro Куратор тега PHP
    frontend developer
    Тем, что в случае использования php вам совершенно ничего не мешает подрубить шаблонизатор, например twig, и делать разбивку страницы более или менее красиво.

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

    base.twig
    <html>
    <head></head>
    <body>
      <header>...</header>
      <main>{% block main %}{% endblock %}</main>
      <footer>...</footer>
    </body>
    </html>


    index.twig
    {% extend 'base.twig' %}
    {% block main %}
      Главная страница
    {% endblock %}


    about-us.twig
    {% extend 'base.twig' %}
    {% block main %}
      Интереснейший текст о компании
    {% endblock %}
    Ответ написан
    1 комментарий
  • Почему не работает код?

    index0h
    @index0h
    PHP, Golang. https://github.com/index0h
    1. НИКОГДА не публикуйте креды к базе!
    2. Не используйте подстановку данных в запрос через конкатенацию. Вместо этого используйте плейсхолдеры.
    Пример 1 (SQL инъекция):
    # Тут заэнкожено: '; DROP TABLE `users`; --
    curl -XPOST -H 'Content-type: application/x-www-form-urlencoded' -d'phone=%27%3B%20DROP%20TABLE%20%60users%60%3B%20--'

    Пример 2 (phone может содержать массив):
    curl -XPOST -H 'Content-type: application/x-www-form-urlencoded' -d'phone[]=+123'

    3. Не используйте глобальные переменные. Про это есть множество статтей.
    4. Если есть возможность - используйте \PDO, вместо mysqli.
    5. Не стоит объявлять функции/классы/трейты/интерфейсы по условию. Вместо этого используйте их по условию, но объявляйте без него.
    6. При работе с путями рекомендую пользоваться глобальными, вместо относительных, иначе этот самый путь будет зависеть от скрипта, с которого запустили ваш код, а не от того, где происходит работа с файлами.
    7. У вас конкурентно не безопасный код за счет того, что работа с файлами происходит в одном и том же каталоге, с одними и теми же именами файлов. Что будет если запустить два запроса одновременно на вытяжку всех пользователей? В лучшем случае один из запросов просто упадет с ошибкой что не может добавить в архив файл (это второй поток его уже удалил). Если будет запущено 2 запроса например на 1го пользователя и на всех - есть вероятность, что один из них вернет далеко не запрашиваемые данные)).
    8. Очень рекомендую разделить вашу обработку на 2 части:
    - Первая пусть записывает в файлики данные по пользователям при обновлении данных этих пользователей.
    - Вторая - вытягивает вытягивает только id требуемых для архивирования и уже добавляет их в архив. Имя архива стоит делать рэндомным, что бы избежать конкурентного доступа к одному и тому же файлу на запись.
    9. getUserses -> getUsers

    Конкретно по вашей проблеме: если я праивльно понимаю, вы в один и тот же архив запихиваете файлы на каждый запрос, грубо говоря один раз вытянув всех пользователей - дальше вы только обновляете их в архиве на 10к файлов, а не создаете новый архив.
    Ответ написан
    3 комментария
  • Phpmailer-это старье?

    DevMan
    @DevMan
    последний релиз был 2 недели назад – жуткое старье.
    пользуются.
    Ответ написан
    2 комментария
  • Как получить полный адрес поста и добавить его в базу?

    @kandrash
    Кратко о себе
    Вам это не нужно. Достаточно добавить accessor в модель.
    /**
     * Полный адрес поста.
     *
     * @return string
     */
    public function getFullAddressAttribute()
    {
        return url("/{$this->user_id}/post/{$this->id}");
    }
    
    // Использование
    $post->full_address;
    Ответ написан
    2 комментария
  • Вопрос инженерам оптикам, можно ли создать линзу/адаптер для установки MFT объектива на EF камеру?

    kawabanga
    @kawabanga
    Не вижу ни одной причины использовать это. Даже если у вас киношные дорогие объективы. Так люди бесились году в 2008-9, когда только 5dmII вышел.
    Сейчас я бы дал предпочтение хорошей картинке со стабом, чем в 2010х, когда у меня на каждый пчих был по объективу (18,35,50,85,135).

    Конкретно по вашему вопросу, есть два решения,
    1) использовать специальные адаптеры, добавляющие линзу посередине. По этому вопросу может подсказать Андрей Крамар, занимается созданием анамарфотных линз.
    2) Удалить зеркало. Так заморачивались раньше, не помню названия серии киношных объективов этих ( как бы не compact prime от цейсов на super 35), но почти каждый киношник хотел такой апгрейд. И немногие ставили.
    И то и другое решение потребует временных и денежных трат минимум в $500. Я бы тушку купил дополнительную под задачи необходимые. Тот же blackmagic pocket.
    Ответ написан
    Комментировать
  • Как сделать так чтобы при нажатии кнопки добавлялось значение ?sort=p.price&order=DESC в конец строки?

    Seasle
    @Seasle Куратор тега JavaScript
    Как вариант:
    const toggleOrder = () => {
      const params = new URLSearchParams(window.location.search);
    
      params.set('order', params.get('order') === 'DESC' ? 'ASC' : 'DESC');
      window.location.search = params.toString();
    };

    Пример. Код.
    Ответ написан
    Комментировать
  • Как перенести самописный движок на вордпресс?

    glaphire
    @glaphire
    PHP developer
    Это будет просто написаная с нуля тема на вордпрессе, которая повторит функционал движка, т.е. тут это сложно назвать переносом, потому что от старого кода ничего не останется
    Ответ написан
    Комментировать
  • Как разбить get запрос и занести все в свои переменные?

    bigton
    @bigton
    Web-программист
    Дано ["REQUEST_URI"]=>"/classpr.add?count=1&v=4"

    1. Берем $_SERVER['REQUEST_URI'] прогоняем через parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH) так вы получите часть classpr.add

    2. Все что после знака вопроса, автоматически располагается в $_GET

    Безопасность

    1. НЕ используйте extract() за такие советы надо банить!
    2. Не доверяйте ничему, что получаете от пользователя (POST, GET, COOKIE, etc), ничего напрямую не вставляйте в базу, не пытайтесь вызвать и тд.

    Вместо $_GET['count'] используйте filter_input(INPUT_GET, 'count', FILTER_VALIDATE_INT).

    Пусть (classpr.add) прогоните через регулярку if ( ! preg_match('~^/([a-z0-9.]*)$~', $path, $matches)) return false;
    Ответ написан
    Комментировать
  • Почему выводится только первый подходящий элемент массива?

    nokimaro
    @nokimaro
    Меня невозможно остановить, если я смогу начать.
    Ошибка в том что return прерывает выполнение цикла так как завершает выполнение функции.
    https://www.php.net/return
    Ответ написан
    2 комментария
  • Как спрятать обратный слеш?

    @Redeve
    Веб-макаке не хватит и 640гБ
    Вы как-то неправильно отдаете джсон...
    $response = [ 'success' => $success, 'status' => $status, 'message' => $message . $addParams ];
    echo json_encode($response);


    Ну а слеши у вас, как уже сказали до меня - не выводятся. Всё ок
    Ответ написан
    Комментировать