Laravel在前端控制器方法中打破foreach循环

时间:2016-05-27 10:32:59

标签: php laravel-4 foreach

我无法在Laravel Framework 4.2中中断Controller方法。 我有一个查询,它遍历一个包含~100K记录的表,并检查几个不同的属性,将它们重新分配到其他几个表中。

我想从前端故意中断这个循环。我在控制器类和Session变量中尝试了一个变量都无济于事。

我还有一个进度条,显示循环的状态。我已经把 它下方有一个按钮,用于中止该方法。

控制器:

class TeilnehmerController extends IXPController {

    public $abort; 

    public function recheckfailedbatch(){

        Session::forget('ALL');
        Session::forget('status');
        Session::forget('progress');
        Session::forget('abort');

        ini_set('memory_limit', '-1');
        ini_set('max_execution_time', '600');

        $anzahl['ALL']= anforderung_mangelhaft::all()->count();
        Session::set('ALL', $anzahl['ALL']);
        Session::set('status', true);

        $progress = "0";

        $all_fails = anforderung_mangelhaft::all();

        foreach ($all_fails as $fail){

          if ($this->abort){
              break(2);
          }

          $progress++;
          Session::set('progress', $progress);
          Session::save();

          // doing more secret fancy stuff here


       }

       Session::set('status', false);
       Session::forget('abort');
       Session::save();
       return Redirect::back()->with('successMessage', "Done.");

    }

    public function recheckfailedbatchstatus(){

        $status = Session::get('status');
        $progress = Session::get('progress');
        $all= Session::get('ALL');
          if ($all != 0){
            $percent = sprintf("%1\$.2f",$progress / $all * 100);

          }
          else{
            $percent = 0;
          }

        return Response::json(array('status' => $status, 'percent' => $percent));
    }

    public function recheck_abort(){

            #$this->abort = true;
            Session::set('abort', true);
            Session::save();
            return dump($this->abort);

    }

}

查看:

@extends('layouts.default')

@section('subview')
    <div>
        <h2 class="mb20">mangelhafte Anforderungen</h2>
        <ul id="sectionsubnav">
            <li>
                <a href="{{action('TeilnehmerController@recheckfailedbatch')}}" ><i class="icon-refresh"></i>Erneute Pr&uuml;fung</a>
                <a href="#collapseSuche" data-toggle="collapse" aria-expanded="false" aria-controls="collapseSuche"><i class="icon-search"></i>Detailsuche</a>
            </li>
        </ul>

        @include('components.sysmessages')   

        @if(Session::get('status'))
        <div class="well well-lg">
          <h4>Pr&uuml;fung l&auml;uft</h4>
            <div class="progress">

              <div id="progress-bar" class="progress-bar progress-bar-striped active" role="progressbar"
  aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width:0%">
        </div>
      </div>
      <a href="{{ action('TeilnehmerController@recheck_abort') }}" onClick="return confirm('Diese Aktion kann nicht r&uuml;ckg&auml;ngig gemacht werden. Sind Sie sicher?');" id="abort" class="btn btn-danger btn-lg" role="button"><i class="icon-remove"></i>Abbrechen</a>

</div>
@endif
<!-- some more fancy content -->
@stop


@section('bodybottomscripts')
    @parent
    <script>
        $(document).ready(function() {

    var element = $("#progress-bar");
    var test = setInterval( function(){ bar_progress() }, 500);

    function bar_progress() {
            $.get( "mangelhaft/recheck-status", function( data ) {
            if (data['status'] == false){
                clearInterval(test);
            }             
            element.text(data['percent'] + '%');
            element.attr("aria-valuenow", data['percent']);
            element.width(data['percent'] + '%'); 
    });
    }
    </script>
@stop

是否可以按照预期的方式进行?我还读过laravel中的队列。我宁愿实施队列来做那些事吗?

2 个答案:

答案 0 :(得分:0)

前端不知道后端,不能影响正在运行的脚本。这是因为前面只有在完成后才从后面获得输出。

您需要重新考虑您的方法,并可能使用ajax来检索您的数据,然后客户端代码可以决定是否与您的API联系,视具体情况而定。

答案 1 :(得分:0)

首先,我认为您不能只使用$this->abort来检查会话。将其替换为Session::get('abort'),看看它是否有效。这两个函数可能在两个不同的请求中起作用,它们与类成员或内存中的任何其他内容没有任何关系(除了一些例外,请参阅进一步说明)。

您可以使用文件来指示正在运行的脚本的中止。在recheck_abort中,创建一个空文件(最好使用操作系统的temp目录)。然后检查是否存在该文件,而不是检查$this->abort。使用此文件执行与使用会话unlink文件相同的操作(如果它在recheckfailedbatch的最开始时存在,并且最后也存在unlink

另一个解决方案是使用shared memory。这有点棘手,但可以正确完成工作。

我认为会话在请求开始时被读取,并且它不会反映当前正在运行时进一步请求所做的更改。我没有检查Laravel源代码以确定,但在处理请求时似乎会话变量驻留在内存中。

另一种解决方法是搜索在处理请求时如何刷新会话。这可能意味着要检查Laravel源代码,但检查它是否非常简洁。