CodeIgniter是否必须在最后一步加载视图?

时间:2010-05-23 18:40:21

标签: php codeigniter asynchronous task

我有一个功能

function do_something() {
    // process
    $this->load->view('some_view', $data);
    exec('mv /path/to/folder1/*.mp3 /path/to/folder2/');
}

我的目的是在输出视图后移动文件。但显然它是在渲染视图之前完成的。我的问题是,$this->load->view();必须是函数的最后一步吗?

我做了一些研究,似乎我的问题类似于this topic。正确的吗?

4 个答案:

答案 0 :(得分:2)

为什么不使用post_system钩子?在将最终页面发送到浏览器之后调用它,这样您就可以正常加载视图,而不会回显它们。

这是一个示例控制器:

class Home extends Controller {

    function index()
    {
        $this->move_audio = TRUE;
        $this->old_folder = "/path/to/folder/";
        $this->new_folder = "/path/to/folder2/";

        $this->load->view("some_view");
    }

}

示例钩子:

function post_system()
{
    $CI =& get_instance();

    if( isset($CI->move_audio) && $CI->move_audio === TRUE)
    {
        // Trim, then add trailing slash for consitency
        $old_folder = rtrim($CI->old_folder, "/")."/*.mp3";
        $new_folder = rtrim($CI->new_folder, "/")."/";

        exec("mv {$old_folder} {$new_folder}");
    }
}

查看hooks user guide了解有关设置的信息。他们是你的朋友!

编辑:我刚才想到的......

如果你只是在一个控制器方法中做这个......那么使用Phil的方法可能会更好。这样可以避免对每个请求进行挂钩调用,如果只需要一次就不需要它。

如果你只需要一次,你可以做的另一件事是使用控制器的_output()处理程序(info here)。这将是这样的:

class Home extends Controller {

    // Initalize the var to avoid having to
    // check if it's set or not

    var $move_audio = FALSE;

    // CONTROLLER METHOD    
    function index()
    {
        $this->move_audio = TRUE;
        $this->old_folder = "/path/to/folder/";
        $this->new_folder = "/path/to/folder2/";

        $this->load->view("some_view");
    }

    // OUTPUT HANDLER
    function _output($output = "")
    {
        echo $output;

        if($this->move_audio === TRUE)
        {
            // Trim, then add trailing slash for consitency
            $old_folder = rtrim($this->old_folder, "/")."/*.mp3";
            $new_folder = rtrim($this->new_folder, "/")."/";

            exec("mv {$old_folder} {$new_folder}");
        }
    }
}

答案 1 :(得分:1)

在运行命令之前将输出发送到浏览器:

function do_something()
{
    // process
    echo $this->load->view('some_view', $data, TRUE);
    exec('mv /path/to/folder1/*.mp3 /path/to/folder2/');
}

否则,您只是将数据提供给将在Controller完成后立即运行的Output类。

答案 2 :(得分:0)

没有。 实际上对于一些Web服务我刚刚使用过这样的东西:

function get_json_search() {
    $results = $this->My_model->get_stuffs();
    echo json_encode($results);
}

您还可以拥有完全私密的网络控制器功能。只需在前面加上'_'。你绝不会将这些视为页面。

function _upload_photo($filepath) { //resize it and so on

也许你误解了MVC。控制器是模型和视图之间的中介。同样,您也不需要使用模型。控制器只是从模型中获取东西并使用视图将其打印出来。没有理由(尽管风格不好)你不能使用控制器内或其他来源的数据或从控制器打印出你的页面。

如果先加载视图,我不明白为什么它不起作用。虽然我会反过来这样做,所以你可以向用户提供反馈。如果文件无法移动,您应该向他们显示错误。如果是性能密集型,请考虑使用队列或cron作业。

答案 3 :(得分:0)

<?php
    while (ob_get_level()) {
        ob_end_flush();
    }
    // start output buffering
    if (ob_get_length() === false) {
        ob_start();
    }

    class Something extends Controller {

        function do_something() {
            $this->load->view('some_view', $data);
            ob_flush(); flush();
            exec('mv /path/to/folder1/*.mp3 /path/to/folder2/');
        }
    }
?>