PHP与数据库
1. 判断连接是否成功
$mysqli = new mysqli($DBHOST,$DBUSER,$DBPASS,$DBNAME);
if($mysqli->connect_error)//返回字符串则表示有错误,否则返回NULL
2. 判断查询是否成功mysqli_query返回值
出错代码:
$dbc = mysqli_connect($DBHOST,$DBUSER,$DBPWD,$DBNAME);
$q = "select * from user where u_name='yao'";
$a = mysqli_query($dbc,$q);
if(mysqli_num_rows($a) == 1){..}
报错代码:
if(mysqli_num_rows($a) == 1){..}
报错内容:Warning: mysqli_num_rows() expects parameter 1 to be mysqli_result, boolean given in/usr/local/work/apache/htdocs/fo/php/checkForm.php on line10
报错原因:
mysqli_query查询失败时返回FALSE;如果查询成功,那么,对于SELECT/SHOW/DESCRIBE/EXPLAIN查询,会返回一个mysqli_result对象。而对于其它正确的查询,会返回TRUE。
解决办法:
对mysqli_query的返回值进行检查,确保不是布尔值FALSE才能作为mysqli_num_rows的参数
if($a && mysqli_num_row($a) == 1)
或者
if($result = mysqli_query($dbc,$query))
{
$n = mysqli_num_rows($result);
}
参考链接:
php手册 http://cn.php.net/manual/en/mysqli.query.php
PHP与表单
一. 表单变量的HTML书写格式
复选框的name设置比较特殊,为了方便使用PHP获取复选框的值
<input type="checkbox" id="loveFruits-apple" name="loveFruits[]" value="apple" />
<label for="loveFruits-apple">苹果</label>
<input type="checkbox" id="loveFruits-pear" name="loveFruits[]" value="pear" />
<label for="loveFruits-pear">梨</label>
二. 获取表单变量值
提交表单之后,如果需要获取checkbox的值,务必先用isset检测,这和别的表单元素不一样
假如用户没有勾选checkbox中的任一项,那么如果不检测而直接访问$_POST['loveFruits']则PHP报错
Notice: Undefined index loveFruits
<?php
if(isset($_POST['loveFruits'))
{
$aLoveFruits = $_POST['loveFruits'];
for($i=0,$iLen=count($aLoveFruits); $i<$iLen;$i++)
{
echo $aLoveFruits[$i];
}
}
}
?>
编码
一. PHP的header()函数与HTML<meta>标签
HTTP响应格式
HTTP 响应包含四部分,一是Status Line,二是Header部分,三是Body部分,其中,二三部分由空行隔开。
Body部分是完整的文档,例如:
<!DOCTYPE html PUBLIC ...>
<html xmlns="" xml:lang="en">
<head><meta http-equiv="Content-Type" content="text/html;charset=utf-8" ></head>
<body>for test</body>
</html>
Status Line指出协议版本、响应编码和状态,例如:
HTTP/1.1 200 ok
Header部分提供关于缓存、编码、服务器信息等各种信息,例如:
Cache-Control:public
Content-Type:text/html;charset=gb2312
Expires:
Last-Modified:
注意到Header部分和Body部分都可能存在Content-Type,其中指定的编码指出该使用什么样的解码方式来解读发送给浏览器的文档。不过,浏览器会优先采用Header部分指定的Content-Type。
设置HTTP响应的Header部分的Content-Type,有多种方式。按优先级由高到低,一是在PHP文档(例如index.php)中使用header()函数;二是在php配置文件中指定default_mimetype和default_charset;三是在APACHE的配置文件httpd.conf中使用指令AddDefaultCharset 。这几种方式都会导致通过<meta>标签指定的字符编码被忽略,header()指出的编码优先级比httpd.conf中配置的编码高。尽量不要使用AddDefaultCharset,否则<meta>标签指定编码的方法就失效了;对于PHP程序,使用header()函数指出编码是好习惯,有比较好的移植性。
二. 文件本身的编码
老工程师倾向于统一字符编码为UTF-8,即,文件的编码为UTF-8,发送给浏览器的文件中,指明编码为UTF-8(通过<meta>或php的header()函数等),然后就省却各种转换。(通过<meta>和<header>等)
尤其是,AJAX默认接收的是UTF-8字符,如果在文件中给AJAX传递GB2312的参数,那就悲剧了,乱码无法避免。
为了使得在UBUNTU下创建的文件默认都是UTF-8编码的,我设置了LC_CTYPE="zh_CN.UTF-8"
方法是在 /etc/environment文件里添加 LC_CTYPE="zh_CN.UTF-8"。zh表示中文(拼音"zhongwen"),CN表示中国大陆(英语CHINA)。关于字符集,先说说UNICODE,UNICODE这个字符集使用四字节表示一个符号,但存储效率低;UTF-8和UNICODE类似,针对一些符号,使用比较少的字节进行编码。
设置之后,则若touch null.php;使用vi null.php并输入冒号及 set fileencoding可以查看文件的编码,比较奇怪的是,使用file --mime-encoding查看一个文件的字符集是无效的。在我的系统中,使用file命令查看一个含有中文字符的文件的字符集,结果将是iso-8859-1(此字符集不支持中文);而vi下使用set fileencoding能正确地显示UTF-8。
为了将以往的非UTF-8文件进行转码为UTF-8,我使用ICONV
对于使用其它编码的文件,可以使用iconv来转化成UTF-8格式。格式是,iconv -f 'gb2312' -t 'utf-8' file -o newfile 。
使secureCRT 和 putty 程序用UTF-8解析文件
secureCRT: 会话选项-->外观-->字符编码-->UTF-8
putty : 点左上角图标出现下拉列表--->点change settings-->点translation-->修改编码为UTF-8
使用SCREEN程序,在secureCRT 和putty下无法显示UTF-8的问题,修改.screenrc文件
去掉一下三行的注释
defutf8 on
defencoding utf-8
encoding utf-8 utf-8
但是,如果某个screen使用过程中断网,之后使用 -r 选项恢复这个screen,那么,此时,依旧无法显示UTF-8编码。目前还没有研究解决方法。
SESSION 与 COOKIE
一. 各自的特点
1. COOKIE 在浏览器端和服务器端都能获取到;SESSION只能在服务器端访问。
二. 实践
1. JAVASCRIPT 子COOKIE
《javascript高级程序设计》提到了“子COOKIE”的概念,大致的意思是为了在一条COOKIE中尽可能多保存信息。使用以下形式设置COOKIE:
name=name1=value1&name2=value2&name3=value3
在JAVASCRIPT中设置子COOKIE的技巧是,对该字符串中的name和value进行URL编码,而对等号(=)和与号(&)不编码。获取子cookie的技巧是,先用&后用=进行字符串分割,然后再解码。这样即使name1等或者value1等中包含等号(=)或与号(&)都能不失真地设置和获取子COOKIE。
2. PHP 子COOKIE
笔者在实践过程中,也曾想用PHP实现这种不失真的子COOKIE。不过在有限的时间内没有找到好的办法,由于使用PHP的setcookie函数设置COOKIE值会自动进行URL编码,所以这明显不符合我的需求。于是采用setrawcookie() 函数。并且,默认name1/value1之类的不包含等号(=)和与号(&)。
我用PHP封装的子COOKIE如下,在我最近做的小网站中派上用场了,挺方便。
class CookieUtil
{
//name value expire path domain secure httponly
//把名值对都存入数组中,作为参数传入
public static function setSubCookie($sName,$aPairs,$iExpire=0,$sPath='/',$sDomain="",$bSecure=false,$bHttpOnly=false)
{
$sCookieText = "";
$bFirst = true;
if($aPairs)
{
//遍历数组进行编码,等号和&符号不编码
foreach($aPairs as $key=>$value)
{
// echo $key.$value;
if(strlen($key) > 0)
{
if(!$bFirst)
{
$sCookieText .= "&";
}
$sCookieText .= urlencode($key)."=".urlencode($value);
$bFirst = false;
}
}
// echo $sCookieText;
}
return setrawcookie(urlencode($sName),$sCookieText,$iExpire,$sPath,$sDomain,$bSecure,$bHttpOnly);
}
public static function getSubCookie($sName)
{
$aPairs = array();
if(isset($_COOKIE[urlencode($sName)]))
{
$sCookieText = $_COOKIE[urlencode($sName)];
$aKeyVals = explode('&',$sCookieText);
foreach($aKeyVals as $value)
{
$aKeyAndVal = explode('=',$value);
// var_dump($aKeyAndVal);
$aPairs[$aKeyAndVal[0]] = $aKeyAndVal[1];
}
}
// var_dump($aPairs);
return $aPairs;
}
}
千言万语汇成一句话,不解释~
使用方法大致是:
<?php
//设置
$aInput['uname']="智译哥";
$aInput['umail']="xxxx@qq.com";
CookieUtil::setSubCookie('user',$aInput,time()+3600*24*30,"/",$yourSite,false,false);
?>
<?php
//获取
$aOutput = CookieUtil::getSubCookie('user');
echo $aOutput['uname'];
echo $aOutput['umail'];
?>
3. 意外
苦于差劲的网络状况,不得不使用XAMPP来本地建站调试,期间使用我心爱的CookieUtil::setSubCookie时,发现在FF和Chrome下无法设置COOKIE,其它如FF和OPERA没问题。在诸多调试之后,KB的我才意识到也许是LOCALHOST的问题,我调用setSubCookie时传入的域名参数是localhost,这不是一个有效的域名,IE和OPERA都不支持,放到线上就OK了。
这个折腾让时间已不多的我心痛不已。
HTML/CSS
一. IE6 BUG
1. IE6 重复字符BUG
在《精通CSS 高级WEB标准解决方案》第二版第9章,作者提到了这个BUG,此BUG可以描述为,当多个浮动元素之间包含注释时,最后一个浮动元素的内容的最后几个字符可能会重复出现。今天(20120416)我也遇到这个问题了,很庆幸书上讲到过这个BUG。不过,我遇到的这个具体的重复字符BUG不是由注释引起,而是由设置为display:none;的元素引起。
注意到两个input之间夹着一个label。我把 label 设置为 display:block;float:left; 把 input 设置为 display:none; 于是在IE6下发生了字符重复("名登陆")。
<label for="way-umail">邮箱登陆</label>
<input id="way-umail" name="way" class="umail" type="radio" checked="checked" />
<label for="way-uname" class="label-uname">用户名登陆</label>
<input id="way-uname" name="way" class="uname" type="radio" />
最后,我把夹在两个Input之间的label取出放到别处,问题解决。
2. 浮动元素的父元素影响浮动效果
其它浏览器效果:
3. checkbox的小正方形周围多出来空白区域
解决方法是把 小方框的宽度设置为14px,多了不行少了也不行。
JAVASCRIPT
一. 操作DOM
1. 对DOM元素的类型进行增、删、查操作
由于还是初学阶段,不很喜欢用JQUERY,所以还是把这几个简单的功能自己实现一下。其中,使用className可以获得跨浏览器兼容性。注意到在className中搜索某个类名时,需要保证匹配的字符串前后的字符不能是除了空格之外的字符。例如要匹配的类名是"a-b",那么,假如className等于" a-b-c 0-a-b",那么就会失配。
这段代码处理能力有限,当sClass包含括号、中括号、花括号等正则式元字符时,可能会出问题,不过,没几个人会用这些符号做类名吧,所以不考虑。
代码如下:
ClassManager = {
isClass:function(oElement,sClass)
{
var oRe = new RegExp("(^| +)"+sClass+"( +|$)","");
if(oRe.test(oElement.className)){
return true;
}else{
return false;
}
},
addClass:function(oElement,sClass)
{
if(!this.isClass(oElement,sClass)){
oElement.className += " "+sClass;
}
//alert("after add" + oElement.className);
},
delClass:function(oElement,sClass)
{
var oRe = new RegExp("(^| +)"+sClass+"( +|$)","");
if(this.isClass(oElement,sClass)){
oElement.className = oElement.className.replace(oRe," ");
}
//alert("after del" + oElement.className);
}
};
二. 事件
1. 浏览器兼容性