Задать вопрос
  • Как называется специально усложненный проект на GitHub?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Simple PHP Easy Plus
    Тут, правда, не 5 строк, а один оператор, но, надеюсь, подойдёт.
    Ответ написан
    1 комментарий
  • Этот код сильно ужасен)?

    zoonman
    @zoonman
    ⋆⋆⋆⋆⋆
    Ну что же, начнём? Только не плакать потом, сами попросили.

    Итак, начнем с архитектуры. Начнем с того, что код чем только не занимается, он и из консоли запускает и как веб-хук и т.д. Сам по себе он является куском битрикса в том или ином виде.
    Далее - код использует ООП, но написан в процедурном стиле.

    Уже за это надо проявлять насилие над личностью.

    <?php
    include "bitrix.php";
    include "function.php";
    require_once  '../src/db.php';


    Просто используйте require_once.

    use должен быть вверху файла.

    $id = $_GET['id'];
    Будет генерировать ошибки, если скрипт был вызван без id.

    $select = $db->query("SELECT * FROM tg_bot WHERE  tg_bot.id='$id'");

    Добро пожаловать в мир SQL-инъекций.

    $bot_token = $select[0]['api_key'];
    Что произойдет, если бот не существует? Ошибки.

    define('BOT_TOKEN', "$bot_token");
    Бить железной линейкой по пальцам. Сильно. Больно. Долго.

    Нельзя использовать переменные внутри define. Эта инструкция придумана для объявления констант. Объявлять константы используя переменные недопустимо.

    if (php_sapi_name() == 'cli') {
        apiRequest('setWebhook', array('url' => isset($argv[1]) && $argv[1] == 'delete' ? '' : WEBHOOK_URL));
        exit;
    }

    Жуть какая-то.

    $content = file_get_contents("php://input");
    $update = json_decode($content, true);
    
    if (!$update) {
        exit;
    }

    Я так понимаю, что здесь происходит вызов самого веб-хука.

    Ну а дальше просто идет месиво. Смешались в кучу кони, люди...

    Что с этим можно сделать?

    Вызубрить ООП и getjump.github.io/ru-php-the-right-way

    Вспомните принцип "Разделяй и властвуй".
    Разделяйте код по функционалу и уровням абстрации.
    Например разделите код на работу с базой, на работу с API, на бизнес-логику.

    Например ваш код мог бы выглядеть так:

    // добавляем автозагрузку классов
    require_once 'vendor/autoload.php';
    // импортируем конфигурацию
    require_once 'config.php';
    
    use Chaly/Bot;
    
    // проверяем, что наш скрипт вызван с индентификтором бота
    if (!isset($_GET['id'])) {
      exit(1); // ненулевой статус говорит об ошибке
    }
    
    // загрузить робота из базы данных
    $bot = Bot::loadById($_GET['id']);
    if (!$bot) {
      exit(1);
    }
    
    // запустить робота
    $bot->run();


    Как может выглядеть тело run()

    public function run() {
      if (Cli::isValid()) {
        switch (Cli::getCommand()) {
            case 'delete':
                $this->delete();
                break;
            case 'register':
                $this->register();
                break;
        }
        return;
      }
    
      $payload = $this->getWebHookPayload();
      if (!$payload) {
        return;
      }
    
      if (isset($payload['message'])) {
        $this->interpretMessage($payload['message']);
      }
    
      // и так далее, думаю смысл понятен
    }
    Ответ написан
    3 комментария
  • Как обработать массив в PHP?

    0xD34F
    @0xD34F
    array_combine(array_keys($arr), array_column($arr, 'VALUE'))

    или

    array_map(function($n) {
      return $n['VALUE'];
    }, $arr)
    Ответ написан
    Комментировать
  • Какой PHP-фреймворк для приложения по обработке данных из разных источников?

    DevMan
    @DevMan
    эмм.... кагбе никакой фреймворк не мешает создать объект на основании внешних данных.
    Ответ написан
    6 комментариев
  • Прямой эфир в ВК на PHP?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    Можно. Но PHP тут (почти) не при чём.

    Надо создать трансляцию, скопировать её секретный URL и запустить на сервере, например, ffmpeg так, чтобы он стримил на этот URL нужный файл в нужном формате, зацикленно.

    Ссылки для ознакомления:
    Ответ написан
    1 комментарий
  • Как скачать миллион картинок?

    deepblack
    @deepblack
    download_images_from_csv.sh (допилите под себя если нужно)
    spoiler
    #!/bin/bash
    COLUMN=1 # csv column to extract
    RENAME=false # if we should rename the file, note that is was really specific for my problem.
    THREADS=16 # threads to use by parallel
    
    #Set Script Name variable
    SCRIPT=`basename ${BASH_SOURCE[0]}`
    
    #Set fonts for Help.
    NORM=`tput sgr0`
    BOLD=`tput bold`
    REV=`tput smso`
    
    # Help function
    function HELP {
      echo -e \\n"Help documentation for ${SCRIPT}."\\n
      echo -e "Basic usage: ./$SCRIPT"\\n
      echo "Command line switches are optional. The following switches are recognized."
      echo "-f csv file = required should be last argument"
      echo "-c column, default $COLUMN"
      echo "-t threads, default $THREADS"
      echo "-r renamd, should be renamed - work in progress here because this is really specific renaming"
      echo -e "-h --Displays this help message. No further functions are performed."\\n
      echo -e "Example: ./${BOLD}$SCRIPT -rc 2 -f file.csv"\\n
      exit 1
    }
    
    
    #Check the number of arguments. If none are passed, print help and exit.
    NUMARGS=$#
    if [ $NUMARGS -eq 0 ]; then
      HELP
      exit 1
    fi
    
    while getopts ::c::r:h:f FLAG; do
      case $FLAG in
        t)
            THREADS=$OPTARG
          ;;
        c)
            COLUMN=$OPTARG
          ;;
        r)
            RENAME=true
          ;;
        h)  #show help
          HELP
          ;;
        \?)
          echo -e \\n"Option -${BOLD}$OPTARG${NORM} not allowed."
          HELP
          ;;
      esac
    done
    
    shift $((OPTIND-1))
    
    FILE=$1
    # shift ops, all optional args are now removed $1 will have to be the filename
    
    if [ "$RENAME" = true ]; then
        mkdir -p images && cat $FILE | tail -n +2 | cut -d ',' -f$COLUMN | grep http | sed -e 's/^[ \t\r]*//' | \
            (cd images; parallel -j$THREADS -d'\r\n' --gnu 'wget {}; mv {/} `echo "{/}" | tr "." "_" | cut -d "_" -f1,3 | tr "_" "."`')
    else
        mkdir -p images && cat $FILE | tail -n +2 | cut -d ',' -f$COLUMN | grep http | sed -e 's/^[ \t\r]*//' | \
            (cd images; parallel -j$THREADS -d'\r\n' --gnu 'wget {};')
    fi
    Ответ написан
    Комментировать
  • Выгоднее ли быть разработчиком в СПБ, чем в Москве?

    vt4a2h
    @vt4a2h
    Senior software engineer (C++/Qt/boost)
    Ну это всё от критериев выгодности зависит.

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

    С любом случае, каждый их этих городов покажется вам раем после какого-нибудь Усть-Прямокишкинска... И разонравится, после того, как вы начнёте смотреть по сторонам и анализировать. Ну или не разонравится, если не начнёте.

    Что в Мск, что в СПб, на зарплату ~120к вас ожидает "квартира" в панельном гетто на окраине с ипотекой на 20+ лет и переплатой в два-три раза. Ну, единственное отличие, что в СПб вы возможно будете тратить меньше времени на дорогу (или нет).

    Мой вас совет: учите английский и уезжайте. СПб и Мск можно как трамплин использовать, не более того.
    Ответ написан
  • Как работает наследование статических методов в php?

    alexey-m-ukolov
    @alexey-m-ukolov Куратор тега PHP
    Статические ссылки на текущий класс, такие как self:: или __CLASS__, вычисляются используя класс, к которому эта функция принадлежит, как и в том месте, где она была определена
    ...
    Позднее статическое связывание пытается устранить это ограничение, предоставляя ключевое слово, которое ссылается на класс, вызванный непосредственно в ходе выполнения.
    Позднее статическое связывание

    Решение:
    public static function getMessage(): string
    {
      return 'message - ' . static::getString();
    }
    Ответ написан
    1 комментарий
  • Это вообще люди делают?

    dimovich85
    @dimovich85 Куратор тега CSS
    https://u-academy.net/
    Поделюсь с вами вот такой ссылкой:
    https://www.youtube.com/playlist?list=PLswdBLT9llb...
    Ответ написан
    1 комментарий
  • Как правильно тестировать приложения, которые запрашивают сторонние API?

    @seriogja
    Добрый день!

    Отдельный класс мока создавать не нужно. Ларавел из коробки идет с пакетом Mockery и оберткой над ним. Поэтому вы можете мокать объект частично (обычно сами вызовы api), при этом остальные методы продолжать работать без изменений.

    Внутри теста:
    $client = factory(Client::class)->create();
    $mock = Mockery::mock(Client::class);
    $this->app->instance($class, $mock);
    $mock->shouldReceive('createFromApi')
                ->withAnyArgs()
                ->andReturn($client);


    В данном примере мокается метод createFromApi класса Client (который, предположим создает экземпляр по данным вызова API). Теперь, указав andReturn($client), мы точно знаем, что вернется экземпляр класса Client. Все остальные методы не изменяются.

    $this->app->instance устанавливает "подправленный" инстанс при резолве из DI. Таким образом, вы мокаете конкретные методы API, которые вызываются в рамках вашего теста.
    Ответ написан
    Комментировать
  • Есть ли менее "замудрёное" решение?

    @balamyt92
    ; select * from users; --
    Это самое верное и правильное решение. В нем нет ни грамма мудрёности. Если вам так сказали то вероятно уровень собеседующего был ниже (на уровне плинтуса).
    Ответ написан
    Комментировать
  • Какие есть интересные free API для веб проекта?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Ответ написан
    Комментировать
  • Почему Ubuntu 18.04 запускается не с первого раза?

    karabanov
    @karabanov Куратор тега Ubuntu
    Системный администратор
    Попробуйте добавить acpi=off к параметрам загрузки ядра

    В файле /etc/default/grub

    Замените GRUB_CMDLINE_LINUX="" на GRUB_CMDLINE_LINUX="acpi=off"

    Сохрание изменения.

    Выполните sudo update-grub
    Ответ написан
    2 комментария
  • Позднее статическое связывание php: как это работает?

    MegaMufa
    @MegaMufa
    Смотрите. Есть такая простая иерархия классов:
    class A
    {
        public static $text = 'class A';
    
        public function selfTest()
        {
            echo self::$text;
        }
    
        public function staticTest()
        {
            echo static::$text;
        }
    }
    
    class B extends A
    {
        public static $text = 'class B';
    }


    Мы создаем экземпляк субкласа и вызываем методы, определенные в предке.
    $obj = new B();
    $obj->selfTest(); // выведет "class A"
    $obj->staticTest(); // выведет "class B"

    self всегда указывает на тот класс, в котором он написал. Здесь метод описан в классе A, и self указывает на класс A, хоть и вызывается из класса B.
    Значение static вычисляется при вызове. И static указывает на класс объекта в котором произошел вызов. В нашем случае он указывает на B, хотя сам код описан в классе A.

    Зачем это надо? Для того, что бы можно было переопределять статичные члены вашего класса в наследниках и вы могли обращаться к новым значениям из методов, описанных в предке.

    С обычными не статичными членами это и так работает, потому что они собираются, когда вы создаете объект класса. Что бы это работало для статичных методов, надо использовать static
    Ответ написан
    1 комментарий
  • Как лучше написать код в Controller в Laravel?

    @hakkol
    1) Вынесите валидацию в отдельный реквест
    2) Создайте хелпер, в котором будет метод по сохранению картинки
    3) Вызывайте в контроллере метод хелпера и передавайте туда файл ($request->file('pasport') или $request->file('certificate'))
    Ответ написан
    Комментировать
  • Что нужно знать С++ разработчику для начала работы на фрилансе?

    devalone
    @devalone
    ̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻
    PHP, Python, Javascript, Java или C#
    Ответ написан
    Комментировать
  • Как лучше учить английский?

    @nuubie
    Начал учить в 24 года английский с абсолютного "0", т.к. в школе/универе учил только немецкий, в 28 лет сдал IELTS на 7.0.

    Несколько советов:
    1. Рекомендую учить английский только по учебникам на английском. Много времени потратил впустую на попытки выучить по Драгункиным, Илонам Давыдовым, Бонкам и т.п... Лучший вариант - взять самые простые уровни Headway и Cutting Edge и последовательно их проходить .
    2. Нужен наставник, чем выше левел, тем более опытный. Upper-Intermediate - Advanced нужен профессиональный преподаватель, желательно сам прошедший хоть какой-то международный экзамен или сертификацию.
    3. Практика - регулярное общение с носителями языка очень быстро убирает т.н. "языковой барьер" даже если сам два слова не можешь связать.
    4. Чтобы грамотно говорить и писать - надо зубарить грамматику регулярно. Лучшие учебники по грамматике: English Grammar in Use и MyGrammarLab, остальное выбирайте на свой вкус. Кроме грамматики есть еще куча нюансов в зависимости от стиля общения/письма: formal/semiformal/informal, в зависимости от страны British/American/Australian English.
    5. Регулярность занятий: выделял 20 - 30 часов еженедельно для самостоятельных занятий, когда стало больше практики на работе - достаточно 4 - 6 часов на самостоятельное изучение и 4 - 6 часов на курсы на работе+speaking club с носителями языка.
    6. Очень помогает понять свои слабые стороны и адекватно оценить текущий уровень сдача экзаменов IELTS, TOEFL.
    7. Многое зависит от целей которые вы перед собой ставите, просто поехать пообщаться в другой стране достаточно с уровнем pre-intermediate+язык жестов :) Если для карьеры - то лучше сразу брать курсы Market Leader или Business Result, English for IT pros и т.д. Во-первых, лексики нужной быстрее наберетесь, во-вторых, материал будет понятней, т.к. тесно связан с вашими интересами.
    8. Есть масса аудиоподкастов и видеоуроков, мне нравятся: EnglishBusiness Pod, ESL Pod, EnglishVid, openlanguage.com
    Ответ написан
    3 комментария
  • Как ускорить вставку в цикле MySQL?

    orlov0562
    @orlov0562 Куратор тега PHP
    I'm cool!
    Проблема в том, что при выполнении каждого запроса, происходит автокомит, что в свою очередь нагружает диск.
    Установи autocomit=0 и после выполняй COMMIT, после порции отправленных данных.

    Транзакция помогает именно по тому, что старт транзакции устанавливает autocomit в 0, а по завершении возвращает его в исходное состояние.

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

    @Arik
    Быстрый вариант
    class Sms
    {
        protected static $instances = [];
    
        public static function getInstance($id = 'default')
        {
            $map = [
                'first' => 'FirstSmsHandler',
                'second' => 'SecondSmsHandler',
    
                'default' => 'FirstSmsHandler',
            ];
    
            if (!isset(self::$instances[$id])) {
                if (!isset($map[$id])) {
                    throw new \Exception(sprintf('Unknown hadler `%s`', $id));
                }
    
                $handler = new $map[$id];
    
                self::$instances[$id] = new self($handler);
            }
    
            return self::$instances[$id];
        }
    
        protected $handler;
    
        public function __construct(SmsHandler $handler)
        {
            $this->setHandler($handler)
        }
    
        public function setHandler(SmsHandler $handler)
        {
            return $this->handler = $handler;
        }
    
        public function changeHandlerByName($handlerName)
        {
            $map = [
                'first' => 'FirstSmsHandler',
                'second' => 'SecondSmsHandler',
    
                'default' => 'FirstSmsHandler',
            ];
    
            if (!isset($map[$handlerName])) {
                throw new \Exception(sprintf('Unknown handler `%s`', $handlerName));
            }
    
            $handler = new $map[$handlerName];
    
            $this->setHandler($handler);
    
            return $this;
        }
    
        public function __call($name, $arguments)
        {
            return call_user_func_array([$this->handler, $name], $arguments);
        }
    }
    
    $sms = new Sms(new FirstSmsHandler());
    $sms->changeHandlerByName($_POST['provider']);
    
    $sms = Sms::getInstance($_POST['provider']);
    
    $sms->getBalance();


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