You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于CodeIgniter在控制器内实现新增与编辑表单的技术问询

优化CodeIgniter控制器内直接拼接表单的实现方案

我看到你在CodeIgniter控制器里直接拼接HTML字符串来实现新增/编辑表单功能,这种写法虽然能快速跑通功能,但后续维护、修改和扩展都会非常麻烦,完全违背了MVC框架的职责分离原则。下面给你拆解问题并给出具体的优化方案:

1. 修复控制器职责混乱问题(核心优化)

控制器的核心职责应该是处理请求、调用模型获取数据、传递数据给视图,而不是直接拼接HTML。我们把HTML渲染逻辑完全移到视图文件中:

优化后的控制器代码

function get_master() {
    // 获取POST参数
    $store_id = $this->input->post('store_id');
    if (empty($store_id)) {
        // 处理参数缺失的情况,比如跳转回店铺选择页
        redirect('store_selection');
    }

    // 获取店铺信息并设置会话
    $get_store = $this->common->get_row(['store_id' => $store_id], DBPREFIX . "store");
    if (!$get_store) {
        show_error('店铺不存在');
    }
    $this->session->set_userdata([
        'store' => $get_store->store_state_id,
        'company' => $get_store->store_company_id
    ]);

    // 获取主数据列表(用于渲染表单)
    $data['masters'] = $this->common->get_whereresult(
        DBPREFIX . 'apimaster',
        [
            'master_status' => 1,
            'master_state' => $get_store->store_state_id
        ],
        'master_name'
    );

    // 加载视图,传递数据
    $this->load->view('metrc_settings/master_form', $data);
}

对应的视图文件(application/views/metrc_settings/master_form.php)

用CodeIgniter的视图语法渲染HTML,支持语法高亮,修改更方便:

<div class="container">
    <?php foreach ($masters as $master): ?>
        <div class="row">
            <div class="form-group col-md-12 col-sm-12 col-xs-12">
                <div class="panel panel-default">
                    <div class="panel-heading" role="tab" id="headingOne-<?= $master->master_id ?>">
                        <h4 class="panel-title" style="height:18px;">
                            <!-- 使用CodeIgniter的form_open辅助函数,自动处理CSRF(如果开启) -->
                            <?= form_open("add_metrcsettingmaster/{$master->master_id}") ?>
                                <div class="form-group col-md-2 col-sm-2 col-xs-12">
                                    <a 
                                        data-toggle="collapse" 
                                        data-parent="#accordion" 
                                        href="#collapseOne-<?= $master->master_id ?>" 
                                        aria-expanded="true" 
                                        aria-controls="collapseOne-<?= $master->master_id ?>"
                                    >
                                        <?= html_escape($master->master_name) ?>
                                    </a>
                                    <input type="hidden" name="master_id" value="<?= $master->master_id ?>">
                                </div>

                                <!-- 开始日期字段 -->
                                <div class="form-group col-md-2 col-sm-2 col-xs-12 start_date" style="margin-top:-8px;">
                                    <input 
                                        placeholder="Start Date" 
                                        type="text" 
                                        class="form-control hasDatepicker" 
                                        name="start_date" 
                                        value=""
                                    >
                                    <span class="start_datetext">Sync Active</span>
                                </div>

                                <!-- 结束日期字段 -->
                                <div class="form-group col-md-2 col-sm-2 col-xs-12 end_date" style="margin-top:-8px;">
                                    <input 
                                        placeholder="End Date" 
                                        type="text" 
                                        class="form-control hasDatepicker" 
                                        name="end_date" 
                                        value=""
                                    >
                                    <span class="end_datetext">Sync Expire</span>
                                </div>

                                <!-- 同步时间字段 -->
                                <div class="form-group col-md-2 col-lg-2 col-sm-2 col-xs-12 time" style="margin-top:-5px;">
                                    <input type="time" name="time" class="form-control" value="">
                                    <span class="timetext">Sync Time</span>
                                </div>

                                <!-- 重复日期多选框 -->
                                <div class="form-group col-md-2 col-sm-2 col-xs-12" style="margin-top: -5px">
                                    <select name="days[]" class="form-control status chosen-select" multiple="multiple">
                                        <option value="Monday">Monday</option>
                                        <option value="Tuesday">Tuesday</option>
                                        <option value="Wednesday">Wednesday</option>
                                        <option value="Thursday">Thursday</option>
                                        <option value="Friday">Friday</option>
                                        <option value="Saturday">Saturday</option>
                                        <option value="Sunday">Sunday</option>
                                    </select>
                                </div>

                                <!-- 手动/自动开关 -->
                                <div class="form-group col-md-2 col-lg-2 col-sm-2 col-xs-12" style="margin-top:-8px;text-align:center;">
                                    <label class="switch">
                                        <p style="margin-top:10px;margin-left:-60px;"> Manual </p>
                                        <p style="margin-top:-27px;margin-left:60px;"> Auto </p>
                                        <input type="checkbox" name="manauto" id="chkPassportt-<?= $master->master_id ?>" value="">
                                        <span class="slider round"></span>
                                    </label>
                                </div>

                                <!-- 提交按钮 -->
                                <div class="col-md-2 col-lg-2 col-sm-2 col-xs-12 pull-right" style="margin-top:-8px;">
                                    <input class="btn btn-danger" type="submit" name="submit" value="Submit">
                                </div>
                            <?= form_close() ?>
                        </h4>
                    </div>

                    <!-- 子项折叠面板 -->
                    <div id="collapseOne-<?= $master->master_id ?>" class="panel-collapse collapse" role="tabpanel" aria-labelledby="headingOne-<?= $master->master_id ?>">
                        <div class="panel-body">
                            <div id="childdata-<?= $master->master_id ?>">
                                <?php 
                                // 预加载当前主项的子数据(推荐在控制器中提前查询后传递,这里为了演示直接在视图调用)
                                $children = $this->common->get_whereresult(
                                    DBPREFIX . 'apichild',
                                    [
                                        'child_status' => 1,
                                        'child_master' => $master->master_id
                                    ],
                                    'child_apiname'
                                );
                                foreach ($children as $child): ?>
                                    <div class="row">
                                        <div class="form-group col-md-12 col-sm-12 col-xs-12">
                                            <!-- 子项表单内容,可参考主项的写法拆分到局部视图 -->
                                            <?= html_escape($child->child_apiname) ?>
                                        </div>
                                    </div>
                                <?php endforeach; ?>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    <?php endforeach; ?>
