《Head First PHP & MySQL》学习总结
第1章 为静态页面赋予生命
1 通过引入PHP,web服务器能够动态地生成HTML web页面
2 表单使用HTML<form>标签创建,每个<form>标签都有一个action属性,不论为action属性设置什么文件名,表单提交时Web服务器都会用设置的这个文件来处理表单。如
<form method="post" action="report.php"> </form>
3 php变量可以直接写在双引号字符串中
$msg = "$name was abducted $when_it_happened and was gone for $how_long.\n".
"Number of aliens: $how_many\n".
"Alien description: $alien_description\n".
"What they did: $what_they_did\n".
"Fang spotted: $fang_spotted\n".
"Other comments: $other";
4 php是一种编程语言,需要一个允许它允许的环境。
5 <?php ...... ?> 为php代码区
6 php的一些规则
- 每个php语句都必须以一个分号( ; )结束,如 echo "hello " ;
- 如果web页面有php代码,一个好的想法是将web服务器上的文件扩展名命名为.php而不是.html
- php变量总是以一个美元符号( $ ) 开头,如 $email
- php变量美元符号后第一个字符可以是一个字母或下划线( _ )。变量名只能由字母,数字或下划线组成
7 php的字符串可以用双引号或单引号引起
8 $_POST是一个特殊的变量,称为超级全局变量。是php内置。直接绑定到HTML表单使用的表单post提交方法
9 echo命令用于将字符串作为html内容输出到浏览器上
10 点号( . ) 用于将字符串和变量链接在一起
11 换行符(\n)只能在双引号串中转义,才会生效。单引号字符串被认为是原始文本,而php处理双引号串时会寻找变量。在一个双引号中遇到变量时,php会在串中插入该变量的值。
$t = 123;
echo "hello , $t \n"; // 输出 hello , 123 ,并另起一行
echo 'hello , $t\n'; // 输出hello , $t\n
第2章 连接MySQL
1 操作MySQL的三个函数
[code]// mysqli_connect()连接数据库 $dbc = mysqli_connect("127.0.0.1","root","root","aliendatabase") or die("Error connecting to MySQL server."); $query = "INSERT INTO aliens_abduction (first_name, last_name, when_it_happened, how_long, " . "how_many, alien_description, what_they_did, fang_spotted, other, email) " . "VALUES ('$first_name', '$last_name', '$when_it_happened', '$how_long', '$how_many', " . "'$alien_description', '$what_they_did', '$fang_spotted', '$other', '$email')"; //操作查询语句 $result = mysqli_query($dbc,$query) or die("Error querying database."); //断开与数据库的连接 mysqli_close($dbc);
2 用mysqli_connect( host,username,password,dbname,port,socket) 建立连接,参数都是可选项
$dbc = mysqli_connect(
"127.0.0.1", // 数据库所在的位置
"yang", // 数据库的帐号
"123456", // 密码
"aliendatabase" ) ; // 数据库名
3 也可以使用mysqli_select_db( ) 选择数据库
$dbc = mysqli_connect("localhost" , "root" , "root") or die("Error"); // 如果失败会直接调用die()
mysqli_select_db($dbc , "aliendatabase"); // 此处选择数据库
4 使用mysqli_query(database_connection , query) 函数操作MySQL数据库。
$result = mysqli_query($dbc , $query) or die("Error querying database");
5 用mysqli_close(database_connection) 关闭连接,用完MySQL数据库连接进行关闭是个好习惯。
6 数据库服务器同时只允许有一定数目的可用连接,所以要尽可能地节省。关闭一个连接会释放掉这个连接。
第3章 创建与填充数据库
1 如果知道某个字段最多有n个字符,使用varchar比char要好。char比varchar效率高,它不必维护可变长度。如果明确的 知道字段的固定长度更适合用char。
2 查询结果,用mysqli_fetch_array()获取查询结果,调用一次读一行
$query = "SELECT * FROM elvis_database" ;
$result = mysqli_query($dbc , $query) ;
while( $row = mysqli_fetch_array($result)){ // $row是一个数组
echo $row['first_name']." ".$row["last_name"]." ".$row["email"];
}
第4章 现实的实际应用
1 isset()判断一个变量是否存在,empty()函数判断变量是否包含一个空值。当一个变量已被赋值,isset()返回true。当一个变量设置为0,空串,false或NULL时empty()返回true。
2 isset()无法显示出空表单域与已填充表单域之间有何区别。
3 php中,与操作符(&&)和或操作符(||)都是短路操作符
4 php嵌套html代码
[code]<?php $t = 1; if($t == 1){ ?> <h>hello</h> <?php } else { ?> <h>ok</h> <?php } ?>
5 将表单动作指向脚本,脚本URL可以用$_SERVER["PHP_SELF"],如下
<form action="<?php echo $_SERVER['PHP_SELF'];?>" method="post"> . . . </form>
6 如果表单form定义了提交控件<input type="submit" name="submit">,则可以用isset($_POST["submit"])判断是否已经点击过提交
[code]<form action = "<?php echo $_SERVER['PHP_SELF'];?>" method="post"> <input type="submit" name="submit" value="ok"> </form> <?php if(isset($_POST['submit'])) echo "submit"; else echo "none"; ?>
7 MySQL插入字段
mysql> alter table email_list ADD id int not null auto_increment FIRST , add primary key(id); ### FIRST表示插入到第一列
8 复选框的name属性带方括号([ ])会自动将复选框值放入该name值的数组中,如下
<input type="checkbox" value="1" name="school[ ]">
9 php可以利用foreach循环处理数组,如下
foreach($colors as $color) {
echo $color ;
}
第5章 使用存储在文件中的数据
1 MySQL的alter语句
- alter table xxtable add column age tinyint // 新增一列
- alter table xxtable drop column age // 删除一列
- alter table xxtable change column score high_score int // 修改列,列名改为high_score,类型改为int
- alter table xxtable modify column date datetime after age // 修改列的数据类型或位置
2 表单上传文件
[code]<form enctype="multipart/form-data" method="post" action="<?php echo $_SERVER['PHP_SELF'];?>"> <input type="hidden" name="MAX_FILE_SIZE" value="32768"/> <label for="name">Name:</label><input type="text" id="name" name="name" value="<?php if(!empty($name)) echo $name;?>"/><br /> <label for="score">Score:</label><input type="text" id="score" name="score" value="<?php if(!empty($score)) echo $score;?>"/><br /> <label for="screenshot">Screen shot:</label> <input type="file" id="screenshot" name="screenshot"/> <hr /> <input type="submit" name="submit" value="Add"/> </form> echo $_FILES['screenshot']['name'].": ".$_FILES['screenshot']['type'].": ".$_FILES['screenshot']['size'].": ".$_FILES['screenshot']['tmp_name'].": ".$_FILES['screenshot']['error']; if(is_file($row['screenshot']) && filesize($row['screenshot'])>0)
- <form enctype="multipart/form-data" ... > 中的enctype属性告诉表单要使用文件上传所需的一种特殊类型编码
- <input type="file" ... > type属性表示文件
- 表单上传的文件要用 $_FILES这个PHP内置的超级全局变量,而不是$_POST。$_FILES['screenshot']['name']为文件名,$_FILES['screenshot']['type']为文件的MIME类型,$_FILES['screenshot']['size']为文件大小,$_FILES['screenshot']['tmp_name']为文件在服务器上的临时存储位置,$_FILES['screenshot']['error']为上传结果,0表示成功
- is_file() 判断是否为文件,filesize()获取文件大小
- <input type="hidden" name="MAX_FILE_SIZE" value="32768"/> 这样的设置可以限制form上传的文件大小只能为32k
3 php函数move_uploaded_file()接受一个文件的源位置和目标位置,然后负责完成文件移动。如下
[code]define('GW_UPLOADPATH','images/'); $screenshot = $_FILES['screenshot']['name']; $target = GW_UPLOADPATH.$screenshot; move_uploaded_file($_FILES['screenshot']['tmp_name'], $target); // 将文件从临时存储位置移动到目标位置
4 define()定义常量,如下
define( 'DW' , 123) ; // 定义常量DW的值为123
5 共享脚本数据
1) 在脚本appvars.php先定义变量
[code]<?php define('GW_UPLOADPATH','images/'); ?>2) 在其他的文件用require_once()来包含这个脚本,这个文件就可以使用这个变量
[code]<?php require_once('appvars.php'); ?>
6 require_once()和include()的区别在于如果未找到包含文件,require_once()会产生一个错误,而include()不会显示任何错误。require_once也保证文件不会被包含多次。php还有include_once()和require()。
7 MySQL的结果排序
[code]select * from guitarwars order by score asc; select * from guitarwars order by score desc,date asc;
8 unlink()函数用于删除一个文件,如下所示,符号@为了避免文件删除失败报错
[code]@unlink($_FILES['screenshot']['tmp_name'];
9 POST请求只能从表单发出,而GET请求可以打包成URL
第6章 保证应用安全
1 http认证提供了一种使用PHP保护页面的简单方法,$_SERVER['PHP_AUTH_USER']保存了用户名,$_SERVER['PHP_AUTH_PW']保存了密码。
2 HTTP认证的基本思想是,服务器会“扣留”一个受保护的web页面,然后要求浏览器向用户询问一个用户名和口令。浏览器和服务器之间是通过首部完成,首部是一个短小的文本消息,包含所请求或传送的特定指令。首部如下
3 浏览器键入一个URL或点击Web页面一个链接时,浏览器会组装一个GET请求,并发送到服务器。这个请求会打包成一系列的首部,每个首部包含有关请求的一些信息。
4 利用php控制首部,header()函数允许从php脚本创建和发送首部,header()函数会立即从服务器向浏览器发送一个首部,而且这个函数必须在向浏览器发送任何具体内容之前调用。header()函数调用应当放在php脚本的所有html代码之前。如下所示
[code]<?php header("Content-Type:text/html"); ?>
注:在首部之前即使发送一个空格或字符浏览器都会拒绝。使用即使是<?php标记前面多一个随意的空格都会导致这个脚本失效。
5 首部可以做很多事
- 位置首部,重定向到其他页面。
[code]<?php // 重定向到百度 header('Location:http://www.baidu.com'); ?>
- 刷新首部,设置时间刷新页面
[code]<?php // 5秒后刷新页面,到百度 header("Refresh:5;url=http://www.baidu.com"); echo "In 5 seconds you'll be taken to baidu"; ?>
- 内容首部,控制由服务器传送的内容类型
[code]<?php // 浏览器会根据text/plain只作为文本显示 header('Content-Type:text/plain'); echo "This <strong>text</strong> won't actually be bold"; ?>
6 http的认证,会自动有弹窗提示要求输入用户名和密码
[code]<?php $username = 'rock'; $password = 'roll'; if(!isset($_SERVER['PHP_AUTH_USER'])||!isset($_SERVER['PHP_AUTH_PW'])||($_SERVER['PHP_AUTH_USER']!=$username||$_SERVER['PHP_AUTH_PW']!=$password)){ header('HTTP/1.1401 Unauthorized'); header('WWW-Authenticate:Basic realm="Guitar Wars"'); exit('<h2>Guitar Wars</h2>Sorry, you must enter a valid user name and password to access this page.'); } ?>
7 保护数据避免SQL注入
- 可以采用trim()去掉字符串前面和后面多余的空格
- 内置函数mysqli_real_escape_string( )将有危险的字符进行转义。
[code]$score = "1000','1v1.jpg',1);"; $score = mysqli_real_escape_string($dbc,trim($score)); //$score 变成"1000\',\'1v1.jpg\',1);"
- MySQL里某些字段可以声明为默认值,不需要insert该字段值
- 表单验证安全后再插入数据
第7章 构建个性化Web应用
1 MySQL有个SHA()的函数,SHA(Secure Hash Algorithm )会对文本串应用一个加密算法,结果是一个唯一加密串,长度固定为40个十六进制字符,如下
insert into mismatch_user(username , password , join_date) values( 'Yang' , SHA('123456') , NOW())
注:SHA()函数提供的是单向加密,即无法对已经加密的数据解密。
2 MySQL提供了另一个与SHA()类似的函数,名为MD5(),一般认为SHA()会更安全些。
3 可以使用mysqli_num_rows()函数查看搜索结果个数
[code]$dbc = mysqli_connect(DB_HOST,DB_USER,DB_PASSWORD,DB_NAME) or die("Fail to connect"); $user_name = mysqli_real_escape_string($dbc,trim($_SERVER["PHP_AUTH_USER"])); $user_password = mysqli_real_escape_string($dbc,trim($_SERVER["PHP_AUTH_PW"])); $query = "select user_id,username from mismatch_user where username='$user_name' and password=sha('$user_password')"; $data = mysqli_query($dbc,$query); if(mysqli_num_rows($data) == 1){ $row = mysqli_fetch_array($data); $user_id = $row['user_id']; $username = $row['username']; }
注:sql语句如果是字符串变量记得一定要在包围在引号里,不如sql语句执行时会异常
4 HTTP认证只有在浏览器关闭时才会重置,或人工手动清除。
5 PHP通过一个名为setcookie()函数和一个$_COOKIE的超级全局变量提供对cookie的访问。如下
[code]// 将"sidneyk"存在名为username的cookie中 setcookie("username","sidneyk"); // 通过$_COOKIE['username']取到"sidneyk"值 $username = $_COOKIE['username'];
6 setcookie()还接受可选的第三个参数,即设置cookie的到期日期。到了这个日期时cookie会自动删除。如果没有指定日期,cookie会在浏览器关闭时自动到期。
[code]<?php require_once('connectvars.php'); $error_msg = ""; if(!isset($_COOKIE['user_id'])){ if(isset($_POST['submit'])){ $dbc = mysqli_connect(DB_HOST,DB_USER,DB_PASSWORD,DB_NAME) or die("Fail to connect"); $user_name = mysqli_real_escape_string($dbc,trim($_POST['username'])); $user_password = mysqli_real_escape_string($dbc,trim($_POST['password'])); if(!empty($user_name) && !empty($user_password)){ $query = "select user_id,username from mismatch_user where username='$user_name' and password=sha('$user_password')"; error_log($query); $data = mysqli_query($dbc,$query); error_log(mysqli_num_rows($data)); if(mysqli_num_rows($data) == 1){ $row = mysqli_fetch_array($data); setcookie("user_id",$row['user_id']); setcookie("username",$row['username']); $home_url = "http://".$_SERVER['HTTP_HOST'].dirname($_SERVER['PHP_SELF'])."/index.php"; header("Location: ".$home_url); }else{ $error_msg = "Sorry, you must enter a valid username and password to log in."; } }else{ $error_msg = "Sorry, you must enter your username and password to log in."; } } } ?> <html> <head> <title>Mismatch - Log In</title> <link rel="stylesheet" type="text/css" href="style.css"/> </head> <body> <h3>Mismatch - Log In</h3> <?php if(empty($_COOKIE["user_id"])){ echo "<p class='error'>$error_msg</p>"; ?> <form method="post" action="<?php echo $_SERVER['PHP_SELF'];?>"> <fieldset> <legend>Log In</legend> <label for="username">Username: </label> <input type="text" id="username" name="username" value="<?php if(!empty($user_name)) echo $user_name;?>"/><br /> <label for="password">Password: </label> <input type="password" id="password" name="password"/> </fieldset> <input type="submit" name="submit" value="Log In"/> </form> <?php }else{ echo "<p class='login'>You are logged in as ".$_COOKIE['username'].".</p>"; } ?> </body> </html>
7 删除cookie要通过调用setcookie()设置过期的时间,如下
[code]setcookie("username","sidneyk",time()-3600);
8 会话允许将小段数据持久地存储在服务器上,而不依赖于客户端。它比cookie更安全和可靠。但不同于cookie,会话无法对一个会话变量将数据存储多久做太多控制。会话一结束就会自动销毁会话变量。关闭浏览器,会话也会结束。
会话有非常明确的开始和结束。session_start()函数开始一个会话,并允许在会话变量中存储数据。session_start()不会设置任何数据,而只是建立会话并开始运行。会话在内部由一个唯一的会话标识符标识。一旦会话开始,就可以用超级变量$_SESSION来设置会话变量。浏览器关闭或调用session_destroy()时会话会结束。
[code]session_start(); // 开始会话 $_SESSION['username'] = 'sidneyk'; // 设置会话变量 $username = $_SESSION['username'] ; // 获取会话变量 session_destroy(); // 结束会话
注:session_destroy()只是结束会话,但不会销毁会话变量。所以一般在结束之前要手动删除会话变量。有一个快捷方法即把$_SESSION设置为空数组,$_SESSION = array()。
9 会话在后台实际上会使用cookie,如果浏览器支持cookie,会话可能会设置一个cookie临时存储会话ID。PHP还必须删除可能在浏览器上自动创建来存储会话ID的所有cookie。如下
[code]if(isset($_COOKIE[session_name()])){ setcookie(session_name(),"",time()-3600); }
10 使用会话完成注销的必要步骤
- 删除会话变量,$_SESSION = array()
- 查看会话cookie是否存在,存在则将其删除 if(isset($_COOKIE[session_name()]))
- 销毁会话 session_destroy()
- 将用户重定向到主页 header()
11 不同的地方调用session_start(),即session_start()多次被调用,但不会创建多个会话,还是只有一个会话。
12 cookie的生命期并不与浏览器实例绑定,即使关闭浏览器,cookie也不会消失。cookie可以永存,至少在它的到期日期来到之前。会话session可以比cookie存储更大的数据。
13 为了避免代码重复,将重复的代码可以独立出来做一个文件,如下
- header.php 页眉
- navmenu.php 导航菜单
- startsession.php 会话启动脚本
- footer.php 页脚
第8章 收获数据
1 外键(foreign key)将一个表中的一行链接到另一个表中的一行。一个表中的外键引用另一个表的主键,从而建立这两个表间的一个联系用于查询。
2 php支持三元操作符( ? : ) , condition ? A : B
第9章 通过函数改善生活
1 默认情况下MySQL的where子句是不区分大小写
2 在SQL中,百分号(%)可以代表0或多个字符,下划线(_)表示一个字符,如下
select * from xxx like '_ _ _ hello' ; // 表示匹配xxxhello
3 explode()可以将一个字符串拆分为多个单独的子字串数组,如下
$search_words = explode( ' ' , 'Tipper Cow') ; // 第一个参数是定界符,即根据什么拆分,可以是一个字符或多个字符。
4 implode()可以将多个子字符串组合成一个字符串,如下
$where_clause = implode(' or ' , $where_list) ; // 第一个参数是定界符,即子字符串间加入该参数组合
5 str_replace()替换字符串或单个字符,如下
$clean_search = str_replace("thousands" , "hundreds" , "Make thousands of dollars your very first month"); // 在第三个参数里找出第一个参数的字符串,用第二个字符串替换
注:explode()和implode(),str_replace()都是准确使用定界符,如定界符为一个空格,源字符串的连续三个空格会被当成三个定界符,如下
$user_search = "bull matador cape";
$search_words = explode(" ",$user_search);
var_dump($search_words);[code]输出: array(5) { [0]=> string(4) "bull" [1]=> string(7) "matador" [2]=> string(0) "" [3]=> string(0) "" [4]=> string(4) "cape" }
6 数组增加
$user_search = "bull matador cape ok";
$search_words = explode(" ",$user_search);
$temp = array();
foreach($search_words as $word){
$temp[] = $word; // 可以不用填写数组下标
}
7 substr( string , start , length) 截取字符串的一部分,第一个参数string是源字符串,第二个参数是截取起点,第三个参数是截取的长度,这个是可选参数。
$job_desc = "Are you a practioner of the lost art of cat juggling?";
echo substr($job_desc,4,3) ; // 输出 you
echo substr($job_desc,49) ; // 输出ing?
echo substr($job_desc,-53,7) ; // 输出 Are you
echo substr($job_desc,-9) ; // 输出juggling?
8 定义函数,使用关键词function
[code]function replace_commas($str){ $new_str = str_replace(',',' ',$str); return $new_str; }
第10章 正则表达式
1
阅读更多
- Head First PHP&MySQL 学习笔记(二) —— 创建和填充数据库
- Head First PHP&MySQL 学习笔记(三,四) —— 现实的实际应用
- Head First PHP &MySQL学习笔记
- Head First PHP&MySQL学习笔记(四)
- Head First PHP&MySQL学习笔记(六)
- Head First PHP&MySQL 学习笔记(一)
- Head First PHP&MySQL学习笔记(三)
- Head first PHP&MySQL 学习笔记(一)
- Head First PHP&MySQL学习笔记(一)
- Head First PHP &MySQL学习笔记
- Head First PHP&MySQL 学习笔记(二) —— Connect MySQL
- Head First PHP&MySQL学习笔记(五)
- Head First PHP&MySQL学习笔记(二)
- HeadFirst PHP&MySQL 重点知识点记录(一)
- [head first php&mysql]读书笔记-客户的反馈(第四章)
- Head First Python学习总结
- [Head.First.PHP.&.MySQL]pdf
- Head First PHP & MySQL
- head first PHP$MySQL 笔记
- [head first php&mysql]读书笔记-基本的安全信息(第五章)