2012-06-03 53 views
0

我正在创建一个分页脚本,我需要获取数据库查询中的第一个和最后一个结果,以便我可以确定当用户单击要转到的页面时显示的结果。这是我在一分钟代码:如何从查询中获取第一个和最后一个结果?

// my database connection is opened 

// this gets all of the entries in the database 
$q = mysql_query("SELECT * FROM my_table ORDER BY id ASC"); 
$count = mysql_num_rows($q); 
// this is how many results I want to display 
$max = 2; 
// this determines how many pages there will be 
$pages = round($count/$max,0); 
// this is where I think my script goes wrong 
// I want to get the last result of the first page 
// or the first result of the previous page 
// so the query can start where the last query left off 
// I've tried a few different things to get this script to work 
// but I think that I need to get the first or last result of the previous page 
// but I don't know how to. 
$get = $_GET['p']; 
$pn = $_GET['pn']; 
$pq = mysql_query("SELECT * FROM my_table ORDER BY id ASC LIMIT $max OFFSET $get"); 

// my query results appear 

if(!$pn) { 
    $pn = 1; 
} 
echo "</table><br /> 
Page $pn of $pages<br />"; 
for($p = 1;$p<=$pages;$p++) { 
    echo "<a href='javascript:void(0);' onclick='nextPage($max, $p);' title='Page $p'>Page $p</a> "; 
} 
+2

**你的代码容易受到SQL注入的攻击**你应该使用准备好的语句,将你的变量作为参数传递给你,这些参数不会被SQL评估。如果你不知道我在说什么,或者如何解决它,请阅读[Bobby Tables](http://bobby-tables.com)的故事。 – eggyal

+1

另外,请停止使用古老的MySQL扩展编写新代码:它不再被维护,并且社区已经开始[弃用过程](http://news.php.net/php.internals/53799)。相反,您应该使用改进的[MySQLi](http://php.net/mysqli)扩展或[PDO](http://php.net/pdo)抽象层。 – eggyal

+0

目前尚不清楚问题是什么。 –

回答

3

我认为你在那里几乎没有问题,但我试着为你解决它们。首先,正如上面的评论所述,您正在使用易受SQL注入攻击的代码。注意这一点 - 您可能想使用PDO,这与MySQL扩展一样易于使用,并且可以为您节省很多麻烦(如注入)。

但你的代码,让我们去通过它:

  1. 你应该问DB获得的行数,不使用MySQL的功能,它更有效,所以使用SELECT count(*) FROM mytable
  2. 对于$pages如果你想要打印所有行,如果你有$max 5并且有11行,round将会使得$pages 2实际上你想要3(最后一页只包含最后11行)
  3. 在LIMIT中您要LIMIT row_count OFFSET offset。你可以从页码计算偏移量,所以:$max = row_count但是$offset = ($max * $page) - $max。在你的代码,如果$get是直接在页面,这意味着你得到$ get'th行(不知道虽然你的JS下一页会发生什么。裸记住,并不是所有使用JavaScript。)

我已经准备了一个简单的例子,使用PDO,也许这让你知道使用PDO有多简单。

的选择行显示例如如何把SQL中的参数,它会在这种情况下,国家绝对安全,'SELECT * FROM pseudorows LIMIT '.$start.','.$max由我想让一个例子是多么容易(再保险):

// DB config 
$DB_NAME = 'test'; 
$DB_USER = 'test'; 
$DB_PASSWD = 'test'; 

    // make connection 
try { 
    $DB_CONN = new PDO("mysql:host=localhost;dbname=".$DB_NAME, $DB_USER, $DB_PASSWD); 
    $DB_CONN->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
} catch (PDOException $e) { 
    die($e); 
} 

// lets say user param 'p' is page, we cast it int, just to be safe 
$page = (int) (isset($_GET['p'])?$_GET['p']:1); 
// max rows in page 
$max = 20; 

// first select count of all rows in the table 
$stmt = $DB_CONN->prepare('SELECT count(*) FROM pseudorows'); 
$stmt->execute(); 
if($value = $stmt->fetch()) { 
    // now we know how many pages we must print in pagination 
    // it's $value/$max = pages 
    $pages = ceil($value[0]/$max); 

    // now let's print this page results, we are on $page page 
    // we start from position max_rows_in_page * page_we_are_in - max_rows_in_page 
    // (as first page is 1 not 0, and rows in DB start from 0 when LIMITing) 
    $start = ($page * $max) - $max; 
    $stmt = $DB_CONN->prepare('SELECT * FROM pseudorows LIMIT :start,:max'); 
    $stmt->bindParam(':start',$start,PDO::PARAM_INT); 
    $stmt->bindParam(':max', $max,PDO::PARAM_INT); 
    $stmt->execute(); 

    // simply just print rows 
    echo '<table>'; 
    while($row = $stmt->fetch()) { 
     echo '<tr><td>#'.$row['id'].'</td><td>'.$row['title'].'</td></tr>'; 
    } 
    echo '</table>'; 

    // let's show pagination 
    for($i=1;$i<=$pages;$i++) { 
     echo '[ <a href="?p='.$i.'">'.$i.'</a> ]'; 
    } 
} 
+0

这很好,谢谢! – JustSomeGuy

0

mysql_fetch_array返回一个关联数组

这意味着你可以使用resetend拿到第一个和最后的结果:

$pqa = mysql_fetch_array($pq); 
$first = reset($pqa); 
$last = end($pqa); 

我不明白你打算如何使用实际结果,只是页码应该足够分页。

不过,希望它有帮助。 是的,升级到mysqli,所以你的代码不会被废弃。

相关问题