Ответы пользователя по тегу PHP
  • А можете поревьювить?

    gzhegow
    @gzhegow
    aka "ОбнимиБизнесмена"
    Глаза радуются, когда такой код видишь, не надо спрашивать - где он тот кто писал

    Немного косметики:
    1. Константы можно определять в интерфейсах, это здорово помогает, незачем для них целая папка с классами

    2. Билдер предполагает (на мой взгляд) строительство чего-то сложного в такой нотации
    ->where()->where()->group(). Если нечто просто возвращает другой объект, это может быть фабрикой. Я имею в виду даже называться фабрика. Билдер означает "здесь столько параметров, что их в одном месте тупо не проставить, и нужно отсюда взять один, отсюда другой, соединить хитро" и тд. поэтому он билдер.

    3. Есть там место где тебе очень нравится if ($a instanceof Class) и раз 20. Можешь закинуть имена классов в качестве ключей в массив и тупо чекать isset(). Разве что ты планируешь наследоваться, тогда isset() будет не очень. Но в любом случае форич упростит этот код строк на 30

    4. по эксепшенам как бы не превратилось в холивар, но смело бросай стандартные Пхпшные эксепшены с небольшой ремарочкой - оберни их в свой неймспейс (в этом случае категории останутся стандартные, а твой модуль будет бросать как бы "свои собственные"). Для случаев когда тебе очень нужно что-то логировать и вытягивать из эксепшена, я бы предусмотрел как и у тебя ClientException только вместо Response просто пхал бы туда ...$arguments. Что кинешь - то и достанешь потом. То есть стандартные мессаг, код и предыдущий будет как у всех эксепшенов - а аргументы - чтобы их логировать. Не думаю что очень ты выиграл от того, что сделал эксепшен в котором первым параметром обязательно респонс. Теперь он может быть использован только здесь и нигде больше. Если эксепшен приводит к каким-то действиям кроме "поймать", "перебросить", "уведомить" или "залогировать" - очень вероятно что это не эксепшен. Хотя такой вариант может быть почему нет.

    5. Интерфейсы лежат вместе с классами это не плохо, но рядом с интерфейсом нет такого же класса, а идут другие, реализующие интерфейс. Похоже на абстракцию, которая могла бы быть. ActionInterface.php, Action.php и папка Action где уже лежат Actions. Но это тоже косметика. В самих экшенах я бы все таки добавил слово Action несмотря на то что неймспейс тоже Action. Если открыть много файлов в редакторе, то сверху одинаковые имена могут дублиться, а так видно - что тут речь про экшен, а там не про экшен.

    6. Вот что мне показалось странным - у тебя куча "экшенов" подразумевающих что это "действие". Но там внутри лежат сущности названные "Действие". Ну то есть ты создал много классов задача которых входные аргументы проверить по типу (кинуть InvalidArgumentException если косяк, по сути), и больше ничего. Ну у них есть геттеры и свойства. Это состояние никак не меняется, оно просто устанавливается и валидируется. Можно. Выглядит красиво, аккуратно. Но бегает у меня сзади призрак который намекает что зарраза, столько файлов создал, он не задолбался? Впрочем если апишка бота непредсказуема - типа на одно возвращает одно, на второе другое и нет ничего общего - то такой способ валидации приемлем. К сожалению кроме разработчика который будет на базе этой штуки лепить, никто не сможет на них никак среагировать, т.к. InvalidArgumentException это в первую очередь "уведомить разработчика что сюда попало то, что не должно", отловить и перевести на несколько языков такую ошибку не получится. Собственно поэтому прибегают к валидации там, где этой штукой будет пользоваться менее опытный разработчик или пользователь.

    Наверное всё, можно пообщаться в той же телеге, если интересно детальнее. В целом понравилось
    Ответ написан
    2 комментария
  • Что нужно знать про ООП?

    gzhegow
    @gzhegow
    aka "ОбнимиБизнесмена"
    А я бы добавил что ООП это украшение кода, а не его суть

    Cейчас есть способы платить Амазону и вообще не писать код, создавая апишки в админке с помощью мышки. Все что будет нужно от ПХП - это делать простые скрипты которые передают данные из точки А в точку Б. Там вообще не нужен будет ООП, потому что не будет понятия "цельный проект" в рамках папки с файлами. Цельный проект это будет куча компьютеров, а на этом конкретно есть передача из А в Б. И тут уже PHPшники посмеются)) Они то готовы к такому

    Увидев, что тебе понравился первый ответ (может ты его и искал?), я попробую пояснить его для тех, кому термины ничего не говорят:

    https://qna.habr.com/q/655113#answer_1431141

    думаю сейчас ты увидишь как набегут великие архитекторы, которые давали тебе советы по этим словам и начнут говорить что то не про это, а это не так и это не здесь. вот это еще одно что надо знать про ООП. Ты никогда не услышишь, что ты прав, потому что термины заменили им мозг, а если им сказать об этом - они объединяются в стаи, чтобы завалить тебя стикерами и унижениями.
    Ответ написан
    19 комментариев
  • Как обновить версию libxml в OpenServer?

    gzhegow
    @gzhegow
    aka "ОбнимиБизнесмена"
    В опенсервере есть модулес пхп и там твой пхп который ты выбрал в панельке стартовой. Заменив там, обновится. А опенсервер каждый раз новый. Или ставить поверху без замены или помнить шо такой то модуль менять нельзя. Можно сделать умнее канеш но долго и никто не выиграет от этого
    Ответ написан
  • Не работает Ajax запрос при отправке формы обратной формы. В чем причина?

    gzhegow
    @gzhegow
    aka "ОбнимиБизнесмена"
    Может ты скрипт свой вешаешь на onSubmit еще до того как загрузилась jquery у которого async?
    Ответ написан
  • Как подсчитать только вложенные элементы массива без родительских?

    gzhegow
    @gzhegow
    aka "ОбнимиБизнесмена"
    Добро пожаловать в пхп. Ты нащупал одну из мощнейших его проблем, которую никакой авторитетный пхпшник никогда не признает.

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

    Сначала по существу, потом о вечном...

    Количество родительского - count($array);
    Когда ты поставил в count() вторым параметром единицу - ты посчитал сумму количеств во всех элементах. Потом отнял количество в главном массиве. Технически ты получил ответ, но сама задача - сначала сделать пачку-пачек а потом посчитать количество элементов во всех пачках без учета основной пачки - это немного странно

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

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

    Вот тебе функции из моей библиотеки:

    // is_array
      // проверяет массив на ключи - цифровые, идущие по порядку с 0
      function _is_array($array) : bool
      {
        if (! is_array($array)) return false;
        if (! $array) return true; // empty array is array too
    
        $i = count($array);
        while ($i-- && ! array_key_exists($i, $array)) return false;
    
        return true;
      }
    
      // is_list
      // проверяет является ли массив - списком (list) без буквенных ключей. цифровые ключи в отличие от array могут идти в любом порядке
      function _is_list($array) : bool
      {
        if (! is_array($array)) return false;
        if (! $array) return true; // empty list is list too
    
        // contains string key? not a list
        foreach (array_keys($array) as $key) {
          if (is_string($key)) return false;
        }
    
        return true;
      }
    
      // is_assoc
      // проверяет, является ли массив "грязным" - содержит хотя бы один строковый ключ
      function _is_assoc($array) : bool
      {
        if (! is_array($array)) return false;
        if (! $array) return false; // empty assoc is not an assoc
    
        // contains string key? there's assoc
        $result = false;
        foreach (array_keys($array) as $key) {
          if (! is_string($key)) continue;
    
          $result = true;
          break;
        }
    
        return $result;
      }
    
      // is_dict
      // проверяет, является ли массив - словарем (dict), без цифровых и пустых ключей
      function _is_dict($array) : bool
      {
        if (! is_array($array)) return false;
        if (! $array) return false; // empty dict is not a dict
    
        foreach (array_keys($array) as $key) {
          if (is_int($key)) return false; // 0,1,2
          if (! $key) return false; // null, ''
        }
    
        return true;
      }


    Теперь массив для тебя - это пачка чего-то.

    Лист, или список - это пачка которая прошла через фильтры (обычно функции фильтрации не изменяют ключей, а просто выбрасывают лишние), или это еще бывает пачка привязанная к таблице-связке в many-to-many.

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

    Dict - полноценный словарь, ключ-значение, являющийся единицей, которую надо класть в массив целиком и воспринимать как цельную сущность.

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

    gzhegow
    @gzhegow
    aka "ОбнимиБизнесмена"
    Рассматривай обьект как ящик с данными.
    Создал ящик. Положил туда что-то. На ящик навесил ярлык с переменной.
    Хочешь другой обьект - это другой ящик создавай новый или копируй (через клонирование) старый. Можешь в переменную положить другой ящик.

    Но помни что если ни одна из переменных не содержит информацию о твоем ящике, то ты его потерял.
    То есть
    $obj = new Obj;
    $obj = new Obj;

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

    Создавай вторую. И там играйся со вторым ящиком
    Ответ написан
    Комментировать
  • Где посмотреть\почитать нормальные уроки по ООП в PHP?

    gzhegow
    @gzhegow
    aka "ОбнимиБизнесмена"
    Если ты начнешь внимать "глубину ооп" то лет через 8 тупого и бесполезного долбалова и попыток уговорить хоть кого-нибудь тебе помочь понять суть и смысл, слушая тупые отговорки, что "ты все не так понял", "это всего лишь инструмент", "нужно найти суть", "это не всегда нужно", ты в конце концов придешь что ООП это всего лишь украшение обычных функций, когда проект не влазит на пластиковую доску с маркерами.

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

    Дальнейшее "понимание глубины" не несет под собой ничего кроме того что есть авторитет, и есть вот ты. и ты никогда не станешь авторитетом, потому что он гуру и на горе. А ты здесь. И не бывает так, чтобы ты и авторитет. Зато бывает менталитет. Извиняюсь, кого обидел
    Ответ написан
  • Как правильно реализовать реализовать классы Родитель->Потомок?

    gzhegow
    @gzhegow
    aka "ОбнимиБизнесмена"
    Вот как я понимал события

    <?php
    
    $events = [];
    
    $on = function (string $name, callable $func) use (&$events)
    {
      $events[ $name ][] = $func;
    };
    
    $fire = function (string $name, $emitter, ...$arguments) use (&$events)
    {
      if (! isset($events[ $name ])) return;
      
      foreach ($events[ $name ] as $func) {
        call_user_func($func, $name, $emitter, ...$arguments);
      }
    };
    
    // когда машина выйдет с завода - поехали!
    $on('car-created', function ($event, $car, ...$comments) { var_dump($car, $comments); });
    
    // ...some application code
    
    // пришло время, тачка готова.
    $fire('car-created', $car, 'faster', 'darling');


    Что тут есть. Есть массив, хранилище, где будут лежать инструкции $func "что сделать", привязанные на ключ $name - "когда сделать".

    Есть функция $on, которая тупо на некое имя записывает в хранилище что делать.
    Есть функция $fire, которая "стреляет" - начинает выполнять всё, что висит на этом `$name`. В параметре эмиттер может быть что угодно, что душе хочется - обычно это виновник торжества, из-за чего событие стрельнуло.

    В аргументс тоже передаешь чего хочешь, параметры массивы и так далее.

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

    Пока просто вот так отнесись к этому
    Ответ написан
    Комментировать
  • PHP Почему не равны две строки?

    gzhegow
    @gzhegow
    aka "ОбнимиБизнесмена"
    очень вероятно что одна строка написана в блокноте с выбранным UTF8-BOM, а вторая написана на сервере или на чьём-то ноутбуке где было выбрано Windows-1251, а потом просто скопировано или вставлено в базу как было

    ну и как ты сам нашел в комментах - __debugInfo магический метод может менять вывод var_dump.
    Ответ написан
    Комментировать
  • Как реализовать запрос с использованием PHP SoapClient?

    gzhegow
    @gzhegow
    aka "ОбнимиБизнесмена"
    Если запрос не HTTPS рекомендую установить программу WireShark, и попробовать посмотреть в каком виде идут другие запросы. Потом можно составить запрос в виде текста и отправить его. А уже потом прикидывать как на это все навесить код, который в пыхе вшит под словом Soap.

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

    gzhegow
    @gzhegow
    aka "ОбнимиБизнесмена"
    /app
    /app/controllers
    /app/controllers/hello
    /app/controllers/hello/world.php
    /app/controllers/index.php
    /app/routes.php
    /public
    /public/index.php
    /.htaccess
    /app.php

    .htaccess
    # .htaccess
    
    Options +FollowSymlinks -Indexes
    DirectoryIndex public/index.html public/index.php
    
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-l
    RewriteRule ^(.*)$ /public/index.php?_url=/$1 [L,QSA]


    app.php
    <?php
    // app.php
    
    define('__ROOT__', __DIR__);
    define('__APP__', realpath(__ROOT__ . '/app'));
    
    $routes = require_once __APP__ . '/routes.php';
    
    foreach ($routes as $pattern => $action) {
      if (! preg_match($pattern, $_SERVER['REQUEST_URI'], $matches)) continue;
    
      $action = array_filter(explode('/', $action));
      $file = basename(array_pop($action), '.php');
    
      array_push($action, $file);
    
      require __APP__ . '/controllers/' . implode('/', $action) . '.php';
      break;
    }


    public/index.php
    <?php
    // public/index.php
    
    // strict
    register_shutdown_function(function () {
      $error = error_get_last();
      if (! $error) return;
      if (! ($error['line'] ?? null)) return;
    
      $errno    = $error['type'];
      $errmsg   = $error['message'];
      $errfile  = $error['file'];
      $errline  = $error['line'];
    
      handle(new \ErrorException($errmsg, $errcode = -1, $errno, $errfile, $errline));
    });
    
    // error
    set_error_handler(function ($errno, $errmsg, $errfile, $errline) {
      if (! $errline) return;
    
      throw new \ErrorException($errmsg, $errcode = -1, $errno, $errfile, $errline);
    }, E_ALL);
    
    // handle
    function handle(\Throwable $e)
    {
      echo '<pre>';
      die(var_dump($e));
    }
    
    // index.php
    try {
      // run application
      require_once __DIR__ . '/../app.php';
    
    } catch (\Throwable $e) { handle($e); }


    app/routes.php
    <?php
    // app/routes.php
    
    $routes = [];
    
    foreach ([
      '/' => 'index',
      '/foo/bar' => 'index',
      '/hello/world' => 'hello/world',
    ] as $pattern => $action) {
      $routes[ '/^' . preg_quote($pattern, '/') . '$/' ] = $action;
    }
    
    return $routes;


    app/controllers/index.php
    <?php
    // app/controllers/index.php
    
    echo 'Index';


    app/controllers/hello/world.php
    <?php
    // app/controllers/hello/world.php
    
    echo 'Hello/World';
    Ответ написан
    5 комментариев
  • Можно ли в одном экземпляре класса получить ответ а в другом работать с ранее полученным ответом?

    gzhegow
    @gzhegow
    aka "ОбнимиБизнесмена"
    Первый скрипт запускается на сервере и второй там же. Что общего на сервере? Жесткий диск. Клади ответ в файл, потом файл читай.

    Если нужно оттолкнуться от прошлого ответа - можно сделать мультикурл (тогда это будет в одной странице, но больше ждать) - говоришь сначала сделай запросы туда туда и вон туда одновременно, а когда все они закончатся, делай дальше тото
    Ответ написан
    Комментировать
  • Можно ли это переписать на ООП? И как примерно всё это можно распределить по классам?

    gzhegow
    @gzhegow
    aka "ОбнимиБизнесмена"
    Мне очень понравилось, как мне объяснил это Алексей Пастушенко

    Так я понял что он сказал:
    Смотри, компьютер все равно будет под капотом выполнять машинный код, процедурщину - функция в нее аргументы и поехали, а еще точнее - машинный код, логические И / ИЛИ, но думать так как машина здесь больше проблем чем преимуществ, хотя для общего развития можно просвятиться про диоды, транзисторы pn переходы и куда только не улетишь. Но если ты попробуешь на доске квадратами обрисовать что к чему цепляется, то у тебя миллион квадратов получится, ведь каждая функция это будет отдельный квадрат.

    ООП можно понимать как попытку нарисовать карту для какого-нибудь острова. Вот так будут изображаться порты, вот так - маяки. вот так будут леса. То есть в конечном счете прога будет работать на процедурщине. Но чтобы обьяснить её и найти в случае поломки код который косячит - мы рисуем карту и по ней пишем себе документацию, чтобы вспомнить что такой-то квадрат делает у нас тото и поэтому это он косячит. Важно понимать (у меня это отняло очень много времени, пока я воткнул) - что мы не "пишем на ООП", мы переписываем на ООП. Когда нужен функционал - мы пишем его на функциях, которые кладем в папку. А когда возникает необходимость следить за этим - кто где что в какой момент и пожалуйста с возможностью настраивать из админки - переписываем на ооп.

    В действительности - косячит какая-то функция. Но когда есть некий обьект где она лежит, нам проще найти "виноватого" (модуль в коде) и пофиксить его.

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

    Отдельная фишка это предсказуемость если в функцию приходят два обьекта которые должны как-то между собой взаимодействовать - то первое что придется делать это проверить - а то вообще пришло? В случае с ООП как минимум один из этих обьектов будет главным и его проверять не нужно (он будет $this). Либо это будет третий обьект, в который ты зашьешь проверку этих двух как будто это была простая функция. но код самой функции будет чище, т.к. проверки оказались в других местах, а здесь выполняется одно какое-то действие

    В остальном ООП это усложнение кода, которое стоит того. Но если тебе нужно быренько связать два сайта через один скрипт, то попытка нарисовать карту этой связи выжрет у тебя неделю. А написать функцию, которая это делает - займет минут 10. Поэтому надо быренько сделать - забей. Надо предсказуемость, логируемость, понимание что где происходит, история изменений, или что самое ядерное - откат в обратном порядке от того, как это делалось - придется рисовать карту. Или сдохнуть на проекте
    Ответ написан
    3 комментария
  • Как изменить url после того как $_GET принял запрос?

    gzhegow
    @gzhegow
    aka "ОбнимиБизнесмена"
    Ты не можешь "изменить URL" ты можешь "перенаправить человека на другую страницу"
    и когда он туда перейдет - выполнится то же самое будто он сразу туда зашел

    header('Location:') это примерно такого же порядка функция как и "echo" - когда ты выводишь ответ.
    То есть пользователь не останется на странице где ты хочешь сменить URL. Пользователь получит ответ о том, что нужно без его ведома перейти на новую страницу

    Может в понимании этого была проблема?
    Ответ написан
  • Как сделать ЧПУ?

    gzhegow
    @gzhegow
    aka "ОбнимиБизнесмена"
    ЧПУ в общем случае это айдишник в конце записи. Это гарантирует что страница уникальная.

    /articles/hello-world-1/

    По этой единичке мы и находим статью, а текст (slug: hello-world) ссылки может быть совершенно любой.
    Знаю что возникнет у тебя вопрос про дублирование контента, типа ссылка /hello-world-1/ ведет туда же, что и /hello-foo-1/, однако твой построитель ссылок всегда будет генерировать её по hello-world, и на сайте, видимым для роботов, никогда не будет hello-foo

    ps. "Плохие времена" к возможностям относятся так себе. Они будут, но не у тех, кто делает работу, а у тех, кто договаривается и считает деньги. И то что ты здесь, говорит что оно так и есть
    Ответ написан
  • Почему медленно загружается страница на PHP, которая берёт данные из MySQL?

    gzhegow
    @gzhegow
    aka "ОбнимиБизнесмена"
    ORDER BY put_date ASC
    больно ссуко( хотя может и не очень

    индекс на парент убедись что есть. можно даже внешний ключ, похер что в одной таблице.

    у тебя дерево вложенности. очень большое (больше 3-4 уровней вполне возможно) - да ещё и с огромным числом записей. делать его через
    id,parent_id
    это очень тяжело

    тебе нужно делать отдельную таблицу
    CommentsTree
    id, comment_id, parent_id, depth, level

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

    id, comment_id, parent_id, depth, level (левел можно в таблице комментов хранить а не в дереве, они одинаковые для конкретного коммента)
    // это вот было
    1, 1, 1, 0, 1 // читать как "коммент 1 родитель он же сам (1), дельта глубины 0, общий уровень 1"
    2, 2, 2, 0, 2 // читать как "коммент 2 родитель он же сам (2), дельта глубины 0, общий уровень 2"
    3, 2, 1, 1, 2 // читать как "коммент 1 родитель 1, дельта глубины 1, общий уровень 2"

    // добавляем потомка к 2
    4, 3, 3, 0, 3 // читать как "коммент 3 родитель он же сам (3), дельта глубины 0, общий уровень 3"
    5, 3, 2, 0, 3 // читать как "коммент 3 родитель 2, дельта глубины 1, общий уровень 3"
    6, 3, 1, 2, 3 // читать как "коммент 3 родитель 1, дельта глубины 2, общий уровень 3"

    Потом из этой таблицы можно дернуть WHERE parent_id = :parent и получить все дерево

    Если похожим образом будешь делать товары, которые кстати говоря бывают в двух категориях одновременно - то еще добавится поле category_path, где через точку (1.2.3) или в JSON ([1,2,3]) лежит путь до самого верха в качестве точки отсчета вместо category_id
    Ответ написан
    2 комментария
  • Можно ли работать с websocet на виртуальном хостинге?

    gzhegow
    @gzhegow
    aka "ОбнимиБизнесмена"
    Ты можешь и с обычной страницы сайта подключиться к сокету, получить что туда накидали и обработать. Но это не очень.

    В случае с виртуальным хостингом где нет консоли можно выпендриться поискав планировщик Cron и запустить задачу типа "1 раз в год выполни этот файл" - а он в свою очередь внутри while true и никогда не кончится.

    Но если ты запустишь и натупишь, то как ты убивать процесс будешь? Да собственно хрен его знает.
    Надо в твоем скрипте-сервере делать поддержку текста "exit;" который приходит в сокет и убивает его)

    Но это форменный изврат, отвечаю
    Посмотреть сокеты в ноде будет легче. Тем более что вся разница в том, что в пыхе ты подымаешь nginx или apache чтобы запускать скрипты, а здесь ты запускаешь node express какой-нибудь который точно то же самое делает
    Ответ написан
    Комментировать
  • Как правильно передать из ajax в php?

    gzhegow
    @gzhegow
    aka "ОбнимиБизнесмена"
    Так у тебя не аякс ругается, а видимо сама страница когда ты её без аякса запрашиваешь, потому что туда ничего не передали.

    Проблема комплексная.

    Не выводи в ответ ничего кроме редиректа, когда данные отправляются постом. Нефиг. Есть Гет для этого. Нет, это не значит что данные нужно отправлять гетом. Это значит что когда ГЕТ - отдавай верстку. А когда пост - сохраняй данные. Если нужно с Гета на Пост перейти и не потерять - есть сессия (привязана к тому кто запрашивал) или база (для всех, придется ввести признак, как ты поймешь что это его). Этот совет актуален когда ты запрашиваешь страничку через браузер.

    В случае с Аяксом (параллельной отправкой) действуют правила API - компьютеры общаются между собой, им плевать что ты хотел нарисовать, они понимают только текст. Причем не понимают - они его передают и обрабатывают. А если еще точнее то они передают пакеты и им даже на текст плевать, но с текстом тебе привычнее работать. То есть в ответ на Пост пусть вылетает JSON с массивом а не верстка. Верстку строим потом на клиенте.

    В третьих можно писать так $id = $_POST['id'] ?? null; если пыха (не бэха) семерка. На крайняк
    $id = (! empty($POST['id']) ? $_POST['id'] : null;
    Ответ написан
    Комментировать
  • Как исправить Array to string conversion?

    gzhegow
    @gzhegow
    aka "ОбнимиБизнесмена"
    Во первых ты пытаешься file_get_contents() от объекта $file. Эта функция на вход хочет строку.
    Возможно у твоего обьекта file есть какой-нибудь arrayAccess или __toString() почему-то возвращающий массив

    $arrayFiles[] = (StorageFactory::make('minio'))->store($file->getClientOriginalName(), file_get_contents($file));


    Может как-то так
    file_get_contents($file->getClientFilePath())

    функцию getClientFilePath() я с потолка взял. Она не имеет смысла кстати. Путь на клиенте тебе не доступен для чтения. Если это файл отправляемый пользователем там будет что-то $file->getTmpPath(), куда он временно закачался для твоего скрипта и откуда исчезнет если ничего не сделать. И там будет не file_get_contents() а какой-нибудь copy($file->getTmpPath(), $new_location);

    Второй код ничего не говорит и даже не вызывает твой $arrayFiles никак не привязан

    Что до $response, то если в нем $arrayFiles; то сделать "echo Array()" нельзя без такой ошибки. Сначала Array() нужно конвертировать в строку с помощью json_encode() или там serialize() или другим способом
    Ответ написан
    2 комментария
  • С помощью какого модификатора повторить регулярное выражение многократно?

    gzhegow
    @gzhegow
    aka "ОбнимиБизнесмена"
    Плюсиком не иначе
    если нужно заменить 'vas' в строке 'vasiliy vasilievich' регулярка ~(^|[ ])vas~
    словами "взять vas перед которыми начало или пробел"

    дальше либо preg_match_all() чтобы найти все, либо preg_replace() которая и так пройдется по всем.

    другой вопрос - что метасимволов подряд сколько-то и ты хочешь их все в разные группы, тогда такое ~([0-9]+;)+~
    но это будет как бы выборка нескольких групп идущих подряд, а не всех повторений в строке

    мне кажется в твоем случае у тебя регулярка не совсем правильная.

    можешь потренироваться на regex101 сайте, там сразу видно результат
    Ответ написан
    Комментировать