• Рефакторинг кода. Как оптимизировать количество if?

    Skiphog
    @Skiphog
    Crutch developer. Looking for a job.
    Вариантов реализации множество, но если по простому, что можно поступить так:
    Создать одноименные методы в зависимости от ожидаемых типов, которые может вернуть $message->getType();
    И собственно их и вызывать ))
    Так вы избавитесь от кучи if и код каждой реализации разместите в свои методы.

    Псевдокод:
    public function resolve()
    {
        // ....
    
        $type = $message->getType();
        
        // Если такого метода не существует, то можно бросить Исключение или еще как-то обработать ошибку
        // А можно вообще ничего не проверять, а сделать обработку в __call(). Вариантов тоже много
        if (!method_exists($this, $type)) {
            throw new Exception(...);
        }
        
        // Вызвать подходящий метод
        return $this->$type(); //либо call_user_func...()
    }
    
    protected function text()
    {
        //code
    }
    
    protected function poll()
    {
        //code
    }
    
    protected function image()
    {
        //code
    }

    По примерно такой же схеме можно использовать отдельные классы, сервисы и т.п.
    Ответ написан
    Комментировать
  • PHP 7.4: как проверить, что типизированное свойство инициализировано?

    Skiphog
    @Skiphog
    Crutch developer. Looking for a job.
    Ещё такой вариант сработает ))
    public function isTypedInitialized(): bool
    {
        return (new ReflectionProperty($this, 'typed'))
            ->isInitialized($this);
    }
    Ответ написан
  • Какие бесплатные сервисы для отправки email есть для Laravel?

    Skiphog
    @Skiphog
    Crutch developer. Looking for a job.
    В одном проекте, для транзакционных писем использую SendPulse
    Бесплатный тариф - 12к писем в месяц, но с ограничением до 50 писем в час.
    Правда, об этом ограничении на сайте ничего не написано. (Может я плохо искал) Об этом вы узнаете только в личном кабинете )))

    Письма отправляются через них уже более трёх лет. Если не превышать лимит, то проблем не возникнет.

    Использую не в Laravel.
    Для PHP у них есть своя библиотечка. Очень простая, всё задокументировано и есть примеры использования.

    НО! На packagist можно найти библиотеки для интеграции sendPulseApi с Laravel.

    Если вам это подходит, то можете попробовать.
    Ответ написан
    Комментировать
  • Выборка из XML?

    Skiphog
    @Skiphog
    Crutch developer. Looking for a job.
    Предложу такой вариант.
    Скорее всего элементов item будет много, поэтому сначала нужно пройти по item простым форычем.
    А первый div можно выбрать по первому ключу.

    $reader = new SimpleXMLElement($xml);
    
    foreach ($reader->channel->item as $item) {
        var_dump((string)$item->description->div[0]);
    }

    Посмотреть пример на SandBox
    Ответ написан
    7 комментариев
  • Как оставить в многомерном массиве элементы с уникальным значением ключа?

    Skiphog
    @Skiphog
    Crutch developer. Looking for a job.
    Моё варварское решение в лоб ))

    $array = [
        'accessories' => [ /* ... Ваш массив ... */],
    ];
    
    
    $tmp = [];
    
    foreach ($array['accessories'] as $item) {
        if (!isset($tmp[$item['vendor_code']])) {
            $tmp[$item['vendor_code']] = $item;
            continue;
        }
    
        $tmp[$item['vendor_code']]['accessory_group_id'] = implode(',',
            array_unique(
                explode(',', $tmp[$item['vendor_code']]['accessory_group_id'] . ',' . $item['accessory_group_id'])
            )
        );
    }
    
    $result_array['accessories'] = array_values($tmp);
    
    var_dump($result_array);
    Ответ написан
    1 комментарий
  • Почему не работает код в задаче гостевая книга на php?

    Skiphog
    @Skiphog
    Crutch developer. Looking for a job.
    Метод render() в классе View работает не так, как вы этого ожидаете.

    Когда вы подключаете шаблон, то в данном случае там доступен только $this, а $this - это сам объект View.
    Поэтому получить массив персон вы можете только через $this->data['persons'] и никакой $persons там естественно нет.
    т.е. в шаблоне работать будет только так
    //...
    foreach ($this->data['persons'] as $person) {
      echo $person['lastName'];
    //  ...
    }

    Понимаете?

    Для того, что был доступ в шаблоне именно к переменной $persons, вам надо импортировать её в методе render() с помощью функции extract() или через присваивание переменной переменной
    public function render(string $template) 
    {
      ob_start();
      // функция импорта
      extract($this->data, EXTR_OVERWRITE);
      include $template;
      $content = ob_get_contents();
      ob_end_clean();
    
      return $content;
    }

    Либо через переменные переменных

    public function render(string $template) 
    {
      ob_start();
      // Импорт
      foreach($this->data as $key => $value) {
       // Переменные переменных $$
        $$key = $value;
      }
      include $template;
      $content = ob_get_contents();
      ob_end_clean();
    
      return $content;
    }

    В том и другом случае результат одинаковый.

    И тогда в шаблоне вы уже сможете работать непосредственно с $persons
    Ответ написан
    2 комментария
  • Что за cms на сайте?

    Skiphog
    @Skiphog
    Crutch developer. Looking for a job.
    Если верить Wappalyzer
    607ab3c45ba57910136195.png
    Это просто сгенерированные статические странички выложенные на Github Pages

    А вообще, вы уже не в первый раз задаёте такой вопрос.
    Если не хотите ковыряться в коде, то поставьте себе расширение для браузера - Wappalyzer. Он достаточно точно определяет популярные CMS и всякое.
    Если для Хрома, то лежит здесь https://chrome.google.com/webstore/detail/wappalyz...

    И на лету чекайте любые сайты в своё удовольствие )
    Ответ написан
    Комментировать
  • Вывод информации php?

    Skiphog
    @Skiphog
    Crutch developer. Looking for a job.
    Вопрос очень простой.

    Но простой он не потому, что реализация простая, а потому, что это наверное один из самых популярных запросов в поисковике на эту тему (возможно :-D)

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

    Но вы можете не верить никому ))) ... и подсмотреть как это делает какой-нибудь Laravel
    https://github.com/laravel/framework/blob/8.x/src/...

    Избавившись от привязки к классу, можно взять эту функцию себе на вооружение примерно так:
    function limit($value, $limit = 100, $end = '...')
    {
        if (mb_strwidth($value, 'UTF-8') <= $limit) {
            return $value;
        }
    
        return rtrim(mb_strimwidth($value, 0, $limit, '', 'UTF-8')) . $end;
    }

    И это тоже ответ на ваш вопрос.
    А что использовать, решать вам.
    Ответ написан
    Комментировать
  • Можно ли магическим образом создать объект?

    Skiphog
    @Skiphog
    Crutch developer. Looking for a job.
    Вы всё делаете правильно, метод render() и не должен быть статическим, но что бы всё заработало корректно, вам нужно использовать другой вид записи.
    Router::get('/', 'Неймспейс\\SiteController@home');

    Либо использовать PHP 8.0

    Постараюсь вкратце пояснить почему.
    Когда вы пишете такую конструкцию
    use App\Controllers; // к примеру
    //...
    
    Router::get('/', [SiteController::class, 'home']);

    SiteController::class как бы так сказать, преобразуется в App\Controllers\SiteController

    Но автор библиотеки плевать хотел на эти ваши неймспейсы и всё что вы там себе придумали.
    Он берёт данные, которые вы передали и получает массив вида
    [
        0 => 'App\Controllers\SiteController',
        1 => 'home'
    ];

    Потом проверяет этот массив на is_callable()
    https://github.com/skipperbent/simple-php-router/b...

    А такое выражение до PHP8 возвращает true, поэтому всё это дело отправляется дальше на исполнение в
    call_user_func_array() пытаясь вызвать метод статически
    https://github.com/skipperbent/simple-php-router/b...
    Отсюда и ошибка.
    Объект же класса ещё не создан
    ---
    Автор предлагает все неймспейсы указать отдельным методом до старта
    SimpleRouter::setDefaultNamespace('App\Controllers');

    Тогда можно указывать класс без неймспейса и всё будет работать.

    Но в этом случае любой анализатор кода либо тот же Шторм скажет вам, что вы делаете какую-то дичь.
    И как поступить решать уже вам.
    Ответ написан
    Комментировать
  • Почему не создается объект класса?

    Skiphog
    @Skiphog
    Crutch developer. Looking for a job.
    use в данном случае не работает.
    т.к. вы динамически создаёте объект, нужно явно указать namespace routetest\Controllers
    // ...
    
    list($controller, $action) = explode('#', $match['target']);
    $controller = "routetest\\Controllers\\$controller";
    
    $obj = new $controller();


    Можно через ::class, но это уже по другому немного
    Ответ написан
    Комментировать
  • Как проксировать WebSockets через nginx?

    Skiphog
    @Skiphog
    Crutch developer. Looking for a job.
    По идее всё должно работать как в документации. Если слушаете ssl.
    Добавьте как в доке
    location /socket/ {
        proxy_pass http://127.0.0.1:8443;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_read_timeout 70s;
    }

    И спокойно подключайтесь к wss://site.ru/socket/
    Ответ написан
    Комментировать
  • Перенаправлять все запросы на один файл .php в nginx?

    Skiphog
    @Skiphog
    Crutch developer. Looking for a job.
    location / {
        try_files $uri /index.php?$args&url=$uri;
    }
    Ответ написан
    1 комментарий
  • Почему SHOW TABLES FROM выводит только одну таблицу?

    Skiphog
    @Skiphog
    Crutch developer. Looking for a job.
    // ...
    
    $result = mysql_query("SHOW TABLES FROM `db`");
    
    while($prodTable = mysql_fetch_array($result)) {
        print_r($prodTable);
    }
    Ответ написан
    Комментировать
  • Как правильно настроить перенаправление в nginx?

    Skiphog
    @Skiphog
    Crutch developer. Looking for a job.
    Можно использовать rewrite
    location / {
        rewrite ^/question/([0-9]+)/answer/([0-9]+)/$ /question/$1#answer-$2 permanent;
        ...
    }
    Ответ написан
    Комментировать
  • Как в хроме сделать действие если вкладка активна?

    Skiphog
    @Skiphog
    Crutch developer. Looking for a job.
    Такой вариант подойдет?
    document.addEventListener("visibilitychange", function() {
      document.visibilityState === 'visible' && alert('Показываю алерт');
    });

    https://developer.mozilla.org/en-US/docs/Web/Event...
    Ответ написан
  • Как сделать замену по регулярному выражению?

    Skiphog
    @Skiphog
    Crutch developer. Looking for a job.
    $text = preg_replace_callback('/{{(.+)}}/', function ($value) {
        return substr($value[1], 0, -5);
    }, $text);
    Ответ написан
    2 комментария
  • Почему вываливается исключение при использовании @foreach?

    Skiphog
    @Skiphog
    Crutch developer. Looking for a job.
    Опечатка или отсутсвие конструкции @endforeach
    Ответ написан
    Комментировать
  • Как реализовать рейтинг у комментариев?

    Skiphog
    @Skiphog
    Crutch developer. Looking for a job.
    Как вариант.

    Добавить в таблицу с комментариями поле с рейтингом. (Денормализовать)

    Каждый раз, как пользователь голосует (лайкает) увеличиваете/уменьшаете счетчик с рейтингом.
    Да, добавляется запрос с апдейтом, но зато вы избавитесь от select на количество, т.к. рейтинг уже будет в таблице.
    Так же при голосовании вставляете запись в comments_votes то, что задумали.

    А при показе комментариев, делаете тот же запрос, что и был, только добавляете left join к таблице comments_votes по признаку id комментария и id пользователя.
    Соответственно, если юзер еще не голосовал, то вернется null.

    Да, добавляется left join. Это увеличит нагрузку, но для ваших требований вы не заметите разницу.

    Ну или как предложили выше вариант с comment_id in (...)
    Ответ написан
  • Почему выводится ошибка Unexpected data found?

    Skiphog
    @Skiphog
    Crutch developer. Looking for a job.
    Заэкранируйте аббревиатуру временной зоны "Т"
    Carbon::createFromFormat('Y-m-d\TH:i', $date)
    Ответ написан
    Комментировать