网络中流行的PHP分页效果


自动适应范围的页码分页程序
也就是说,页码格式如下
<< < 1 2 3 4 5 6 7 > >>
<< < 6 7 8 9 10 11 12 > >>


<?php
/*
* author:php100.com 论坛 nicholas_ng
*/
function page($page,$total,$phpfile,$pagesize=3,$pagelen=3){
$pagecode = '';//定义变量,存放分页生成的HTML
$page = intval($page);//避免非数字页码
$total = intval($total);//保证总记录数值类型正确
if(!$total) return array();//总记录数为零返回空数组
$pages = ceil($total/$pagesize);//计算总分页
//处理页码合法性
if($page<1) $page = 1;
if($page>$pages) $page = $pages;
//计算查询偏移量
$offset = $pagesize*($page-1);
//页码范围计算
$init = 1;//起始页码数
$max = $pages;//结束页码数
$pagelen = ($pagelen%2)?$pagelen:$pagelen+1;//页码个数
$pageoffset = ($pagelen-1)/2;//页码个数左右偏移量

//生成html
$pagecode='<div class="page">';
$pagecode.="<span>$page/$pages</span>";//第几页,共几页
//如果是第一页,则不显示第一页和上一页的连接
if($page!=1){
$pagecode.="<a href=\"{$phpfile}?page=1\"><<</a>";//第一页
$pagecode.="<a href=\"{$phpfile}?page=".($page-1)."\"><</a>";//上一页
}
//分页数大于页码个数时可以偏移
if($pages>$pagelen){
//如果当前页小于等于左偏移
if($page<=$pageoffset){
$init=1;
$max = $pagelen;
}else{//如果当前页大于左偏移
//如果当前页码右偏移超出最大分页数
if($page+$pageoffset>=$pages+1){
$init = $pages-$pagelen+1;
}else{
//左右偏移都存在时的计算
$init = $page-$pageoffset;
$max = $page+$pageoffset;
}
}
}
//生成html
for($i=$init;$i<=$max;$i++){
if($i==$page){
$pagecode.='<span>'.$i.'</span>';
} else {
$pagecode.="<a href=\"{$phpfile}?page={$i}\">$i</a>";
}
}
if($page!=$pages){
$pagecode.="<a href=\"{$phpfile}?page=".($page+1)."\">></a>";//下一页
$pagecode.="<a href=\"{$phpfile}?page={$pages}\">>></a>";//最后一页
}
$pagecode.='</div>';
return array('pagecode'=>$pagecode,'sqllimit'=>' limit '.$offset.','.$pagesize);
}
?>


===========提供======演示================

<?php
$phpfile = 'index.php';//页面文件名
$page= isset($_GET['page'])?$_GET['page']:1;//默认页码
$db = mysql_connect('localhost','test','test');//链接数据库
mysql_select_db('test',$db);//选择数据库
$counts = mysql_num_rows(mysql_query('select `id` from `test`',$db));//获取需要的数据总条数
$sql='select `id`,`title` from `test`';//定义查询语句SQL
$getpageinfo = page($page,$counts,$phpfile);//调用函数,生成分页HTML 和 SQL LIMIT 子句
$sql.=$getpageinfo['sqllimit'];//组合完整的SQL语句
$data = $row = array();//初始化数组
$result = mysql_query($sql,$db);//获取结果集
//将数据装入$data数组
while($row = mysql_fetch_array($result)){
$data[]=$row;
}
?>
<?php
echo $getpageinfo['pagecode'];//显示分页的html代码
?>

