Как выполнить серверную работу в PHP для Windows и веб-приложения? - PullRequest
0 голосов
/ 14 октября 2018

Я создал веб-приложение, которое может извлекать изображения с Facebook, а также дает возможность пользователю загружать или извлекать весь альбом и архивировать его. Кроме того, пользователь может создавать резервные копии их на диске Google, приложение работает нормально, нокогда пользователь запрашивает zip-изображения и загружает их или загружает на диск Google, пользователь должен ждать процесса не менее 30 секунд, поэтому я хочу использовать многопоточность, которую я могу использовать в веб-приложении (000webhost я использую для веб-хостинга)Я прочитал некоторые решения, такие как exec (), но он не работает в 000webhost, поэтому предложите мне хорошее и рабочее решение.

1 Ответ

0 голосов
/ 14 октября 2018

Функция exec() просто запускает команду в ОС, как вы используете оболочку или терминал.Это все еще «блокирующий» процесс.

В linux довольно легко сделать его без блокировки, просто добавив

php -f $file > /dev/null &

, который > /dev/null отправляет выходные данные из STDOUT и STDERR в корзинуи & фактически заставляет его работать без блокировки.

В Windows вы должны сделать это совершенно по-другому, но вы можете использовать COM('WScript.Shell') следующим образом:

  $WshShell = new \COM('WScript.Shell');
  $cmd = "cmd /C php $file";
  $oExec = $WshShell->Run($cmd, 0, false)

Для удобства я написал оболочку для них, которая будет определять, используете ли вы Windows илиLinux.Вы можете найти его на GitHub или на источнике:

  class BgProcess{

    /**
     * 
     * @var string
     */
    protected $_comand;

    /**
     * 
     * @var boolean
     */
    protected $_osWin;

    /**
     * 
     * @param string $arg0, $arg1 ...
     * $arg0 is location of php file to run
     * $arg1 ..is additional params to send to script
     * 
     * eg.  new BgProcess( '/home/cli_scripts/script.php', 'true', 'false' );
     * 
     */
    public function __construct($arg0){

        if(stripos(php_uname('s'), 'win') > -1){
            $this->_osWin = true;
        }else{
            $this->_osWin = false;
        }

        $args = func_get_args();
        if(empty($args)){
            throw new Exception(__CLASS__.' arguments required' );
        }

        $file = str_replace('\\', '/', array_shift($args));
        $script = escapeshellarg($file).' '.implode(' ', array_map('escapeshellarg', $args));
        if(false !== ($phpPath = $this->_getPHPExecutableFromPath())){
            if($this->_osWin){  
                $WshShell = new \COM('WScript.Shell');
                $cmd = 'cmd /C '.$phpPath.' '.$script;
                $oExec = $WshShell->Run($cmd, 0, false);
            }else{
                $cmd = $phpPath.' -f '.$script.' > /dev/null &';
                exec($cmd, $oExec);
            }

            $this->_comand = $cmd;
        }else{
            throw new Exception( 'Could not find php executable' );
        }
    }

    /**
     * 
     * @return string
     */
    public function getCommand(){
        return $this->_comand;
    }

    /**
     * 
     * @return string|boolean
     */
    protected function _getPHPExecutableFromPath() {
        $paths = explode(PATH_SEPARATOR, getenv('PATH'));
        if($this->_osWin){
            foreach ($paths as $path) {
                if (strstr($path, 'php')){
                    $php_executable =  $path . DIRECTORY_SEPARATOR . 'php.exe';
                    if(file_exists($php_executable) && is_file($php_executable)){
                        return $php_executable;
                    }
                }
            }
        }else{
            foreach ($paths as $path) {
                $php_executable = $path . DIRECTORY_SEPARATOR . "php";
                if (file_exists($php_executable) && is_file($php_executable)) {
                    return $php_executable;
                }
            }

        }
        return false;
    }

}

Вы используете его вот так

 new BgProcess($file);
 //php -f $file > /dev/null &

Если вы хотите поместить аргументы в

new BgProcess($file, $arg1);
//php -f $file $arg1 > /dev/null &

new BgProcess($file, $arg1, $arg2);
//php -f $file $arg1 $arg2 > /dev/null &

Как обычно, вы можете использовать $argv[0] для получения файла, $argv[1] для первого аргумента в скрипте, выполняемого этим.Есть несколько других предостережений при запуске PHP в командной строке, например, $_SERVER['HTTP_HOST'] не существует.Но я не буду освещать их все здесь, так как это так.Я просто упомяну это для полноты.

Эта часть _getPHPExecutableFromPath() пытается найти путь php.exe.Это очень помогает установить его в переменных среды в Windows.Я предлагаю просто прибегнуть к помощи «установить путь php в windows», потому что это зависит от вашей версии windows, и мне не хочется делать кучу скриншотов.

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

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

Единственная причина, по которой я вообще ответил, это то, что у меня есть такой класс, который я могу легко предоставить.Я также, вероятно, потрачу 3 дня, чтобы понять, как это сделать в Windows (так что я горжусь этим)

Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...