Как выполнять инструкции, не дожидаясь завершения выполнения предыдущего оператора в PHP? [Дубликат]

Если вы не инициализировали ссылочный тип и хотите установить или прочитать одно из его свойств, он будет генерировать исключение NullReferenceException.

Пример:

Person p = null;
p.Name = "Harry"; // NullReferenceException occurs here.

Вы можно просто избежать этого, проверив, является ли переменная не нулевой:

Person p = null;
if (p!=null)
{
    p.Name = "Harry"; // Not going to run to this point
}

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

Итак, если вы имеете дело со типами значений, NullReferenceExceptions не может произойти. Хотя вам нужно поддерживать оповещение при работе со ссылочными типами!

Только ссылочные типы, как следует из названия, могут содержать ссылки или буквально буквально ничто (или «нуль»). Если типы значений всегда содержат значение.

Типы ссылок (эти должны быть проверены):

  • динамический
  • объект
  • string

Типы значений (вы можете просто игнорировать эти):

  • Числовые типы
  • Интегральные типы
  • Типы с плавающей запятой
  • decimal
  • bool
  • Пользовательские структуры

323
задан Lance Roberts 22 October 2011 в 01:47
поделиться

17 ответов

Threading недоступен на складе PHP, но одновременное программирование возможно с использованием HTTP-запросов в виде асинхронных вызовов.

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

Не забудьте проверить правильный идентификатор сеанса, например:

http: //localhost/test/verifysession.php? sessionid = [ правильный id]

startprocess.php

$request = "http://localhost/test/process1.php?sessionid=".$_REQUEST["PHPSESSID"];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $request);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 1);
curl_exec($ch);
curl_close($ch);
echo $_REQUEST["PHPSESSID"];

process1 .php

set_time_limit(0);

if ($_REQUEST["sessionid"])
   session_id($_REQUEST["sessionid"]);

function checkclose()
{
   global $_SESSION;
   if ($_SESSION["closesession"])
   {
       unset($_SESSION["closesession"]);
       die();
   }
}

while(!$close)
{
   session_start();
   $_SESSION["test"] = rand();
   checkclose();
   session_write_close();
   sleep(5);
}

verifysession.php

if ($_REQUEST["sessionid"])
    session_id($_REQUEST["sessionid"]);

session_start();
var_dump($_SESSION);

closeprocess.php

if ($_REQUEST["sessionid"])
    session_id($_REQUEST["sessionid"]);

session_start();
$_SESSION["closesession"] = true;
var_dump($_SESSION);
15
ответ дан 4 revs, 3 users 70% 24 August 2018 в 09:08
поделиться

Вы можете использовать exec () для запуска сценария командной строки (например, командной строки php), и если вы передаете вывод в файл, ваш скрипт не будет ждать завершения команды.

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

exec("/path/to/php -f '/path/to/file.php' | '/path/to/output.txt'");

Я думаю, что для нескольких общих серверов хостинга по умолчанию отключены exec () по соображениям безопасности, но, возможно, стоит попробовать.

4
ответ дан Anil 24 August 2018 в 09:08
поделиться

Многопоточность возможна в php

Да, вы можете делать многопоточность в PHP с помощью pthreads

Из документации PHP :

pthreads - это объектно-ориентированный API, который предоставляет все инструменты, необходимые для многопоточности в PHP. PHP-приложения могут создавать, читать, писать, выполнять и синхронизировать с Threads, Workers и Threaded.

Предупреждение. Расширение pthreads нельзя использовать в среде веб-сервера. Поэтому потоки в PHP должны оставаться в приложениях на основе CLI.

Простой тест

#!/usr/bin/php
<?php
class AsyncOperation extends Thread {

    public function __construct($arg) {
        $this->arg = $arg;
    }

    public function run() {
        if ($this->arg) {
            $sleep = mt_rand(1, 10);
            printf('%s: %s  -start -sleeps %d' . "\n", date("g:i:sa"), $this->arg, $sleep);
            sleep($sleep);
            printf('%s: %s  -finish' . "\n", date("g:i:sa"), $this->arg);
        }
    }
}

// Create a array
$stack = array();

//Initiate Multiple Thread
foreach ( range("A", "D") as $i ) {
    $stack[] = new AsyncOperation($i);
}

// Start The Threads
foreach ( $stack as $t ) {
    $t->start();
}

?>

Первый запуск

12:00:06pm:     A  -start -sleeps 5
12:00:06pm:     B  -start -sleeps 3
12:00:06pm:     C  -start -sleeps 10
12:00:06pm:     D  -start -sleeps 2
12:00:08pm:     D  -finish
12:00:09pm:     B  -finish
12:00:11pm:     A  -finish
12:00:16pm:     C  -finish

Второй запуск

12:01:36pm:     A  -start -sleeps 6
12:01:36pm:     B  -start -sleeps 1
12:01:36pm:     C  -start -sleeps 2
12:01:36pm:     D  -start -sleeps 1
12:01:37pm:     B  -finish
12:01:37pm:     D  -finish
12:01:38pm:     C  -finish
12:01:42pm:     A  -finish

Пример реального мира

error_reporting(E_ALL);
class AsyncWebRequest extends Thread {
    public $url;
    public $data;

    public function __construct($url) {
        $this->url = $url;
    }

    public function run() {
        if (($url = $this->url)) {
            /*
             * If a large amount of data is being requested, you might want to
             * fsockopen and read using usleep in between reads
             */
            $this->data = file_get_contents($url);
        } else
            printf("Thread #%lu was not provided a URL\n", $this->getThreadId());
    }
}