PHP100编程安全性小结

  规则 1:绝不要信任外部数据或输入

  关于 Web 应用程序安全性,必须认识到的第一件事是不应该信任外部数据。外部数据(outside data) 包括不是由程序员在 PHP 代码中直接输入的任何数据。在采取措施确保安全之前,来自任何其他来源(比如 GET 变量、表单 POST、数据库、配置文件、会话变量或 cookie)的任何数据都是不可信任的。

  对用户输入进行清理的一个简单方法是,使用正则表达式来处理它。

  规则 2:禁用那些使安全性难以实施的 PHP 设置

  已经知道了不能信任用户输入,还应该知道不应该信任机器上配置 PHP 的方式。例如,要确保禁用 register_globals。如果启用了 register_globals,就可能做一些粗心的事情,比如使用 $variable 替换同名的 GET 或 POST 字符串。通过禁用这个设置,PHP 强迫您在正确的名称空间中引用正确的变量。要使用来自表单 POST 的变量,应该引用 $_POST['variable']。这样就不会将这个特定变量误会成 cookie、会话或 GET 变量。

  要 检查的第二个设置是错误报告级别。在开发期间,希望获得尽可能多的错误报告,但是在交付项目时,希望将错误记录到日志文件中,而不是显示在屏幕上。为什么 呢?因为恶意的黑客会使用错误报告信息(比如 SQL 错误)来猜测应用程序正在做什么。这种侦察可以帮助黑客突破应用程序。为了堵住这个漏洞,需要编辑 php.ini 文件,为 error_log 条目提供合适的目的地,并将 display_errors 设置为 Off。

  规则 3:如果不能理解它,就不能保护它

  一些开发人员使用奇怪的语法,或者将语句组织得很紧凑,形成简短但是含义模糊的代码。这种方式可能效率高,但是如果您不理解代码正在做什么,那么就无法决定如何保护它。

  规则 4:“纵深防御” 是新的法宝

  即使使用 PHP regex 来确保 GET 变量完全是数字的,仍然可以采取措施确保 SQL 查询使用转义的用户输入。

  纵深防御不只是一种好思想,它可以确保您不会陷入严重的麻烦。

一个网络,两种中文

 

越来越多的迹象表明,中国的网络监管部门已经开始了它们的“白名单”计 划。根据这个计划,凡是提供中文内容的网站,如果没有向中国的有关部门做出备案,报告自己的姓名、身份证号、住址、电话、居所,那么就会在2009年12 月底之前被彻底屏蔽,无法直接在中国大陆进行访问。在最近几天,很多中小型网站和独立博客已经遭遇这样的命运。根据一份官方的评论文章,受到影响的站点超 过300万个。其中,包括我的个人博客。

备案是一个法律所规定的程序,这使得整件事情看起来像是一个严肃的执法过程。不过,相信有许多站长和Blogger并不那么看。对于开设论坛的站长 来说,备案需要他们拥有自己的公司,同时拥有100万元以上的资金。论坛为什么会和实体以及巨额的资金联系起来,这让人感觉非常困惑。一个漫画论坛或者读 书论坛如何能筹措100万元资金?而对于Blogger而言,即便是在报纸和杂志上发表文章,编辑部也从来不曾索要过如此详细的个人资料。令人好奇的是, 要这些个人资料去做什么呢?

许多Blogger和我做了一样的选择---购买国外网络服务商提供的域名,把博客迁移到海外服务器上。这并不能有效避免跨省追捕,但是多少让人心 理上觉得有一点宽慰。现在,这种模式遭到了严厉的打击。很明显,类似这样的海外中文网站并不在白名单之列,也就无法直接访问。由此,产生了一系列有趣的问 题:

按照现行的规定,其实是中国的网络监管部门对所有的中文内容网站宣布了管辖权。只要你在网络上用中文发表内容,那么就必须备案,否则中国大陆人民就 无法访问。那么,加拿大的华人网站需要向中国政府备案么?他们使用中文,但是站长很可能是加拿大公民。为什么加拿大公民要服从中国政府的管理?美国呢?新 加坡呢?澳大利亚呢?这一管辖权是根据语言而来的,那么,英美会不会要求全世界的英文站点向它们备案?比如说CCTV-9,或者是《中国日报》的站点?除 了普通网民,世界上也有大量政府网站、公司网站、公益网站提供中文页面,需要不需要让美国白宫的网站也在中国备案?是否需要联合国的网站也在中国备案?给 我一个理由,它们为什么要这么做?