</div>

2. 新增编辑功能的支持

当前代码只有新增逻辑,我们可以扩展支持编辑:

  • 在控制器中判断是否存在编辑ID,查询对应数据传递给视图
  • 在视图中为表单字段赋值,实现数据回显

控制器新增编辑逻辑

function add_metrcsettingmaster($master_id = null) {
    // 判断是否为编辑模式
    $is_edit = false;
    $edit_data = [];
    if ($master_id && $this->input->server('REQUEST_METHOD') == 'GET') {
        $is_edit = true;
        $edit_data = $this->common->get_row(
            [
                'metrcsettingconf_master_id' => $master_id,
                'metrcsettingconf_company_id' => $this->session->userdata('company'),
                'metrcsettingconf_store_id' => $this->session->userdata('store')
            ],
            DBPREFIX . 'metrcsetting_conf'
        );
    }

    // 处理表单提交(新增/编辑)
    if ($this->input->server('REQUEST_METHOD') == 'POST') {
        // 验证表单数据
        $this->form_validation->set_rules('start_date', 'Start Date', 'required');
        // 其他验证规则...

        if ($this->form_validation->run()) {
            $post_data = $this->input->post();
            if ($is_edit) {
                // 执行更新逻辑
                $this->common->update(DBPREFIX . 'metrcsetting_conf', $post_data, ['metrcsettingconf_id' => $edit_data->metrcsettingconf_id]);
            } else {
                // 执行新增逻辑
                $this->common->insert(DBPREFIX . 'metrcsetting_conf', $post_data);
            }
            redirect('get_master');
        }
    }

    // 传递编辑数据到视图
    $data['is_edit'] = $is_edit;
    $data['edit_data'] = $edit_data;
    $data['master_id'] = $master_id;
    $this->load->view('metrc_settings/master_edit_form', $data);
}

视图中回显编辑数据

<input 
    placeholder="Start Date" 
    type="text" 
    class="form-control hasDatepicker" 
    name="start_date" 
    value="<?= $is_edit ? html_escape($edit_data->start_date) : '' ?>"
>

3. 其他优化建议

  • XSS安全防护:所有输出到HTML的动态内容都用html_escape()包裹,防止XSS攻击
  • 表单验证:使用CodeIgniter的form_validation类对用户输入进行验证,确保数据合法性
  • 代码复用:把重复的表单字段(比如日期选择器、开关组件)拆分成局部视图,通过$this->load->view('partials/_date_picker')复用
  • CSRF保护:开启CodeIgniter的CSRF防护,form_open()会自动生成CSRF令牌字段,防止跨站请求伪造

内容的提问来源于stack exchange,提问作者Amod Kumar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 09:09:09