【问题标题】:Checking while loop key exists in seperate array检查while循环键是否存在于单独的数组中
【发布时间】:2014-10-10 15:56:13
【问题描述】:

检查了各种各样的问题,但无法找到我需要的东西,我有点茫然。

我正在尝试通过解析列名并将有效列名添加到 $colnames 数组中,然后将这些值作为标题添加到 CSV,然后只显示相关的从 MySQL 中选择要导出到 CSV 的列通过while循环从数据库中获取数据。

在其他问题的指导下,我特别查看了以下内容:How to get all the key in multi-dimensional array in php

代码如下:

function query_to_csv($query, $filename, $attachment = false, $headers = true, $specs_off = false) {

    if($attachment) {
        // send response headers to the browser
        header( 'Content-Type: text/csv; charset=UTF-8' );
        header( 'Content-Disposition: attachment;filename='.$filename);
        $fp = fopen('php://output', 'w');
    } else {
        $fp = fopen($filename, 'w');
    }

    $result = mysql_query($query) or die( mysql_error() );

    if($headers) {
        // output header row (if at least one row exists)
        $row = mysql_fetch_assoc($result);
        if($row) {

            // PRODUCTS TABLE SPECIFIC - get rid of specs_ and free_ columns so have nicer data set for user
            if($specs_off) { 

                $columnames = array_keys($row);   
                $colnames = array(); 
                //$colnames = array_keys($row);

                foreach($columnames as $key => $value) {

                    if((substr_count($value, "spec_") < 1) && (substr_count($value, "free_") < 1))  {
                        array_push($colnames, $value);                                  
                    }

                }
            }
            else {
                $colnames = array_keys($row);
            }

            // add in additional columns if exporting client data  
            if($table == 'clients') {array_push($colnames, "products", "last_order_date");}

            //write the colnames to the csv file
            fputcsv($fp, $colnames);

            // reset pointer back to beginning
            mysql_data_seek($result, 0);
        }
    } // done with the headers etc, now lets get on with the data


    // clear out and create the $row_data array 
    $row_data = array(); 

    // run through the row array adding values to row_data as we go 
    while($row = mysql_fetch_assoc($result)) {

        // create the array_keys_multi from https://stackoverflow.com/questions/11234852/how-to-get-all-the-key-in-multi-dimensional-array-in-php/11234924#11234924
        function array_keys_multi(array $array) {
            $keys = array();

            foreach ($array as $key => $value) {
                $keys[] = $key;

                if (is_array($array[$key])) {
                    $keys = array_merge($keys, array_keys_multi($array[$key]));
                }
            }

            return $keys;

        }

        // run the function on the $row array
        array_keys_multi($row); 

        // now use the $keys array  
        foreach($keys as $key => $value) {

             // check if the value is in the colnames array and if so push the data on to the $row_data array ready for export to CSV
             if(in_array($value, $colnames)) {
                 array_push($row_data, $row[$value]);
             }
        }

        // now we are ready to write the CSV
        fputcsv($fp, $row_data);

    }

    fclose($fp);
    exit;

} // end of query_to_csv

// Write the sql statement
$sql = "SELECT * FROM ".$table." "; 
if(isset($where_1_col)) { $sql .= " WHERE `".$where_1_col."` = '".$where_1_val."'"; }
if(isset($where_2_col)) { $sql .= " AND `".$where_2_col."` = '".$where_2_val."'"; }
if(isset($where_3_col)) { $sql .= " AND `".$where_3_col."` = '".$where_3_val."'"; }
if(isset($where_4_col)) { $sql .= " AND `".$where_4_col."` = '".$where_4_val."'"; }
if(isset($order_by_col)) { $sql .= " ORDER BY `".$order_by_col."` ". strtoupper($order_by_dir) ." "; }

// output as an attachment
query_to_csv($sql, $table."_export.csv", true, true, true);

我得到的只是所选列名的大量导出,其重复次数与初始查询中的值一样多。我不知道如何获取值。

欢迎任何关于我哪里出错或如何更巧妙地处理此问题的建议。

【问题讨论】:

  • 您可以使用array_keys() 来获取密钥。 php.net/manual/de/function.array-keys.php |而且我认为您需要将array_keys_multi($row); 更改为$keys = array_keys_multi($row);
  • 在我对您的回答发表评论后,我将您的上述评论与您的​​建议结合起来,完全删除了 array_multi_keys(array $array) 函数并替换为 $keys = array_keys($row);。然后,$keys 数组将根据 $colnames 数组进行检查,如原始代码所示。它有效。现在不知道我如何表明哪一点对我有帮助。

标签: php mysql arrays csv fputcsv


【解决方案1】:

您似乎只是将新行数据附加到$row_data,但从未清除该数组。

array_push($row_data, $row[$value]);

我做了什么来解决它:

移动

// clear out and create the $row_data array 
$row_data = array(); 

进入while循环。

改变

// clear out and create the $row_data array 
$row_data = array(); 
while($row = mysql_fetch_assoc($result)) {
...
}

到

while($row = mysql_fetch_assoc($result)) {
// clear out and create the $row_data array 
$row_data = array(); 
...
}

注意:
您在任何地方都在使用$table,但从未定义它。喜欢这里if($table == 'clients')
如果它是全局变量,您还需要在函数中添加 global $table 或参数。

编辑:
正如我在对您的问题的评论中提到的,您可以使用 array_keys() 来获取密钥。 php.net/manual/de/function.array-keys.php
然后改变

array_keys_multi($row); 

到

$keys =  array_keys($row);

之后你可以删除array_keys_multi()

您还可以将该部分移到您的 while 循环前面,因为您只需要计算一次所需的列名,而不是在每次迭代中。

【讨论】:

  • 非常感谢 endofsource。我按照建议将$row_data = array(); 移到了while 循环中,但仍然没有乐趣。该脚本似乎已被array_multi_keys(array $array) 函数损坏,因为如果包含它,它就不会运行。如果我注释掉,它会运行并只导出标题行,没有实际数据。 $table 变量以 $_GET 的形式提供。很抱歉遗漏了这一点。再次感谢您的帮助。
猜你喜欢
  • 1970-01-01
  • 2019-04-19
  • 1970-01-01
  • 2011-05-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-08
  • 2023-03-06
相关资源
最近更新 更多