现在看起来它们不用,对了,有一张白名单。在这张白名单上的站点都是“安全的”。那么,我们不妨考虑一下“不安全”的情况:当一家外国法人持有的网 站发生了“安全问题”,去纠正或者追究责任,难道这要比找到一个开设BBS或者博客的中国人困难?有互联网以来的十余年间,类似的事情从来没有发生过。有 “安全问题”的中国网友总在第一时间被找到,而且被警告或者惩戒。所以,所有的过错无非是:

1、 有人使用中文作为网站内容。
2、 他们没有提供个人详细资料。

判罚依据是:如果这些人是外国人,那么没有问题;如果这些人是中国人,那么关闭站点。

也就是说,中文被泾渭分明地划分为两部分。一种是中国人可以看的中文,一种是除了中国人全世界都可以看到的中文。它们的区别在于,对于全世界它们都 是可见的,但是对于中国人来说,只有一部分可见。而之所以如此,是因为你持有中国护照,在中国生活。我觉得,这一政策有效地把中国人和世界上的其它居民有 效地区分开来,看到人类文明史上最宽广的一道数字鸿沟。它让高达三亿两千万人口在虚拟世界里处于隔绝状态,以至于让我不得不看一下门口有没有写着一个牌 子,上面写着:第九区。

10个节约开发时间的CSS技巧

1.简单的纯CSS Tooltip

通过这些代码,你可以做出简单的Tooltip。这是CSS代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
a:hover {
 background:#ffffff; /*要兼容IE6的话必须添加背景色*/
 text-decoration:none;
}
a.tooltip span {
 display:none;
 padding:2px 3px;
 margin-left:8px;
 width:130px;
}
a.tooltip:hover span{
 display:inline;
 position:absolute;
 background:#ffffff;
 border:1px solid #cccccc;
 color:#6c6c6c;
}


HTML代码如下:

1
Easy <a class="tooltip" href="#">Tooltip<span>This is a Example by imbolo.com.</span></a>.

效果如图。

2.重设基本样式

为了统一不同浏览器对各种HTML标签的默认样式的渲染,我们必须从新定义各种标签的样式,这样能对以后的开发带来方便。重新定义各种HTML标签只需要在CSS的开头加入以下代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, font, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td {
 margin: 0;
 padding: 0;
 border: 0;
 outline: 0;
 font-size: 100%;
 vertical-align: baseline;
 background: transparent;
}
body {
 line-height: 1;
}
ol, ul {
 list-style: none;
}
blockquote, q {
 quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
 content: none;
}
 
/* 元素获得焦点时的样式! */
:focus {
 outline: 0;
}
 
/* 特殊文本的样式! */
ins {
 text-decoration: none;
}
del {
 text-decoration: line-through;
}
 
/* 细线表格样式 */
table {
 border-collapse: collapse;
 border-spacing: 0;
}

3.方便的CSS调试器

这段代码可以把页面上的各种标签嵌套用不同的线条划分出来,方便你找出BUG。

1
2
3
4
5
6
7
8
* { outline: 2px dotted red }
* * { outline: 2px dotted green }
* * * { outline: 2px dotted orange }
* * * * { outline: 2px dotted blue }
* * * * * { outline: 1px solid red }
* * * * * * { outline: 1px solid green }
* * * * * * * { outline: 1px solid orange }
* * * * * * * * { outline: 1px solid blue }

4.使一个未设定宽度的DIV居中

对于一个有固定宽度的DIV容器,你可以轻松地通过margin:auto属性令他居中。如果要居中的DIV容器并没有设置宽度的话,你可以使用下面的CSS代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
.content {
 margin: 0 auto 8px;
 display: table;
 }
 
.content div {
 display: table-cell;
 }
 
<!--[if IE]>
.content {
 display: block;
 text-align: center;
 }