$t = microtime(true);
$g = new AsyncWebRequest(sprintf("http://www.google.com/?q=%s", rand() * 10));
/* starting synchronization */
if ($g->start()) {
    printf("Request took %f seconds to start ", microtime(true) - $t);
    while ( $g->isRunning() ) {
        echo ".";
        usleep(100);
    }
    if ($g->join()) {
        printf(" and %f seconds to finish receiving %d bytes\n", microtime(true) - $t, strlen($g->data));
    } else
        printf(" and %f seconds to finish, request failed\n", microtime(true) - $t);
}
354
ответ дан duskwuff 24 August 2018 в 09:08
поделиться

Пока вы не можете нить, у вас есть определенная степень управления процессом в php. Вот два полезных набора:

Функции управления процессом http://www.php.net/manual/en/ref.pcntl.php

Функции POSIX http://www.php.net/manual/en/ref.posix.php

Вы можете разветвить свой процесс с помощью pcntl_fork - вернуть PID ребенок. Затем вы можете использовать posix_kill для использования этого PID.

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

10
ответ дан J.D. Fitz.Gerald 24 August 2018 в 09:08
поделиться

Как насчет pcntl_fork?

проверьте нашу страницу руководства для примеров: PHP pcntl_fork

2
ответ дан Jarrod 24 August 2018 в 09:08
поделиться

Я знаю, что это старый вопрос, но для поиска людей есть расширение PECL, написанное на C, которое теперь дает возможность многопоточности PHP, оно расположено здесь https://github.com/krakjoe/pthreads

8
ответ дан Jeffrey Kevin Pry 24 August 2018 в 09:08
поделиться

У вас может быть опция:

  1. multi_curl
  2. Можно использовать системную команду для того же
  3. Идеальный сценарий, создать функцию потоковой передачи на языке C и компилировать / настраивать в PHP. Теперь эта функция будет функцией PHP.
2
ответ дан Joe McBride 24 August 2018 в 09:08
поделиться

Может быть, я что-то пропустил, но exec не работал как асинхронный для меня в среде Windows, который я использовал в окнах, и он работал как charm;)

$script_exec = "c:/php/php.exe c:/path/my_ascyn_script.php";

pclose(popen("start /B ". $script_exec, "r"));
-2
ответ дан Mubashar Ahmad 24 August 2018 в 09:08
поделиться

pcntl_fork не будет работать в среде веб-сервера, если он имеет безопасный режим включен. В этом случае он будет работать только в версии CLI для PHP.

2
ответ дан Palec 24 August 2018 в 09:08
поделиться

Вы можете имитировать потоки. PHP может запускать фоновые процессы через popen (или proc_open). Эти процессы могут быть переданы с помощью stdin и stdout. Конечно, эти процессы могут быть программой php. Это, вероятно, так близко, как вы доберетесь.

5
ответ дан Pete 24 August 2018 в 09:08
поделиться

, используя потоки, становится возможным благодаря расширению PECLs pentl

http://www.php.net/manual/en/book.pthreads.php

8
ответ дан pinkal vansia 24 August 2018 в 09:08
поделиться

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

chdir(dirname(__FILE__));  //if you want to run this file as cron job
 for ($i = 0; $i < 2; $i += 1){
 exec("php test_1.php $i > test.txt &");
 //this will execute test_1.php and will leave this process executing in the background and will go         

 //to next iteration of the loop immediately without waiting the completion of the script in the   

 //test_1.php , $i  is passed as argument .

}

Test_1.php

$conn=mysql_connect($host,$user,$pass);
$db=mysql_select_db($db);
$i = $argv[1];  //this is the argument passed from index.php file
for($j = 0;$j<5000; $j ++)
{
mysql_query("insert  into  test   set

                id='$i',

                comment='test',

                datetime=NOW() ");

}

Это будет выполнять test_1.php два раза одновременно, и оба процесса будут работать в фоновом режиме одновременно, поэтому таким образом вы может достичь многопоточности в php.

Этот парень сделал действительно хорошую работу Многопоточность в php

-4
ответ дан Pir Abdul 24 August 2018 в 09:08
поделиться

Класс Thread доступен, поскольку PECL pthreads ≥ 2.0.0.

2
ответ дан Robin Daugherty 24 August 2018 в 09:08
поделиться

В зависимости от того, что вы пытаетесь сделать, вы также можете использовать curl_multi для его достижения.

3
ответ дан Sheldmandu 24 August 2018 в 09:08
поделиться

Для многопоточности HTTP с использованием GuzzleHttp (поскольку pthreads могут не работать в веб-приложениях), см. ниже блог - https://blog.madewithlove.be/post/concurrent-http-requests/

0
ответ дан Som 24 August 2018 в 09:08
поделиться

Я знаю, что это устарело, но вы можете посмотреть на http://phpthreadlib.sourceforge.net/

Он поддерживает двунаправленную межпоточную связь, а также имеет встроенные средства защиты от уничтожения дочерних потоков (предотвращение сирот).

3
ответ дан Unsigned 24 August 2018 в 09:08
поделиться

почему вы не используете popen ?

for ($i=0; $i<10; $i++) {
    // open ten processes
    for ($j=0; $j<10; $j++) {
        $pipe[$j] = popen('script2.php', 'w');
    }

    // wait for them to finish
    for ($j=0; $j<10; ++$j) {
        pclose($pipe[$j]);
    }
}
26
ответ дан Uwe Keim 24 August 2018 в 09:08
поделиться
Другие вопросы по тегам:

Похожие вопросы: