Я запускаю свой код на CodeIgniter — Ubuntu Server.
Я искал асинхронные способы запуска функций.
Это моя функция:
<?php
// Registers a new keyword for prod to the DB.
public function add_keyword() {
$keyword_p = $this->input->post('key_word');
$prod = $this->input->post('prod_name');
$prod = $this->kas_model->search_prod_name($prod);
$prod = $prod[0]->prod_id;
$country = $this->input->post('key_country');
$keyword = explode(", ", $keyword_p);
var_dump($keyword);
$keyword_count = count($keyword);
echo "the keyword count: $keyword_count";
// problematic part that needs forking
for ($i=0; $i < $keyword_count ; $i++) {
// get new vars from $keyword_count
// run API functions to get new data_arrays
// inserts new data for each $keyword_count to the DB
}
// Redirect to main page.
redirect('banana/kas');
}
«Foreach» использует переменные с медленными API и обновляет базу данных.
Я видел некоторые учебники, использующие fork, но не совсем понял его синтаксическую часть. Большинство вещей, которые я нашел, были просто объяснениями того, как это работает (2 процесса: parent-child ect ‘), но не дали хорошего объяснения того, как применять это в коде.
Может кто-нибудь объяснить, как я работаю с синтаксисом fork ()?
Продолжить выполнение PHP после отправки HTTP-ответа
http://www.onlinetechtutorials.com/2014/06/how-to-run-php-code-asynchronously.html
http://php.net/manual/en/function.pcntl-fork.php (более общий)
Со стороны сервера: https://www.youtube.com/watch?v=xVSPv-9x3gk
РЕДАКТИРОВАТЬ:
Я правильно понял?
<?php
// Registers a new keyword for prod to the DB.
public function add_keyword() {
$keyword_p = $this->input->post('key_word');
$prod = $this->input->post('prod_name');
$prod = $this->kas_model->search_prod_name($prod);
$prod = $prod[0]->prod_id;
$country = $this->input->post('key_country');
$keyword = explode(", ", $keyword_p);
var_dump($keyword);
$keyword_count = count($keyword);
echo "the keyword count: $keyword_count";
for ($i=0; $i < $keyword_count ; $i++) {
// create your next fork
$pid = pcntl_fork();
if(!$pid){
//*** get new vars from $keyword_count
//*** run API functions to get new data_arrays
//*** inserts new data for each $keyword_count to the DB
print "In child $i\n";
exit($i);
// end child
}
}
// we are the parent (main), check child's (optional)
while(pcntl_waitpid(0, $status) != -1){
$status = pcntl_wexitstatus($status);
echo "Child $status completed\n";
}
// your other main code: Redirect to main page.
redirect('banana/kas');
}
?>
Это не вызовет никаких проблем с использованием этого внутри цикла? это будет знать, чтобы сложить каждый процесс?
Вы должны указать, какую операционную систему вы используете, потому что расширения pcntl недоступны на платформе Windows
Также вы должны знать, что активация управления процессами в Linux / Unix на веб-сервере может дать вам неожиданные результаты, поэтому только CLI / CGI Режим рекомендуется использовать PCNTL
Пожалуйста, внимательно прочитайте это PCNTL Введение
Теперь ваш код кажется правильным и хорошо реализованным, но вы должны скомпилировать PHP с этой опцией --enable-pcntl
включить функции pcntl, такие как int pcntl_fork(void)
в противном случае вы получите
Неустранимая ошибка: вызов неопределенной функции pcntl_fork ()
Для меня лучшим решением для запуска функций / методов асинхронным способом является использование Pthreads, если вы заинтересованы в этом совете, я могу отредактировать свой ответ, добавив примеры и как установить его на платформах Windows или Linux
Читать Эта статья уметь компилировать PHP
У вас есть один форк после вашего pcntl_fork (), проверьте $ pid и затем вы можете использовать его. Повторите для получения дополнительных вилок.
<?php
for($i = 1; $i <= 3; ++$i){
// create your next fork
$pid = pcntl_fork();
if(!$pid){
// begin child, your execution code
sleep(1);
print "In child $i\n";
exit($i);
// end child
}
}
// we are the parent (main), check child's (optional)
while(pcntl_waitpid(0, $status) != -1){
$status = pcntl_wexitstatus($status);
echo "Child $status completed\n";
}
// your other main code
?>
Для асинхронных http-запросов вы можете использовать multicurl: http://php.net/manual/en/function.curl-multi-init.php
Насколько я знаю, вы можете достичь этого двумя способами …
Использование:
Pthreads — это библиотека параллельной обработки, а amp — это чисто асинхронная среда …
Таким образом, способ использования pthreads заключается в том, чтобы сначала загрузить / включить расширение pthreads и добавить extension=/path/to/pthread.so
в файле php.ini …
А затем создать класс, который расширяет Thread
Класс и переопределите метод run, и поместите в него все, что вы хотите сделать параллельно.
Так что для вашей конкретной цели класс может выглядеть примерно так:
<?php
class Inserter extends Thread {
public $db_con = null;
public $data;
public function __construct($db_connection, $data) {
$this->db_con = $db_connection;
$this->data = data;
}
private function run() {
// use your logic to insert the data...
}
}
Чтобы использовать это, просто создайте экземпляр класса, поместите переменную соединения с БД и данные для обработки в ctor. И вызвать метод запуска объекта. Подобно:
$inserter = new Inserter($dbConn, $data);
$inserter->start();
куда $dbConn
хранит соединение с БД и $data
хранит необходимые данные.
И это все…