Wywołanie metody asynchronicznej PHP w ramach Yii

Pytanie

Chcę wiedzieć, czy możliwe jest asynchroniczne wywołanie metody kontrolera Yii z jednej z jego akcji, gdy akcja renderuje widok, pozostawiając metodę na zakończenie długiej operacji. Chciałbym zrobić coś takiego jak poniższy kod i nie muszę zwracać wynikumy_long_running_func.

<code>public function actionCreate() {
    $model = new Vacancies;
    if (isset($_POST['Vacancies'])) {
        $model->setAttributes($_POST['Vacancies']);
        $model->save();
        //I wish :)
        call_user_func_async('my_long_running_func',$model);
    }
    $this->render('create', array( 'model' => $model));
}
</code>
Problem

Próbuję napisać akcję kontrolera w Yii, która publikuje wakat i powiadamia zainteresowanych subskrybentów o tym poście. Problem polega na tym, że wykonanie zapytania powiadomienia zajmuje dużo czasu.

Teraz szukam sposobu na asynchroniczne uruchomienie zapytania, aby plakat widział jego odpowiedź w tak krótkim czasie, jak to możliwe, podczas gdy zapytanie działa w tle w sposób podobny do delegatów C # lub zdarzeń.

Rozwiązania, które znalazłem w wyszukiwarceżądania asynchroniczne w trakcie działania kontrolera, ale wszystko, co chcę zrobić, to uruchomić metodę kontrolera asynchronicznie, a akcja musiałaczekać dopókiupraszanie) zostały zakończone.

Próbowałem

Wypróbowałem następujące metody, ale zapytanie nadal jest wolne dla moich danych testowych około 1500 użytkowników.

Yii ActiveRecord

<code>if ($vacancy->save()) {                
    if($vacancy->is_active == 1) {
        $url = Yii::app()->createUrl('vacancies/view',array('id'=>$model->id));
        $trainees = YumUser::getUsersByRole('Trainees');
        if($trainees!=null) {
            foreach($trainees as $trainee){
                $message = new YumMessage;
                $message->from_user_id = Yii::app()->user->id;
                $message->title = 'Vacancy Notification: '.date('M j, Y');
                $message->message = "A new vacancy has been posted at <a href='{$url}'>{$url}</a>.";
                $message->to_user_id = $trainee->id;
                $message->save();                
            }
        }
    }    
}
</code>

Obiekty dostępu do danych Yii

<code>if ($vacancy->save()) {        
    if($vacancy->is_active == 1) {
        $url = Yii::app()->createAbsoluteUrl('vacancies/view',array('id'=>$model->id));
        $trainee_ids=Yii::app()->db->createCommand()->select('user_id')->from('trainee')->queryColumn();
        $fid=Yii::app()->user->id;
        $msg="A new vacancy has been posted at <a href='{$url}'>{$url}</a>.";
        $ts = time();
        $tt = 'Vacancy Notification: '.date('M j, Y');
        if($trainee_ids!=null) {
            foreach($trainee_ids as $trainee_id){
                Yii::app()->db->createCommand()
                  ->insert('message',array('timestamp'=>$ts,'from_user_id'=>$fid,'to_user_id'=>$tid,'title'=>$tt,'message'=>$msg));
            }
        }
    }
}
</code>

Przygotowane oświadczenia

<code>if ($vacancy->save()) {                
    if($vacancy->is_active == 1) {
        $url = Yii::app()->createUrl('vacancies/view',array('id'=>$model->id));                    
        $trainee_ids=Yii::app()->db->createCommand()->select('user_id')->from('trainee')->queryColumn();
        $fu=Yii::app()->user->id;
        $msg="A new vacancy has been posted at <a href='{$url}'>{$url}</a>.";
        $ts = time();
        $tt = 'Vacancy Notification: '.date('M j, Y');
        $sql="INSERT INTO message (timestamp,from_user_id,title,message,to_user_id) VALUES (:ts,:fu,:tt,:msg,:tu)";
        if($trainee_ids!=null) {
            foreach($trainee_ids as $trainee_id){

                $command=Yii::app()->db->createCommand($sql);
                $command->bindParam(":ts",$ts,PDO::PARAM_INT);
                $command->bindParam(":fu",$fu,PDO::PARAM_INT);
                $command->bindParam(":tt",$tt,PDO::PARAM_STR);
                $command->bindParam(":msg",$msg,PDO::PARAM_STR);
                $command->bindParam(":tu",$trainee_id,PDO::PARAM_INT);

                $command->execute();

            }
        }
    }
}
</code>
Badania

Sprawdziłem również następujące strony internetowe (mogę publikować tylko dwa linki), ale wymagają one, aby akcja poczekała, aż żądanie zostanie ukończone lub będzie wymagało zwinięcia (na które nie mam dostępu na serwerze wdrażania) lub potrzebuję zewnętrznej biblioteki. Liczyłem na natywną implementację PHP.

Symulowanie wielowątkowości w PHPWielowątkowość w phpAsynchroniczne wywołania PHP?Asynchroniczne przetwarzanie w PHPEdytować

Udało mi się znacznie skrócić czas odpowiedzi, przepisując moje zapytanie w ten sposób (przenosząc pętlę użytkownika do warstwy bazy danych):

<code>public function actionCreate() {
    $user=YumUser::model()->findByPk(Yii::app()->user->id);
    $model = new Vacancies;
    $model->corporate_id=$user->professional->institution->corporate->id;
    $model->date_posted=date('Y-m-d');
    $model->last_modified=date('Y-m-d H:i:s');

    if (isset($_POST['Vacancies'])) {
        $model->setAttributes($_POST['Vacancies']);
        if ($model->save()) {                
            if($model->is_active == 1) {
                $url = Yii::app()->createAbsoluteUrl('vacancies/view',array('id'=>$model->id));                    
                $fu=Yii::app()->user->id;
                $msg="A new vacancy has been posted at <a href='{$url}'>{$url}</a>.";
                $ts = time();
                $tt = 'New Vacancy: '.$model->title;
                $sql='INSERT INTO message (timestamp,from_user_id,title,message,to_user_id) SELECT :ts,:fu,:tt,:msg,t.user_id FROM trainee t';
                Yii::app()->db->createCommand($sql)->execute(array(':ts'=>$ts,':fu'=>$fu,':tt'=>$tt,':msg'=>$msg));
            }                
            if (Yii::app()->getRequest()->getIsAjaxRequest())
                Yii::app()->end();
            else
                $this->redirect(array('view', 'id' => $model->id));
        }
    }
    $this->render('create', array( 'model' => $model));
}
</code>

Niezależnie od tego byłoby miło, gdyby ktoś mógł opublikować sposób wywoływania funkcji asynchronicznie.

questionAnswers(3)

yourAnswerToTheQuestion