.content div {
 display: inline;
 zoom: 1;
}
< ![endif]-->

5.为大图片添加伪AJAX的载入图标

等待图片下载是浏览网页是意见烦人的事,但用JavaScript动态载入图片技术难度又比较大。你可以用CSS加上一个载入图标,缓解访客等待加载时的情绪。

1
img { background: url(loading.gif) no-repeat center center; }

6.CSS图像预载

如果你要在HTML文件加载完成前预载图片,你可以把图片设置为一个DIV容器的背景图,并且把这个容器设为不可见。当HTML加载后再把这个DIV容器插入页面里。

1
2
3
4
5
6
div.loader {
 background:url(images/hover.gif) no-repeat;
 background:url(images/hover2.gif) no-repeat;
 background:url(images/hover3.gif) no-repeat;
 margin-left:-10000px;
}

7.CSS透明度

由于老式浏览器对页面元素透明度处理不好,你必须为透明的元素写hack。

1
2
3
4
5
selector {
 filter: alpha(opacity=60); /* MSIE/PC */
 -moz-opacity: 0.6; /* Mozilla 1.6 and older */
 opacity: 0.6;
}

8.为IE和其它浏览器设置元素的最小高度

由于IE不支持min-height属性,我们还是要为IE写hack。以下代码的第一部分是正确的代码,可以在标准浏览器里使用,第二部分是针对IE的hack。由于IE不能识别min属性,因此height值设定为8em,使容器能装下超出容器范围的文本。

1
2
3
4
5
6
7
8
9
10
11
12
/* for browsers that don't suck */
.container {
 min-height:8em;
 height:auto !important;
}
 
/* for Internet Explorer  */
/*\*/
* html .container {
 height: 8em;
}
/**/

9.根据链接类型选用不同的链接样式

超链接的形式主要有http链接和mailto链接两种,你可以为这两种链接设置不同的样式。通过CSS3,你甚至能为指向不同文件类型的附件链接建立不同的样式!不过,这种做法对不兼容CSS3的浏览器不够友好,而这也是我们必须尽快淘汰老版本IE的原因。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/* HTTP链接的样式 */
a[href^="http://"]
{
padding-right: 13px;
background: url(external.gif) no-repeat center right;
}
 
/* Mailto链接的杨思 */
a[href^="mailto:"]
{
padding-right: 20px;
background: url(email.png) no-repeat center right;
}
 
/* 指向PDF格式附件的样式 */
a[href$=".pdf"]
{
padding-right: 18px;
background: url(acrobat.png) no-repeat center right;
}

10.移除IE里文本输入框的滚动条

 

IE浏览器会画蛇添足地为多行的文本输入框加上一个滚动条,哪怕你输入的文字长度还没有超出输入框的范围。通过下面的代码你可以把多余的滚动条移除。

mysql_fetch_row,mysql_fetch_array,mysql_fetch_assoc的区别

<?php
$link=mysql_connect('localhost','root',”);
mysql_select_db('abc',$link);
$sql = “select * from book”;
$result = mysql_query($sql);
while($row =mysql_fetch_row($result))
{
echo $row['cid'].'::'.$row[1].'<br>';
}
$result = mysql_query($sql);
while($row = mysql_fetch_array($result))
{
echo $row['cid'].'::'.$row[1].'<br>';
}
$result = mysql_query($sql);
while($row = mysql_fetch_object($result))
{
echo $row->cid.'::'.$row->title.”<br>”;
}
$result = mysql_query($sql);
while($row = mysql_fetch_assoc($result))
{
echo $row['cid'].'::'.$row[1].'<br>';
}
?>


