Если вы не инициализировали ссылочный тип и хотите установить или прочитать одно из его свойств, он будет генерировать исключение 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 не может произойти. Хотя вам нужно поддерживать оповещение при работе со ссылочными типами!
Только ссылочные типы, как следует из названия, могут содержать ссылки или буквально буквально ничто (или «нуль»). Если типы значений всегда содержат значение.
Типы ссылок (эти должны быть проверены):
Типы значений (вы можете просто игнорировать эти):
Threading недоступен на складе PHP, но одновременное программирование возможно с использованием HTTP-запросов в виде асинхронных вызовов.
С установкой тайм-аута curl, установленной на 1, и используя тот же session_id для процессов, которые вы хотите чтобы быть связанными друг с другом, вы можете общаться с переменными сеанса, как в моем примере ниже. С помощью этого метода вы даже можете закрыть свой браузер, и одновременный процесс все еще существует на сервере.
Не забудьте проверить правильный идентификатор сеанса, например:
http: //localhost/test/verifysession.php? sessionid = [ правильный id]
blockquote>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);
Вы можете использовать exec () для запуска сценария командной строки (например, командной строки php), и если вы передаете вывод в файл, ваш скрипт не будет ждать завершения команды.
Я не могу полностью запомнить синтаксис CLI php, но вы бы хотели что-то вроде:
exec("/path/to/php -f '/path/to/file.php' | '/path/to/output.txt'");
Я думаю, что для нескольких общих серверов хостинга по умолчанию отключены exec () по соображениям безопасности, но, возможно, стоит попробовать.
Да, вы можете делать многопоточность в PHP с помощью pthreads
Из документации PHP :
pthreads - это объектно-ориентированный API, который предоставляет все инструменты, необходимые для многопоточности в PHP. PHP-приложения могут создавать, читать, писать, выполнять и синхронизировать с Threads, Workers и Threaded.
Предупреждение. Расширение pthreads нельзя использовать в среде веб-сервера. Поэтому потоки в PHP должны оставаться в приложениях на основе CLI.
blockquote>Простой тест
#!/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); }
Пока вы не можете нить, у вас есть определенная степень управления процессом в 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.
Как насчет pcntl_fork?
проверьте нашу страницу руководства для примеров: PHP pcntl_fork
Я знаю, что это старый вопрос, но для поиска людей есть расширение PECL, написанное на C, которое теперь дает возможность многопоточности PHP, оно расположено здесь https://github.com/krakjoe/pthreads
У вас может быть опция:
Может быть, я что-то пропустил, но exec не работал как асинхронный для меня в среде Windows, который я использовал в окнах, и он работал как charm;)
$script_exec = "c:/php/php.exe c:/path/my_ascyn_script.php";
pclose(popen("start /B ". $script_exec, "r"));
pcntl_fork
не будет работать в среде веб-сервера, если он имеет безопасный режим включен. В этом случае он будет работать только в версии CLI для PHP.
Вы можете имитировать потоки. PHP может запускать фоновые процессы через popen (или proc_open). Эти процессы могут быть переданы с помощью stdin и stdout. Конечно, эти процессы могут быть программой php. Это, вероятно, так близко, как вы доберетесь.
, используя потоки, становится возможным благодаря расширению PECLs pentl
Многопоточность означает одновременное выполнение нескольких задач или процессов, мы можем достичь этого в 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
Класс Thread доступен, поскольку PECL pthreads ≥ 2.0.0.
В зависимости от того, что вы пытаетесь сделать, вы также можете использовать curl_multi для его достижения.
Для многопоточности HTTP с использованием GuzzleHttp (поскольку pthreads могут не работать в веб-приложениях), см. ниже блог - https://blog.madewithlove.be/post/concurrent-http-requests/
Я знаю, что это устарело, но вы можете посмотреть на http://phpthreadlib.sourceforge.net/
Он поддерживает двунаправленную межпоточную связь, а также имеет встроенные средства защиты от уничтожения дочерних потоков (предотвращение сирот).
почему вы не используете 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]);
}
}