使用内爆时出现 CSV 错误

CSV error while using implode

请帮忙,我是 Yii 的新手。我想从 CGridView 中选中的行生成并导出 CSV 文件。当我使用静态 SQL 查询时它正常工作,但是当我在 WHERE 子句中使用 implode 函数时 - 控制器 returns 出错。 我调用控制器动作的按钮:

$this->widget('bootstrap.widgets.TbButtonGroup', array(
'type' => 'primary',
'size'=>'mini',
'buttons' => array(
    array(
        'label' => 'Export',
        'type' => 'success',
        'buttonType'=>'ajaxLink',
        'encodeLabel'=>true,
        'icon'=> 'th white',
        'url'=>Yii::app()->createUrl('/propertyPurchaseSale/ExportChecked'),
        'ajaxOptions'=>array(
        "type" => "post",
        "data" => "js:{ids:$.fn.yiiGridView.getSelection('property-purchase-sale-grid')}",
        "update" => '#', 'success'=>"js:function(data) {window.location.assign('/propertyPurchaseSale/ExportChecked');}"),                                                
                              array( //htmlOptions
                                    )                                    
                                ),
                array(
                    ...
                ),
                ),
            ));

我的控制器操作:

public function actionExportchecked() {
        header('Content-type: text/csv');
        header('Content-type: multipart/form-data');
        header('Content-Disposition: attachment; filename="Export_(' . date('H-i_d.m.Y') .').csv"');
        header('Content-Transfer-Encoding: binary'); 
        header('Expires: 0');
        header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
        header('Content-Description: File Transfer');
                    $fp = fopen('php://output', 'w');

        if(Yii::app()->request->isAjaxRequest)
        {
            if(isset($_POST['ids']))
            {       
                $idx = $_POST['ids'];
                $count=Yii::app()->db->createCommand('SELECT COUNT(*) FROM property')->queryScalar();
                // $sql='SELECT * FROM property WHERE id  IN (981, 982, 985)';  --> when I use static values - all work
                $sql="SELECT * FROM property WHERE id IN('".implode("', '",$idx)."')";  // --> when I use join or implode function - data exist in firebug, but page return error 500

                $dataProvider=new CSqlDataProvider($sql, array(
                    'totalItemCount'=>$count,
                    'sort'=>array(
                        'attributes'=>array(
                             'fullname', 'address', 'phone', 'db_number', 'created_date'
                        ),
                    ),
                    'pagination'=>false,
                ));
                                    fputs($fp, $bom =( chr(0xEF) . chr(0xBB) . chr(0xBF) ));
                                    if ($fp)
                                    {                        
                        echo    PropertyPurchaseSale::model()->getAttributeLabel("id").";".
                                    PropertyPurchaseSale::model()->getAttributeLabel("fullname").";".
                                PropertyPurchaseSale::model()->getAttributeLabel("address").";".
                                PropertyPurchaseSale::model()->getAttributeLabel("phone").";".
                                PropertyPurchaseSale::model()->getAttributeLabel("db_number").";".
                                PropertyPurchaseSale::model()->getAttributeLabel("created_date").
                                " \r\n";                        
                        foreach ($dataProvider->getData() as $data) {
                            echo $data['id'] . '; ' . $data['fullname'] . '; ' . $data['address'] . '; ' . $data['phone'] . '; ' . $data['db_number'] . '; ' . $data['created_date'] . '; ' . "\r\n";
                        }
            }
                    exit;
                }
            }}

求助,我做错了什么?

我下意识的反应是没有任何东西可以证实 $_POST['ids'] 是一个数组。如果它只是一个字符串,那么 implode 将失败,SQL 将被不正确地格式化,这将导致 500 级错误。

也许这可行:

// check for empty, that way invalid entry won't go through
if(!empty($_POST['ids'])) {
    // Check if it is an array
    $input_idx = is_array($_POST['ids'])?
        // if so, then use it as an array
        $_POST['ids']:
        // If not, you need to turn it into an array. I'm only guessing that this should 
        // be a ','. It could be a " " or some other character(s)
        explode(',',$_POST['ids']);
    // Remove all non-numeric items in the array.
    $idx = array_filter($input_idx, 'is_numeric');
    if(!$idx) {
        // Do something with bad data.
    }
    // continue with the line $count = ...

您还应该确保数据安全,因为这些 ID 可能包含 SQL 注入。 (Perhaps this answer)