Ответы пользователя по тегу PHP
  • Вопрос с собеседования: Есть ли в PHP нативная возможность инициализировать переменную как в функции preg_match()?

    neuotq
    @neuotq
    Прокрастинация
    Вас проверяли на знание того, как передаются переменные в функция в php. Переменные передаются всегда по значению, те передаёте переменную в функцию, туда копируется в новую переменную значение оригинальной.

    С помощью амперсанда & мы можем заставить передавать ссылку на эту же переменную в памяти. И тогда манипуляции с ней внутри функции будут равны манипуляциям вне.

    С объектами не большая путаница происходит, но только из-за того что многие не думают/забывают что хранится в переменной когда создаётся объект. При создании объекта в саму переменную помещается его идентификатор, по которому php и обращается к этому объекту.
    Ну и соответственно при передаче такой переменной в функцию, мы копируем этот идентификатор в новую переменную. Переменная уже другая, независимая от той что была, но идентификатор объекта тот же. Поэтому манипуляции с объектом в функции(обращение к свойствам/методам) отразятся на объекте с этим идентификатором. И со стороны выглядит словно переменная с объектом всегда передаётся по ссылке(словно стоит амперсанд), но это не так. Например внутри функции вы перезапишете переменную(к примеру присвоите null) то оригинальная переменная с объектом не поменяется.

    А вот есть если передать её по ссылке, те с амперсандом, то внутри функции будет переменная со ссылкой на переменную вне, и поэтому не только манипуляции с объектом, но и перетирание переменной в целом повлияет.

    class A {
        public $foo = 1;
    }
    
    //создали переменную
    //в ней хранится id объекта, сам объект где-то в памяти оптимизированно лежит
    $newObj = new A;
    
    //Вывод 1
    echo $newObj->foo;
    
    function foo($obj) {
    	//в obj скопирован id объекта
    	//тк он тот же, то меняется и оригинальный объект
    	$obj->foo = 2;
    	//локальная переменная перетёрся, больше id объекта не хранит
    	//на внешнюю не повлияло
    	$obj = null;
    	
    }
    
    foo($newObj);
    // получили 2
    echo $newObj->foo;
    
    
    function bar(&$obj) {
    	//obj ссылается на тоже место в памяти, что и внешняя переменная с id объета
    	//тк он тот же, то меняется и оригинальный объект (тут логично, тк по ссылке)
    	$obj->foo = 2;
    	//локальная переменная перетёрся, больше id объекта не хранит
    	//внешняя тоже перетрётся
    	$obj = null;
    }
    
    
    bar($newObj);
    //ошибка предупреждение, нельзя читать свойства на null
    echo $newObj->foo;


    Ну и зная всё это, вы можете написать свою простую функцию, по типа прегматча.
    function mySum($a, $b, &$result) {
    	$result = $a + $b;
    }
    //первые два параметра по значению, в третий передаём переменную
    //она тут же инициализируется (как если бы её до этого написать просто $res;)
    // и передаётся её ссылка внутрь функции
    mySum(1,2, $res);
    
    //3
    echo $res;
    Ответ написан
    Комментировать
  • Почему не удается получить доступ к смещению типа string в строке?

    neuotq
    @neuotq
    Прокрастинация
    Сама ошибка вполне однозначная, вы обращаетесь к строке по индексу.
    У вас в коде в строке 30:
    $aUnit[$server['unit']][$server['game']]
    Но выше мы видим что
    $aUnit[$unit['id']] = '';
    Ну так делать нельзя. В PHP 7* на этот счёт были предупреждения, видимо вы их игнорировали.
    Ответ написан
    5 комментариев
  • Как задать следующий вопрос chatGPT по API?

    neuotq
    @neuotq
    Прокрастинация
    Контекст вы должны сохранять, а передавать в следующем запросе через роли.
    Простое объяснение тут, пример оттуда:

    completion = openai.ChatCompletion.create(
      model="gpt-3.5-turbo", 
      messages = [
    # system - системная базовая роль, грубо говоря это сама база "Я" gpt
    {"role": "system", "content" : "You are ChatGPT, a large language model trained by OpenAI. Answer as concisely as possible.\nKnowledge cutoff: 2021-09-01\nCurrent date: 2023-03-02"},
    # user - роль юзера кто задаёт вопросы
    {"role": "user", "content" : "How are you?"},
    # Асистент одна из ролей, можно задать ранее в запросе, типа Act as bla blah
    # либо он поймёт что должен быть именно ассистентом смотрите оп ответу в API
    {"role": "assistant", "content" : "I am doing well"},
    # Снова юзер
    {"role": "user", "content" : "How long does light take to travel from the sun to the eart?"}]
    )


    Ну и примерно так строишь цепочку. Ну и да, ресурсо(читай денежно) пожирающе, а что делать. Значит приносить $$ должно больше чем тратится.
    Ответ написан
    Комментировать
  • Почему у некоторых людей не работает сайт при переходе из инстаграм?

    neuotq
    @neuotq
    Прокрастинация
    Я бы смотрел в сторону VPN которые используют люди.
    Cloudflare будет грузиться и показывать хоть что-то, даже есть доступ к ресурсу запрещен.
    Поэтому остаются сетевые проблемы и задержки/таймауты из лагов VPN. У народа часто фигня разная стоит.
    Поэтому этот пресловутый белый экран как раз таки и показывает проблемы с отправкой/получением данных. Бразуер(не важно встроенный или нет) будет в таких случаях частенько висеть.
    Попробуйте несколько дней потестить с включенными бесплатными разными VPN из топа Маркета/Апстора. Проследить статистику. Особенно полезно это сделать на мобильном интернете среднего качества с просадками, а не на стабильном wifi
    Ответ написан
    Комментировать
  • Есть ли список распространённых и общепринятых слов для именования переменных в PHP?

    neuotq
    @neuotq
    Прокрастинация
    Нет, специальных договорённостей общепризнанных нет, кроме:
    • понятное название по контексту, не использовать однобуквенные. Лучше целые слова/сочетания слов либо известные всем сокращения.
    • с маленькой буквы, в регистре CamelCase (если несколько слов)
    • название классов с большой буквы.


    $variableNameExample = "Hi Im the best of the best";
    Ответ написан
  • Если изменить значения в конфигурационном файле uploads.ini нужно запускать билд контейнеров или перезагружать и почему?

    neuotq
    @neuotq
    Прокрастинация
    Если упрощенно:

    1. Есть сущность образ - image. Его можно скачать, собрать свой и т.д.
    2. Есть контейнер - он запускается из образа, на основе данных/правил, которые в нём (образе) прописаны.
    3. Контейнер работает, вы в нём что-то делаете, меняете значения и т.д. НО сам образ, на основе которого он сделан, не изменяется. Поэтому при перезапуске контейнера изменения как бы "пропадают". Но на самом деле вы просто запустили контейнер на основе вашего изначального образа.
    4. Есть несколько способов:
      1. Закоммитить изменения в новый образ, который создаётся на основе текущего контейнера.
      2. Подключать внешние диски внутрь контейнера, и на них уже сохраняется информация вне образа и контейнера, а не на пользовательском диске (в облаке или где угодно).


    5. Способ выбирается в зависимости от контекста. В вашем случае, вероятно, правильно будет сделать новый образ, в котором эти настройки будут "вшиты", и контейнер Docker будет запускаться уже с нужными вам uploads.ini.


    Поэтому гуглим доки.

    Если кратко:
    #Получаем наш образ базу
    sudo docker pull mycool_image
    
    #смотрим чё там по образам, видим айдишник нашего
    sudo docker images
    
    #Запускаем в интерактивном режиме, с входом в баш (пример условный)
    sudo docker run -it hash_of_mycoll_image bin/bash
    
    #редактируем и потом сохраняем в нем наш файлик настроек
    nano /path/to/uploads.ini
    
    #Выходим
    exit
    
    #Смотрим список запущенных контейнеров и видим там наш родимый с изменениями
    sudo docker ps -a
    
    #Сохраняем(комитим) изменения в докер контейнере в НОВЫЙ образ
    sudo docker commit hash_of_DOCKER_CONTEINER mycool_image_with_uploads_ini
    
    #Смотрим список образов с сохраненным нашим новым образом, 
    #теперь можем запускать контейнер на его основе
    sudo docker images

    Примерно так. НО всё же, вперёд читать документацию.
    Ответ написан
    Комментировать
  • Как обеспечить идемпотентность запросов к API?

    neuotq
    @neuotq
    Прокрастинация
    С кукисами и прочим оставьте это на стандарты что уже вам даёт WP(и/или плагины что вы там используете).
    После нажатия купить, у вас создаётся запись о покупке в БД, со статусом не оплачен. У покупки во всех системах для создания инет магазинов и тп уникальный айди, вот на основе его и можно генерировать уникальный (допустим
    с помощью crypt) ключ идемпотентности.
    После успешной оплаты в БД статус меняется на оплчен и этот заказ и его айди больше никогда не используется. Даже при повторной покупке это будет уже клон этой, но с новым айди.
    Таким образом и себя защитите и в целом простое и относительно надёжное решение.
    Могут быть нюансы только когда оплата прошла, а ваш сервис это узнать через обратный webhook не смогла(допустим был лаг и тп) и запись в БД не стала - оплачен. Но обычно платёжные шлюзы даёт проверять статусы оплаты и по запросу, поэтому если не приходит ответ там в течении какого-то времени, можно запрашивать в ручную. Ну и затем в любом случае устаревает запрос на оплату(почти во всех платёжках есть тайм аут на то, в какое время можно оплатить уже после создания инвойса на их стороне), так что и тут в целом все норм.
    Ответ написан
    4 комментария
  • Почему возникает утечка памяти в php-fmp?

    neuotq
    @neuotq
    Прокрастинация
    В прошлом месяце была большая дискуссия(а началась ещё год назад), закрывали пару багов в 8.1/8.2, пока ещё не в релизной версии.
    Ответ написан
    4 комментария
  • Wordpress - Как передавать в форме данные: "Откуда пользователь перешел на сайт"?

    neuotq
    @neuotq
    Прокрастинация
    В форминаторе есть похожий функционал, с помощь. скрытого поля можно реализовать, вот здесь документация. Попробуйте может вам подойдёт.
    Ответ написан
    Комментировать
  • Как на php показать какой отрезок времени назад был опубликован пост?

    neuotq
    @neuotq
    Прокрастинация
    Используйте библиотеку Carbon
    $postTimestamp = '2023-01-01 00:00:01';
    echo Carbon::parse($postTimestamp)->diffForHumans(Carbon::now());
    // "5 days before"
    
    //Локализация
    Carbon::parse($postTimestamp)->locale('ru')->diffForHumans(Carbon::now());

    Только изучите документацию подробнее, важно чтобы даты были в одном часовом поясе лучше всего хранить в UTC 0 и соответственно сравнивать тоже в нем. А уже если нужно вывести конкретную дату(дату и время, а не разницу), то тут перед выводом делать смещение, Carbon это тоже умеет.
    Ответ написан
    Комментировать
  • Как сравнить такой массив?

    neuotq
    @neuotq
    Прокрастинация
    Пункт 0. Возможно есть способ сравнивать на этапе формирования нового массива и как то это хранить/помечать?
    Пункт 1. Не мучайте себя и других, а пробуйте поискать готовые библиотеки, например эту:
    array-diff-multidimensional
    Ответ написан
  • Как сделать чтобы curl срабатывал раньше?

    neuotq
    @neuotq
    Прокрастинация
    Есть функция sleep()
    //SOME CODE
    // sleep for 10 seconds
    sleep(10);
    //SOME CODE AFTER 10 seconds PAUSE

    Но это так себе подход, де факто блокирующий выполнение скрипта(условно как подвис, хотя конечно другое).
    Ответ написан
    Комментировать
  • Как будет лучше написать проект в портфолио, на чистом php или фреймворке?

    neuotq
    @neuotq
    Прокрастинация
    Если очень кратко - фреймворк и это Laravel.
    А если чуть подробней, то важнее показать, что решаешь конкретную проблему, можно даже взять какую-либо среднею проблему из популярных с задач/запросов на фриланс биржах.
    Показать, что понимаешь построение базовой структуры проекта, основные принципы проектирования (условные SOLID) и решаешь определенную задачу приносящую понятную очевидную пользу.
    Последнее тоже важно. Иногда пишут запудренные, оверинжиниринг штуки, но что она решает и зачем нужно ещё разобраться. А тут и понятная проблема, понятное решение, относительно красивый и понятный код.
    Ответ написан
  • Как правильно распарсить дату с временными зонами в Laravel?

    neuotq
    @neuotq
    Прокрастинация
    Зачем что-то парсить лишний раз. У вас приходят даты в UTC (Z в конце говорит об этом).
    Карбон отлично всё создаёт из этой строки
    $tm = Illuminate\Support\Carbon::create('2022-05-01T07:00:00.000Z');
    /*
    Illuminate\Support\Carbon @1651388400 {#4888
         date: 2022-05-01 07:00:00.0 +00:00,
       }
    */
    В базе мы тоже(надеюсь) храним в UTC
    <code lang="php">
    $tm->setTimeZone('Europe/Moscow');
    /*
    => Illuminate\Support\Carbon @1651388400 {#4887
         date: 2022-05-01 10:00:00.0 Europe/Moscow (+03:00),
       }
    */
    $tm->setTimeZone('Europe/London');
    /*
    => Illuminate\Support\Carbon @1651388400 {#4887
         date: 2022-05-01 08:00:00.0 Europe/London (+01:00),
       }
    */
    </code>
    Ответ написан
    5 комментариев
  • Как сделать приватные поля в ларавеле?

    neuotq
    @neuotq
    Прокрастинация
    UPD Как правильно заметил товарищ vism я тут немного чуши написал по инерции. Не посмотрел куда дал ссылку. Там в примере главная проблема что человек из репозитория снова таки возвращает саму элокуент модель, а хорошо бы DTO - Data Transfer Object. Посмотрите пакет от Spatie https://github.com/spatie/data-transfer-object.

    А в целом ответить на ваш вопрос легче было, если был бы ясен контекст. Зачем приватные поля? Возможно все проще перевести в данные у вас, и это логику "защиты" перенести на уровень валидации. Тогда и ставить ничего не нужно, просто в валидации, где нужно, проверяйте входящие данные и выкидывайте ошибку. Здесь будет и гибкость(где нужно разные влаидаторы) и "магия" Ларавел в целом сохраняется коробочная.
    /---
    Это потому, что Laravel в качестве ORM использует Eloquent, который сделан по паттерну ActiveRecord. Многие считают его антипаттерном. Оставим срачи за рамками.
    Вам подойдёт внедрения подхода с паттерном репозитория .
    Вот простой пример, будет понятно куда копать и как действовать:
    https://www.twilio.com/blog/repository-pattern-in-...
    Ответ написан
  • Существует ли библиотека для трансляции php кода в node.js?

    neuotq
    @neuotq
    Прокрастинация
    Технически сам язык конечно же можно перевести в другой, я думаю даже простенькие функции будут работать.
    НО! Дальше будет куча но. Обычной трансляцией не обоёдешься, так как много подводных камней и особенностей самого API PHP, принципов работы многих встроенных библиотек, хаков, костылей и просто приёмов которые используют люди в своих проектах и тп.
    В таком огромном и сложном проекте как Wordpress этого всего просто нереальное количество.
    Вы же понимаете часто даже код больших проектов, в рамках одного языка(любого) тяжело переводить с версии на новую версию. А тут на другой язык/платформу исполнения кода.
    Это в любом случае ручной труд, а автоматический транслятор вам только будет помогать переводить конкретные конструкции, а так огромное количество ручного труда для каждого файла/класса/функций и тп.
    Технически это возможно, но займёт огромное количество человека-часов, легче с нуля написать.
    Второй вариант найти решение с условной виртуальной машиной, которая исполняет php код внутри js окружения. Были когда-то подобные пакеты, но спроса нет и всё заглохло. Это тоже трудоёмкий процесс, нужно бежать и развивать свою такую штуку.
    Поэтому сегодня есть только условные прокси на node.js, которые запускают php скрипты на php(тем или иным способом, но исполняет их именно php).
    Поэтому мы приходим к технологии WebAssembly, там есть например проект wasmer, с помощью которого можно запускать wasmer-php. Но снова таки, это не трансляция кода, а просто запуск php в среде браузера, js тут уже чисто для управления и запуска самого wasmer...
    Ответ написан
    Комментировать
  • Как сохранить изображение которое генерируется в реальном времени?

    neuotq
    @neuotq
    Прокрастинация
    Короче говоря, сразу отмечу, мне не очень нравится такое вкрапления кода в шаблон, я бы создал свой сервисный класс обертку, но да ладно. Значит у тега a есть свойство download, куда можно дать имя файла(как он будет называться при сохранении) и который браузеру сразу и подскажет что ссылка для скачивания и угадывать что там не нужно, ждать хедеров от сервера и тп тоже не нужно(я упростил объяснение).
    Ваш код должен быть таким:
    <img src="data:image/png;base64, {!! base64_encode(QrCode::format('png')->size(300)->wiFi([
         'ssid' => $this->ssid,
         'encryption' => $this->encryption,
         'password' => $this->password
         ])) !!} ">
         <a 
    download="qr.png"
    href="data:image/png;base64, {!! base64_encode(QrCode::format('png')->size(300)->wiFi([
         'ssid' => $this->ssid,
         'encryption' => $this->encryption,
         'password' => $this->password
         ]))  !!}" class=""></a>

    Как видим, код здесь повторяется и два раза генерируем png, поэтому возможно есть смысл использовать доп переменную что сохранить код картинки и в blade передавать уже только само значение переменной.
    Ответ написан
  • Как вставить в Excel сгенерированный qr?

    neuotq
    @neuotq
    Прокрастинация
    В документации есть пример как добавлять картинки, правда насколько я помню с svg там были некоторые проблемы, но вы потестите. Если что генерируйте png с ним всё ок.
    Код примерно такой будет:
    $qrPath = 'some/path/toqr.svg';
    $qr = QrCode::format('svg')->size(50)->encoding('UTF-8')->generate('MyNotePaper', $qrPath);
    $qrDrawing = new \PhpOffice\PhpSpreadsheet\Worksheet\Drawing();
    $qrDrawing->setName('MyNotePaper');
    $qrDrawing->setDescription('MyNotePaper');
    $qrDrawing->setPath($qrPath);
    $qrDrawing->setWorksheet($sheet->getActiveSheet());
    $qrDrawing->setCoordinates('AE48');
    Ответ написан
  • На чем исполнять несложный интернет-магазин?

    neuotq
    @neuotq
    Прокрастинация
    Советую брать что-то готовое. Потому как если проект будет живой и работать, в любом случае будут вылезать те или иные косяки, недоработки и т.п.
    Так что берите например тот же вукомерс, базовый набор и вперед.
    По умолчанию ничего сложного, куча всего уже готово(интеграции и проч) легко кастомизируется. Это же можно сказать и про многие другие.
    Либо вообще выбрать платформу вроде insales.
    Писать свое не рекомендую. Тем более если условно простое. Больше смысла писать свой продукт под нечто большое, с уникальными требованиями и тп, на что потом будут готовы выделять ресурсы. А так будет просто мертворожденное решение и проблема у владельцев если нужно что-то допилить.
    Ответ написан
    2 комментария
  • Почему никогда не выполняется первое условие?

    neuotq
    @neuotq
    Прокрастинация
    У вас в форме нет ничего что передаёт $_POST['text'], текстареа у вас с именем message, поэтому если вы перепутали то замените на $_POST['message'].
    Ответ написан