前端經驗
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獲取復選框的值
[html]
- <input type="checkbox" id="loveFruits-apple" name="loveFruits[]" value="apple" />
- <label for="loveFruits-apple">蘋果</label>
<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] view plain copy print?- <?php
- if(isset($_POST[‘loveFruits‘))
- {
- $aLoveFruits = $_POST[‘loveFruits‘];
- for($i=0,$iLen=count($aLoveFruits); $i<$iLen;$i++)
- {
- echo $aLoveFruits[$i];
- }
- }
- }
- ?>
<?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如下,在我最近做的小網站中派上用場了,挺方便。
[php] view plain copy print?- 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;
- }
- }
- 千言萬語匯成一句話,不解釋~
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] view plain copy print?- <?php
- //設置
- $aInput[‘uname‘]="智譯哥";
- $aInput[‘umail‘]="[email protected]";
- CookieUtil::setSubCookie(‘user‘,$aInput,time()+3600*24*30,"/",$yourSite,false,false);
- ?>
<?php //設置 $aInput[‘uname‘]="智譯哥"; $aInput[‘umail‘]="[email protected]"; CookieUtil::setSubCookie(‘user‘,$aInput,time()+3600*24*30,"/",$yourSite,false,false); ?>
[php] view plain copy print?
- <?php
- //獲取
- $aOutput = CookieUtil::getSubCookie(‘user‘);
- echo $aOutput[‘uname‘];
- echo $aOutput[‘umail‘];
- ?>
<?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. 浮動元素的父元素影響浮動效果
一個常見的問題是,如果子元素絕對定位,父元素需要指定為相對定位,否則容易出問題;今天(20120416)我碰到個問題,子元素浮動,在其它瀏覽器下效果良好,但到了IE6下會莫名其妙地多出來空間,而且經過IE DEVELOPER TOOLS 檢查多出來的空間不屬於任何元素。我沒能提取出最少的代碼展現這個問題,此處記下,以後出問題時嘗試設置父元素高度即可,不繼續追究了。經過設置父元素高度,解決了問題。 IE6 下效果:其它瀏覽器效果:
3. checkbox的小正方形周圍多出來空白區域
註意到下圖checkbox小正方形,旁邊多出來一些空白區域。這些空白區域很像設置了padding,但是通過IE developer tools查看,並沒有padding。 其它瀏覽器效果:解決方法是把 小方框的寬度設置為14px,多了不行少了也不行。
JAVASCRIPT
一. 操作DOM
1. 對DOM元素的類型進行增、刪、查操作
由於還是初學階段,不很喜歡用JQUERY,所以還是把這幾個簡單的功能自己實現一下。其中,使用className可以獲得跨瀏覽器兼容性。註意到在className中搜索某個類名時,需要保證匹配的字符串前後的字符不能是除了空格之外的字符。例如要匹配的類名是"a-b",那麽,假如className等於" a-b-c 0-a-b",那麽就會失配。
這段代碼處理能力有限,當sClass包含括號、中括號、花括號等正則式元字符時,可能會出問題,不過,沒幾個人會用這些符號做類名吧,所以不考慮。
代碼如下:
[javascript] view plain copy print?- 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);
- }
- };
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. 瀏覽器兼容性
1)IE 只支持事件冒泡流,事件從源元素開始向元素的父元素傳播,直至HTML元素,最後是document節點;FF等還支持事件捕獲流,與冒泡流傳播順序相反。 2)DOM事件流包括三個階段,事件捕獲階段、處於目標階段、事件冒泡階段。根據《javascipt高級程序設計》的講解,我的理解是,從當事件傳播到源元素的瞬間,到事件處理程序開始執行的瞬間,這個階段是處於目標階段。而整個事件處理程序執行的過程歸屬於事件冒泡階段。 3)IE不支持DOM事件流,其它OK。 4)onblur 和 onfocus不支持事件冒泡 轉自:https://blog.csdn.net/yaozhiyi/article/details/7437925前端經驗