分析:
mysql_fetch_row,这个函数是从结果集中取一行作为枚举数据,从和指定的结果标识关联的结果集中取得一行数据并作为数组返回。每个结果的列储存在一个数组的单元中,偏移量从 0 开始。 注意,这里是从0开始偏移,也就是说不能用字段名字来取值,只能用索引来取值,所以如下代码是取不到值的:
while($row = mysql_fetch_row($res)){
echo $row['cid'].'::'.$row[1].”;
} //这里的$row['cid'] 取不到值。
mysql_fetch_array,从结果集中取得一行作为关联数组,或数字数组,或二者兼有,除了将数据以数字索引方式储存在数组中之外,还可以将数据作为关联索引储存,用字段名作为键名。 也就是说他得到的结果像数组一样,可以用key或者索引来取值,所以
while($row = mysql_fetch_array($res)){
echo $row['cid'].'::'.$row[1].”;
}//这里$row['cid'],$row[1]都能得到相应的值。
mysql_fetch_object,顾名思义,从结果集中取得一行作为对象,并将字段名字做为属性。所以只有这样才能取到值
while($row = mysql_fetch_object($res)){
echo $row->cid.'::'.$row->title.”";
}
mysql_fetch_assoc,从结果集中取得一行作为关联数组,也就是说这个函数不能像mysql_fetch_row那样用索引来取值,只能用字段名字来取,所以
while($row = mysql_fetch_assoc($res)){
echo $row['cid'].'::'.$row[1].”;
} //$row[1]这样是取不到值的
补充一点:
mysql_fetch_array函数是这样定义的:array mysql_fetch_array ( resource result [, int result_type]),返回根据从结果集取得的行生成的数组,如果没有更多行则返回 FALSE。
mysql_fetch_array() 中可选的第二个参数 result_type 是一个常量,可以接受以下值:MYSQL_ASSOC,MYSQL_NUM 和 MYSQL_BOTH。其中:
1、mysql_fetch_assoc($result)==mysql_fetch_array($result,MYSQL_ASSOC);
2、mysql_fetch_row($result)==mysql_fetch_array($result,MYSQL_NUM);
所以mysql_fetch_array()函数在某种程度上可以算是mysql_fetch_row()与 mysql_fetch_assoc()的集合。另外,mysql_fetch_array()另外还有MYSQL_BOTH参数,将得到一个同时包含关联和数字索引的数组。
在来说句 $row = $db->fetch_array($query);
$db是人数据库操作类,$db->fetch_array($query),fetch_array($query)是那个db类里的方法,$row = $db->fetch_array($query)这句的意思是从记录集$query中得到数据库中的一行记录。
不用类可这样实现
复制代码 代码如下:

$conn=@mysql_connect($host,$user,$pass);
@mysql_select_db($database,$conn);
$query=mysql_query($sql);
while($row=mysql_fetch_array($query)){
$rows[]=$row;
}

标签: 数组, row, 索引, 一行

关于mysql持久连接(mysql_connect与mysql_pconnect)【很明白】

在某些场合,mysql_pconnect( ) 是不适用的。

——————————————————————————–

状况一:

 使用 1 部 web server 与 1 部 MySQL server(两者可能同在一部主机上),而 web server 固定只对 MySQL server 上的某一个数据库进行存取动作。

 因为每次存取数据库时,都是由 web 那边使用同一账号对 MySQL 上的同一数据库作业,若我们将 MySQL 与 web server 的「同时联机数」都调整为 200,就好像 MySQL 这边一直有 200 位「服务生」,随时等着接待来自 web 的 200 位「顾客」似的。而且「顾客」离开之后,「服务生」也不下场休息,时时都站在门口等着接待下一个「顾客」。

 在这种情况下,您只要注意将 MySQL 的「同时联机数」调得比 web server 的高或相等,就会发现使用 mysql_pconnect( ) 是个不错的选择。
——————————————————————————–

