如果列名称匹配变量,则仅打印行列

时间:2013-04-24 11:38:06

标签: php mysql

我有一个脚本从mysql结果生成一个表,我的目标是根据包含我想要显示的列名称的变量使列显示为完全动态。我已经用这段代码生成表格标题:

$search_field_names=explode(',', $search_field_names)    
for($i=0, $count=count($search_field_names);$i<$count;$i++) {
        echo ('<th>'.$search_field_names[$i].'</th>');
    }

其中$ search_field_names是逗号分隔的值字符串(例如fristname,lastname,user_id等)。

举一个例子,假设上面的字符串包含我想要显示的7个列名:

$search_field_names=('firstname,lastname,dob,company,position,user_id,date_added')

然后,第一个代码片段将生成一个包含这7个名称的表标题。

然后是棘手的部分:存储所有记录的数据库表共有22列。通过与第一个打印出记录的片段完全相同的事情,结果是它打印了该表中的前7列,这不一定是我想要的。

以下是我如何获取记录(这显然是在脚本中的上述片段之后):

$query=mysqli_query($mysqli, "SELECT * FROM table WHERE column_name1='$search_query' AND column_name2='$search_query' etc...);
while($row=mysqli_fetch_assoc($query)) {
echo('<tr>');
for($i=0, $count=count($search_field_names);$i<$count;$i++) {
        echo ('<td>'.$row[$i].'</td>');
    }
echo('</tr>');

所以,我想要实现的只是获取数据库中的列,这些列与变量$ search_field_names中设置的名称相对应。

1 个答案:

答案 0 :(得分:1)

Haider建议的两个解决方案使用您的$ search_field_names变量来调整您的查询:

$query=mysqli_query($mysqli, "SELECT ".implode(",", $search_field_names)." FROM table");
while($row=mysqli_fetch_assoc($query)) {
    echo('<tr>');
    for($i=0, $count=count($search_field_names);$i<$count;$i++) {
        echo ('<td>'.$row[$i].'</td>');
    }
    echo('</tr>');
}

或者,既然你正在做一个mysqli_fetch_assoc,这应该可行:

$query=mysqli_query($mysqli, "SELECT * FROM table");
while($row=mysqli_fetch_assoc($query)) {
    echo('<tr>');
    for($i=0, $count=count($search_field_names);$i<$count;$i++) {
        // Using header name as the key to the column
        echo ('<td>'.$row[ $search_field_names[$i] ].'</td>');
    }
    echo('</tr>');
}

编辑:到目前为止,我们只是巧妙地循环遍历$ search_field_names来生成结果表。您在上一条评论中询问我们是否可以在构建查询约束时使用相同的技巧。一个问题是,您似乎想要在查询中直接使用$ _POST。请不要这样做,这是SQL injections的来源。另一个问题是,我们永远不能聪明。如果所有字段都是相同的类型,我们可以这样做,但如果你的一个搜索字段是日期或整数,那么编写和调试将非常困难。

所以,如果你真的对你的查询很聪明,你可以这样做(假设所有搜索字段都是字符串值):

<?php
// Assuming you have a $post_array like so, where inputs have the same names as the column names in the database
// $post_array = array('username' => 'T', 'url' => 'http');

// Build constraints of the form column_name LIKE 'value%'
$constraints = array();
foreach ($post_array as $key => $value) {
    $constraints[] = "$key LIKE ?";
    $post_array[$key] = $value.'%';
}

// Build a query selecting the columns from $post_array, with corresponding constraints
// Note : replace " AND " by " OR " if you want the query to match ANY parameter.
$query_text = "SELECT ".implode(", ", array_keys($post_array))." FROM table WHERE ".implode(" AND ", $constraints);

// Prepare this query, we don't want SQL injections!
$query = $mysqli->prepare($query_text);

$bind = array();
foreach ($post_array as $key => $value) {
    // We need to use our bind variables outside the scope of this loop, so we create them in $GLOBALS
    $GLOBALS[$key] = $value;
    // Array of references to our bind variables.
    $bind[] = &$$key;
}
// Binding the parameters : we need as many 's' as there are inputs
$bindtypes = str_repeat('s', count($post_array))
call_user_func_array(array($query, 'bind_param'), array_merge( array($bindtypes), $bind ));
// Binding the retrieved columns
echo call_user_func_array(array($query, 'bind_result'), $bind);
$query->execute();

// Header row
echo '<tr>';
foreach ($post_array as $key => $value) {
    echo '<th>'.$key.'</th>';
}
echo '</tr>';

// Result rows
while ($query->fetch()) {
    echo('<tr>');
    foreach ($post_array as $key => $value) {
        echo '<td>', $$key, '</td>';
    }
    echo('</tr>');
}
?>