0

我有一个从 MySQL 数据库中绘制的表,其中包含 4 个字段:idpostcodeblacklist_reasonsignup_attempts

然后我有以下类来输出和处理这个问题,它是一个返回数组$MySQL的 mysql 类,而不是 MySQL 资源。ExecuteSQL

class Blacklist {

private $MySQL = null;
private $rowsPerPage = 6;

public function __construct( $MySQL ) {

    $this->MySQL = $MySQL;

}

public function displayBlacklistList( $page = 1 ) {

    ( $page == 1 ) ? $start = 0 : $start = $this->rowsPerPage*($page-1);

    $finish = $this->rowsPerPage;           

    $sql = "SELECT * FROM blacklist LIMIT $start, $finish";
    $res = $this->MySQL->ExecuteSQL($sql);

    echo '
    <p><a href="#" class="btn btn-success">Add row</a></p>
    <table class="table table-hover table-bordered table-striped">
        <thead>
            <tr>
                <th>ID</th>
                <th>Postcode</th>
                <th>Blacklist reason</th>
                <th>Signup attempts</th>
                <th>Actions</th>
            </tr>
        </thead>
    <tbody>';

    foreach( $res as $k => $v ) {
        echo '
        <tr>
            <td>'.$v['id'].'</td>
            <td>'.$v['postcode'].'</td>
            <td>'.$v['blacklist_reason'].'</td>
            <td>'.$v['signup_attempts'].'</td>
            <td><a href="#" class="btn btn-primary">Edit</a> <a href="#" class="btn btn-danger">Remove</a></td>
        </tr>';
    }

    echo '
    </tbody>
    </table>';

    echo $this->_displayPagination( $page, $res );
}
}

一切都按预期工作并显示,除非我在数据库中有 6 行并设置$this->rowsPerPage = 5为这会导致第二页(显示最后一行)循环并显示与表中的字段一样多的行,以及数据在每个单元格中是预期结果的第一个字符。如果我在表中有 10 行并且每页显示 9 行,也会发生同样的情况,等等。

例如我得到这个:

ID  Postcode    Blacklist reason    Signup attempts
7   7           7                   7
B   B           B                   B
A   A           A                   A
6   6           6                   6

当我期望:

ID  Postcode    Blacklist reason    Signup attempts
7   BH233SF     A reason            6

问题显然出在foreach()循环上,我习惯于在while( mysql_fetch_assoc() )这里使用循环,但在这种情况下,我使用的是返回数组而不是对象的类,我不知道为什么会这样。

-- 问题解答 --

executeSQL返回一个关联数组:

Array ( [id] => 7 [postcode] => BH233SF [blacklist_reason] => A reason [signup_attempts] => 6 )

它返回的内容很好,因为 var_dump 也证明了这一点:

array(4) { ["id"]=> string(1) "7" ["postcode"]=> string(7) "BH233SF" ["blacklist_reason"]=> string(8) "A reason" ["signup_attempts"]=> string(1) "6" }
4

3 回答 3

2

解决方案

显然,您的Mysql对象在执行只有一个结果的查询时直接返回一个关联数组。因此,在只有一页的情况下,您应该直接避免 foreach 循环并打印出结果值。或者,您可以只声明$res为一个单一值的数组,以防万一$page == 1

if ($page == 1)
    $res = array($res);

为什么会这样

您的$res数组是具有成对键值的哈希。这意味着foreach ($res as $a => $b)将遍历数组中的每个键(4 个键 = 4 次)必须是与键$b对应的值$a。在您的情况下$b,始终是一个字符串,因此b[...]被视为从字符串中选择一个字符。例如$v['id'],转换为$v[0](因为(int) 'id'= 0),返回第一个字符。

于 2013-04-16T12:13:36.713 回答
2

当您有多行时,您的数据库类似乎返回一个数组数组,但当只有一个时,只返回一个未嵌套的行。

因此,在第一页上,foreach循环返回 $v 中的一行,而最后一页只有一个值,而是循环遍历该行本身。

如果您在字符串上指定索引,它会在该位置返回一个字符,因为文字“id”不是有效数字,它会转换为零(假),因此$v['id']实际上被视为$v[0]返回第一个字符细绳。其他值也是如此。

如果您不能修改类以始终返回数组中的单行以保持一致性(这将是理想的解决方案),那么您需要检查是否已返回一行,然后自己嵌套结果。如果该类没有返回行数的方法,那么您可以这样做:

if (isset($res['id']))
   $res = array($res);
于 2013-04-16T12:23:15.990 回答
1

以你想要的方式工作,你应该有

array(
    0 => array(
        "id" => "7", 
        "postcode" => "BH233SF", 
        "blacklist_reason" => "A reason", 
        "signup_attempts" => "6")
);

否则,您的foreach循环会遍历列而不是行,这就是它变得混乱的原因。

于 2013-04-16T12:14:53.553 回答