状况二:

 使用 1 部 web server 与 1 部 MySQL server(两者可能同在一部主机上),而 web server 会对 MySQL server 上的两个数据库进行存取动作。

 从 web server 那边提出数据存取需求时,有时是针对第 1 个数据库(DB1),有时则是针对第 2 个数据库(DB2)。若我们也将 MySQL 与 web server 的「同时联机数」都调整为 200,这样一来,就好像 MySQL 这边有 200 位「服务生」,但同时经营两个「吧台」(DB1 与 DB2),而「顾客」可能多达 200 位。

 一开始,DB1 这个「吧台」比较热门,MySQL 派了 150 位「服务生」上场接待;同样地,当「顾客」离开之后,这 150 位「服务生」仍守着 DB1 而不下场休息。后来,DB2 那边也热闹起来了,「顾客」越来越多,MySQL 得加派「服务生」上场,有几个能派?答案是 50 个!

 为什么「服务生」的人力调配会捉襟见肘?那是因为 web 那边使用了 mysql_pconnect( ) 来建立联机。「服务生」一开始被指定到哪个「吧台」工作,就会持续在那边停留,绝不「转台」。
——————————————————————————–

 请注意,当使用持续性的联机时,每个已建立的联机只为来自同一部 web server、使用同一组账号,且存取同一数据库的使用者服务。

 如此一来,假设每部 web server 的「同时联机数」都是 200,而且同时使用 2 部 web server 会怎么样呢?从 web1 来了 50 个「顾客」,先是到 DB1 走一趟,接着再到 DB2 晃一圈,这样需要多少「服务生」接待他们?100 个(web1->DB1: 50 web1->DB2: 50)!又从 web2 来了 50 个「顾客」,也做了同样的动作(web2->DB1: 50 web2->DB2: 50)。在此之后,还有「服务生」是闲着的吗?后续若从 web1 或 web2 同时涌入多于 50 位「顾客」时,谁来应付他们?

 倘若您使用的是像 Apache 这类的 multi-process web server(一个 parent process 协调一组 children processes 运作),某个 children process 建立的「持续联机」,是不能分享给其它 children process 来使用的(「服务生」只对先前接待过的「顾客」服务)。在这样的情况下,将会使得 MySQL 上闲置的 process 越积越多(很多「服务生」站在门口等着「老顾客」上门,而不理会「新顾客」)。
mysql_pconnect( ) 一定是最佳选择吗?我想未必尽然。
——– 两者之间的区别 ————–
mysql_pconnect() 和 mysql_connect() 非常相似,但有两个主要区别。
首先,当连接的时候本函数将先尝试寻找一个在同一个主机上用同样的用户名和密码已经打开的(持久)连接,如果找到,则返回此连接

标识而不打开新连接。
其次,当脚本执行完毕后到 SQL 服务器的连接不会被关闭,此连接将保持打开以备以后使用(mysql_close() 不会关闭由

mysql_pconnect() 建立的连接)。
可选参数 client_flags 自 PHP 4.3.0 版起可用。
此种连接称为”持久的”。
看到这里,写一条代码来测试一下

/*
* pconnect_test.php
*/
$link = mysql_pconnect("localhost", "mysql_user", "mysql_password")
        or die("Could not connect: " . mysql_error());
    print ("Connected successfully");

通过刷新网页的方式执行这条代码,发现每执行一次,mysql的进程数就增加一个。在这里我不禁有了疑问。上面说mysql_pconnect这个函

数的使用的时候,不是说”当连接的时候本函数将先尝试寻找一个在同一个主机上用同样的用户名和密码已经打开的(持久)连接,如果找到

,则返回此标识而不打开新连接”么?为什么我每刷新一次页面他就给我打开一个新的连接呢?

考虑到这有可能是PHP的bug,我到PHP的bug列表中找关于和too many connections 有关的条目。
相关的话题主要有三个,分别是

#11966        mysql_pconnect opens new connections with the same parameters
#26117        Persistent connection not reused
#13589        Persistent connections stay open and accumulate

描述比较长,我就不在这里贴,具体的内容你自己去看。重点主要是”当一个进程打开一个mysql的持续连接,只要该进程还存在,这个持续

的连接就不会断开,而且每一个进程会打开一个mysql的持续连接,而不能使用其他进程打开的持续连接”。