1. 页面乱码:
浏览器默认的是utf8,所以正常输出汉字应该是可以显示的。为了以防意外,在<head>标签内加上下列语句:
<meta http-equiv=”Content-Type” content=”text/html; charset=utf-8”>
2. 数据库读写
在插入数据或者读出数据之前,在连接语句后,选择数据库语句之前加上如下语句:
mysql_query(“set names ‘utf8’”);
CODE:
<?php
$con = mysql_connect("localhost", "root", "");
if (!$con) {
die("数据库连接失败!" . "<br />") ;
}
mysql_query("set names 'utf8'");
mysql_select_db("study_php", $con);
$sql = "insert into student values('$_POST[num]', '$_POST[name]', '$_POST[sex]', $_POST[age])";
$result = mysql_query($sql); // 注意:mysql_query不需要加$con这个参数!!!
if ($result) {
echo "成功插入1条记录!";
} else {
echo "插入失败!";
}
mysql_close($con);
?>
读取数据时候也一样:
CODE:
<?php
$con = mysql_connect("localhost", "root", "");
if (!$con) {
die("数据库连接失败!" . "<br />");
}
mysql_query("set names 'utf8'");
mysql_select_db("study_php", $con);
$resultSet = mysql_query("select * from student");
while ($row = mysql_fetch_array($resultSet)) {
echo "Name: " . $row['name'] . " Sex: " . $row['sex'] . "<br />";
}
mysql_close($con);
?>
3. Warning: mysql_fetch_array() expects parameter 1 to be resource, boolean given in xxx…
$row = mysql_fetch_array($result);
报此错的原因是:result值为空。就是说,如果上面的查询出错,导致result无值,那么此处mysql_fetch_arrah($result)自然就会被认为没有加参数。所以正确的做法是在执行该语句之前加一句判断:
if ($result) {
$row = mysql_fetch_array($result);
}
4. Parse error: syntax error, unexpected T_VARIABLE, expecting T_FUNCTION in xxxx….
如果在定义class的时候,一个属性没有加修饰符(public, private, protected)则会报此错,但是方法可以不用加修饰符。
5. Warning: mail() [function.mail]: "sendmail_from" not set in php.ini or custom "From:" header missing in…
6. Warning: mail() [function.mail]: Failed to connect to mailserver at "localhost" port 25, verify your "SMTP" and "smtp_port" setting in php.ini or use ini_set() in…
7. 全局变量在声明的时候不能被赋值
以下语句是错误的:
global $dl_myplugin = new MyPlugin();
应该改为:
global $dl_myplugin;
$dl_myplugin = new MyPlugin();
8. $_SERVER[“REQUEST_URI”]的作用
REQUEST_URI是访问本页面的连接(当前地址栏内的地址)。所以这一整句的作用相当于”#”
CODE:
<div /> <form method='post' action="#">
<h2>MyPlugin</h2>
<h3>Content to Add to the End of a Post</h3>
…
效果等同于:
<div /> <form method='post' action="<?php echo $_SERVER[“REQUEST_URI”];?>">
<h2>MyPlugin</h2>
<h3>Content to Add to the End of a Post</h3>
…
9. utf8, utf-8, UTF-8
UTF-8是标准写法,最为保险的一种写法;
utf8被mysql使用
其余情况可以用utf-8
10. PHP页面编码用header和meta的区别
1) 使用 <META http-equiv="content-type" content="text/html; charset=xxx"> 标签设置页面编码
这个标签的作用是声明客户端的浏览器用什么字符集编码显示该页面,xxx可以为GB2312,GBK,UTF-8(和MySQL不同,MySQL是 UTF8)等等。因此,大部分页面可以采用这种方式来告诉浏览器显示这个页面的时候采用什么编码,这样才不会造成编码错误而产生乱码。但是有的时候我们会发现有了这句还是不行,不管xxx是哪一种,浏览器采用的始终都是一种编码,这个情况我后面会谈到。
请注意,<meta>是属于html信息的,仅仅是一个声明,它起作用表明服务器已经把HTML信息传到了浏览器。
2) header("content-type:text/html; charset=xxx");
这个函数header()的作用是把括号里面的信息发到http标头。
如果括号里面的内容为文中所说那样,那作用和<META>标签基本相同,大家对照第一个看发现字符都差不多的。但是不同的是如果有这段函数,浏览器就会永远采用你所要求的xxx编码,绝对不会不听话,因此这个函数是很有用的。为什么会这样呢?那就得说说HTTPS标头和HTML信息的差别了:
https标头是服务器以HTTP协议传送HTML信息到浏览器前所送出的字串。
因为meta标签是属于html信息的,所以header()发送的内容先到达浏览器,通俗点就是header()的优先级高于meta(不知道可不可以这样讲)。加入一个php页面既有header("content-type:text/html; charset=xxx"),又有<META http-equiv="content-type" content="text/html; charset=xxx">,浏览器就只认前者http标头而不认meta了。当然这个函数只能在php页面内使用。
同样也留有一个问题,为什么前者就绝对起作用,而后者有时候就不行呢?这就是接下来要谈的Apache的原因了。
3) AddDefaultCharset
Apache 根目录的 conf 文件夹里,有整个Apache的配置文档httpd.conf。
用文本编辑器打开httpd.conf,第708行(不同版本可能不同)有AddDefaultCharset xxx,xxx为编码名称。这行代码的意思:设置整个服务器内的网页文件https标头里的字符集为你默认的xxx字符集。有这行,就相当于给每个文件都加了一行header("content-type:text/html; charset=xxx")。这下就明白为什么明明meta设置了是utf-8,可浏览器始终采用gb2312的原因。
如果网页里有header("content-type:text/html; charset=xxx"),就把默认的字符集改为你设置的字符集,所以这个函数永远有用。如果把AddDefaultCharset xxx前面加个“#”,注释掉这句,而且页面里不含header("content-type…"),那这个时候就轮到meta标签起作用了。
总结:
来个排序
header("content-type:text/html; charset=xxx")
AddDefaultCharset xxx
<META http-equiv="content-type" content="text/html; charset=xxx">
如果你是web程序员,给你的每个页面都加个header("content-type:text/html; charset=xxx"),保证它在任何服务器都能正确显示,可移植性强。
至于那句AddDefaultCharset xxx,要不要注释就仁者见仁了。反正我是注释掉了,不过我写页子也要写header(),便于放到服务器上能正常显示。
11. Invalid argument supplied for foreach()
CODE:
function getMemberInfo() {
$tmpInfo = mysql_query("select * from xy_member where member_name = '" .
$_POST['user_name'] . "'");
if ($tmpInfo) {
foreach($tmpInfo as $key => $value) {
if ($key != 'member_ID') {
$memberInfo[$key] = $value;
}
}
return $memberInfo;
} else {
echo '数据库无此人信息!' . '<br />';
return NULL;
}
}
问题出在php不能判断$tmpInfo是否为数组,可以修改代码如下:
CODE:
function getMemberInfo() {
$tmpInfo = mysql_query("select * from xy_member where member_name = '" .
$_POST['user_name'] . "'");
if ($tmpInfo) {
foreach((array)$tmpInfo as $key => $value) {
if ($key != 'member_ID') {
$memberInfo[$key] = $value;
}
}
return $memberInfo;
} else {
echo '数据库无此人信息!' . '<br />';
return NULL;
}
}
或者:
CODE:
function getMemberInfo() {
$tmpInfo = mysql_query("select * from xy_member where member_name = '" .
$_POST['user_name'] . "'");
if (is_array($tmpInfo)) {
foreach($tmpInfo as $key => $value) {
if ($key != 'member_ID') {
$memberInfo[$key] = $value;
}
}
return $memberInfo;
} else {
echo '数据库无此人信息!' . '<br />';
return NULL;
}
}
12. 利用JavaScript过滤空格
CODE:
<script>
// 去左右空格
function Trim(str) {
return str.replace(/\s+$|^\s+/g,"");
}
// 去左空格
function LTrim(str) {
return str.replace(/^\s+/,"");
}
// 去右空格
function RTrim(str) {
return str.replace(/\s+$/,"");
}
String.prototype.Trim=Trim;
String.prototype.RTrim=RTrim;
String.prototype.LTrim=LTrim;
</script>
Example.
<script>
var form = document.forms[0];
form.elements[0].value.Trim() ;
</script>
13. mysql_query
mysql_query()仅对SELECT, SHOW, EXPLAIN或DESCRIBE语句返回一个资源标识符,如果查询执行不正确则返回FALSE。对于其他类型语句MYSQL_QUERY()在执行成功时返回TRUE,出错时返回FALSE。费FALSE的返回值意味着查询语句是合法的并能够被服务器执行,这并不能说明任何有关影响到或返回的行数。很有可能一条查询执行成功了但并未影响到或并未返回任何行。如果没有权限访问查询语句中的引用表式,mysql_query()也会返回FALSE。
查看记录是否存在的方法(假定查询成功):
mysql_num_rows()来查看对应于SELECT语句返回的行数;
mysql_affected_rows()查看对应于DELETE, INSERT, REPLACE或UPDATE语句;
14. 在PHP中实现页面跳转的三种方法
PHP(仅此一种)
Header("Location: http://www.dreamdu.com/xhtml/");
JavaScript
echo "<script>window.location=\"http://www.dreamdu.com/xhtml/\";</script>";
HTML的meta的refresh
echo "<meta http-equiv=\"refresh\" content=\"0; url=http://www.dreamdu.com/\" />";
15. Location对象(JavaScript)中href,reload,replace的区别
Location对象包含有关当前URL的信息。Location是Window对象的一个部分,可通过window.location属性来访问。
1)href是Location对象的属性,而reload和replace是方法。所以在使用的时候应该用如下方式:
window.location.href=””;
window.location.reload(””);
window.location.replace(””);
2)href是设置或返回完整的URL
reload重新加载当前文档
replace用新的文档替换当前文本
3)
Location 对象描述
Location 对象存储在 Window 对象的 Location 属性中,表示那个窗口中当前显示的文档的 Web 地址。它的 href 属性存放的是文档的完整 URL,其他属性则分别描述了 URL 的各个部分。这些属性与 Anchor 对象(或 Area 对象)的 URL 属性非常相似。当一个 Location 对象被转换成字符串,href 属性的值被返回。这意味着你可以使用表达式 location 来替代 location.href。
不过 Anchor 对象表示的是文档中的超链接,Location 对象表示的却是浏览器当前显示的文档的 URL(或位置)。但是 Location 对象所能做的远远不止这些,它还能控制浏览器显示的文档的位置。如果把一个含有 URL 的字符串赋予 Location 对象或它的 href 属性,浏览器就会把新的 URL 所指的文档装载进来,并显示出来。
除了设置 location 或 location.href 用完整的 URL 替换当前的 URL 之外,还可以修改部分 URL,只需要给 Location 对象的其他属性赋值即可。这样做就会创建新的 URL,其中的一部分与原来的 URL 不同,浏览器会将它装载并显示出来。例如,假设设置了Location对象的 hash 属性,那么浏览器就会转移到当前文档中的一个指定的位置。同样,如果设置了 search 属性,那么浏览器就会重新装载附加了新的查询字符串的 URL。
除了 URL 属性外,Location 对象的 reload() 方法可以重新装载当前文档,replace() 可以装载一个新文档而无须为它创建一个新的历史记录,也就是说,在浏览器的历史列表中,新文档将替换当前文档。
16. 使用span来显示文本
CODE:
<body>
将要显示的文本:<br />
<span id="txt"></span>
<br /><br />
<script>
function check() {
document.getElementById("txt").innerHTML="O(∩_∩)O哈哈哈~";
}
</script>
<input type="button" value="提交"/>
</body>
注意:
1)span的id与getElementById中的一致!
2)<span>元素一定要放在js执行之前,因为如果放在js后面,js将找不到id。(类比其他的表单元素亦是如此)
3)如果想要向JS中传输字符串,则可以使用下列代码:
CODE:
<form action="<?php echo $_SERVER['REQUEST_URI']; ?>" method="post" name="form1">
<h3>在下面填写要添加成员的邮箱,<font color="red">用逗号分隔</font></h3>
<textarea name="addMemContent" style="width:50%; height:100px;">
</textarea>
<br />
<span id="txtHint"></span>
<br/>
<div /> <input type="button" onclick="check(document.form1.addMemContent.value)" value="检查用户是否已存在"/>
<input type="submit" name="addMember" value="添加"/>
</div>
</form>
在js中,代码如下:
CODE:
function check(str) {
document.getElementById("txtHint").innerHTML=str;
}
这样就可以把表单中的任何一个元素的值传入js函数进行处理了!
17. 注意mysql_query的返回
使用select语句,默认返回的是二维数组(即使你的select语句可能只返回一条记录),必须转化成一维来显示:
CODE:
$result = mysql_query("select * from xy_member where member_name = '". $_POST['user_name'] . "'");
if (mysql_num_rows($result)) { // 该用户存在
$row = mysql_fetch_array($result); // 必须得有这一句来将二维数组转化
echo "member_name: " . $row['member_name'] . " member_pwd: " . $row['member_pwd'];
if ($_POST['user_pwd'] == $row['member_pwd']) { // 登陆成功
echo "<script>window.location.replace('member_info.php');</script>"; // 跳转
} else { // 密码错误
echo "<script>document.getElementById('user_pwd_error').innerHTML='Wrong Password';</script>"; // 提示错误
}
} else { //非法用户
echo "<script>document.getElementById('user_name_error').innerHTML='User does not exist!';</script>";
}
if (mysql_num_rows($result)) { // 该用户存在
$row = mysql_fetch_array($result);
if ($_POST['user_pwd'] == $row['member_pwd']) { // 登陆成功
$_SESSION['user_name'] = $_POST['user_name']; // 注册用户
echo "<script>window.location.replace('member_info.php');</script>";
} else { // 密码错误
echo "<script>document.getElementById('user_pwd_error').innerHTML='Wrong Password';</script>";
}
} else { //非法用户
echo "<script>document.getElementById('user_name_error').innerHTML='User does not exist!';</script>";
}
18. 防止用户使用get方式提交表单
$user_name = $_POST['user_name'];
if (!isset($user_name)) { // 防止用户使用get方式提交
echo "<script>window.location.replace('login.php')</script>";
}
注:下面表格中的“默认”意思是不加GET和POST验证,Y表示可以跳转,N表示不能跳转
|
默认 |
GET |
POST |
默认 |
Y |
N |
N |
GET |
Y |
Y |
N |
POST |
Y |
N |
Y |
还有一种终极方法,类似JSP中验证用户是否登录的方法:session。见19.
19. $_SESSION
$_SESSION的特点是:从建立开始到用户离开网站——一次会话。
Session的机制是为每个访问者创建一个唯一的id(UID),并给予这个UID来存储变量。UID存储在cookie中,亦通过URL进行传导。
在将信息存到PHP Session中之前,必须启动会话:session_start(),该函数必须位于<html>标签之前!
CODE:
<?phpsession_start();// store session data$_SESSION['views']=1;?><html><body><?php//retrieve session dataecho "Pageviews=". $_SESSION['views'];?></body></html>
删除session中的某些数据,可以使用unset()或session_destroy()函数。unset()函数用于释放指定的session变量:
unset($_SESSION['views']);
也可以通过session_destroy()函数彻底终结session:
session_destroy();
此函数将重置session,这将会失去所有已经存储的session数据。
20. 终结烦人的PHP页面乱码问题
1)可以通过修改Apache配置文件来解决,修改默认的字符编码;
2)第一种方法对于XAMPP1.7.3或更高版本可能不可用,可以通过修改页面的编码方式;
3)如果上述方法均不可用,则可使用UE打开php文件,然后另存为"UTF-8 无 BOM"的格式即可(注意若有汉字,提前复制,因为转码后汉字均变乱码,需要重写汉字)。一定要保存成无BOM格式,否则普通的UTF-8格式会自动在开头加上<feff>字符(在Linux下打开看,在win下看不到)。这样如果在开始有<?php session_start() ?>的话将提示下列警告:
这是由于<?php session_start() />必须放在开头!!
4)如果是用Eclipse开发,则可以直接修改Eclipse的编码格式:
工作空间范围:
Window->Preferences->General->Workspace->Text file encoding->Other->UTF-8
项目范围:
Project->Properties->Resource->Text file encoding->Other->UTF-8
21. PHP邮件
STMP:每个邮箱都有STMP地址。这个地址可以在申请邮箱时的说明中找到,也可以在邮箱的设置中找到。以下是常用邮箱的STMP:
邮箱 |
Smtp |
Port |
帮助 |
163 |
smtp.163.com |
25 |
点击 |
126 |
smtp.126.com |
|
点击 |
QQ |
smtp.qq.com |
|
点击 |
Gmail |
smtp.gmail.com |
465 |
点击 |
下载后的包中不仅有class.phpmailer.php,而且还有文档,示例,其中有使用Gmail作为邮件服务器发送邮件的例子,经过我的修改,如下:
CODE:
<?php
// example on using PHPMailer with GMAIL
date_default_timezone_set('UTC');
include("class.phpmailer.php");
include("class.smtp.php"); // note, this is optional - gets called from main class if not already loaded
$mail = new PHPMailer();
$mail->IsSMTP();
$mail->SMTPAuth = true; // enable SMTP authentication
$mail->SMTPSecure = "ssl"; // sets the prefix to the servier
$mail->Host = "smtp.gmail.com"; // sets GMAIL as the SMTP server
$mail->Port = 465; // set the SMTP port
$mail->Username = "Johnson.wei.056@gmail.com"; // GMAIL username
$mail->Password = "Qiuhunduwu&056"; // GMAIL password
$mail->From = "johnson.wei.056@gmail.com";
$mail->FromName = "Johnson";
$mail->Subject = "邮件测试";
$mail->AltBody = "看到这则消息后,说明您的浏览器不支持HTML浏览,请使用支持HTML的Email浏览!"; //Text Body
$mail->WordWrap = 50; // set word wrap
$mail->Body = '<B>这是通过$mail->Body设置的</B>';
$mail->AddReplyTo("Johnson.wei.056@gmail.com","魏江龙"); // Reply address
$mail->AddAddress("ybmmwjl@163.com","独舞秋魂"); // Address of the receiver
$mail->IsHTML(true); // send as HTML
$mail->CharSet = "UTF-8"; // 一定要设置编码,否则邮件发送过去很能出现乱码
if(!$mail->Send()) {
echo "Mailer Error: " . $mail->ErrorInfo;
} else {
echo "Message has been sent";
}
?>
22. 5行代码实现checkbox全选/全不选
(部分摘自:http://blog.csdn.net/lkhdmail/archive/2008/12/16/3530060.aspx)
CODE:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title>无标题文档</title>
<style type="text/css">
p {margin:0;font-size:12px;line-height:26px;}
</style>
<script type="text/javascript">
function check_all(obj,cName)
{
var checkboxs = document.getElementsByName(cName);
for(var i=0;i<checkboxs.length;i++){checkboxs[i].checked = obj.checked;}
}
</script>
</head>
<body>
<p><input type="checkbox" name="all" />全选/全不选</p>
<p><input type="checkbox" name="c" value="" /></p>
<p><input type="checkbox" name="c" value="" /></p>
<p><input type="checkbox" name="c" value="" /></p>
<p><input type="checkbox" name="c" value="" /></p>
</body>
</html>
23. 异常:Catchable fatal error: Object of class Cart could not be converted to string in XXX
由於最近在協助客戶將所有 PHP4 的網站全部升級至 PHP5,轉移的過程中遇到了一個 PHP Catchable fatal error 的錯誤訊息,訊息如下:
PHP Catchable fatal error: Object of class Cart could not be converted to string in C:\Inetpub\wwwroot\libs\functions.inc.php on line 118
我先開啟該檔案的 118 行查看出了什麼問題,但查不出任何異狀,只好開始往回 Stack Trace,查到了錯誤發生的地方:
<?php echo $val; ?>
而至於 $val 是我從資料庫的資料取出之後,透過 unserialize 過的物件,由於我有些欄位的值是儲存成物件序列化(Serialize)的結果 ( e.g. 購物車資訊 ),等要用時再直接反序列化來用。
由於之前的程式沒寫好,遇到這類程式也是直接輸出物件,但當時 PHP4 又沒有實做 __toString() 方法,所以導致當要將 object 轉換成 string 時才會發生這個嚴重錯誤(fatal error)。這個不相容的問題是發生在 PHP 5.2 之後的版本,詳細的資訊可參考 Backward Incompatible Changes 說明。
若要解決這個問題也很簡單,由於序列化(Serialize)所儲存的是「當時物件的資訊」,並不包含「類別」的定義,所以原本在資料庫中的資料並沒有異動的需要,只要你將原本物件定義的地方加上 __toString() 方法即可。例如:
function __toString(){ return "";}