php综合web开发(2)

来源:互联网 发布:能看回放的网络电视 编辑:程序博客网 时间:2024/06/15 23:02
本博客介绍了进行php综合web开发需要的技术与方法。

mysql数据库详解

安装了XAMPP后可以从C:\xampp\mysql\bin访问可执行的mysql,为了进入mysql的命令行接口,需选择start->run,并在run框中输入cmd进入命令行:
mysql -u root//登陆
show database;//显示当前所有数据库
mysql有6种不同的提示:
Mysql>mysql准备好等待命令
->等待下一行命令
‘>等待下一行以单引号开始的字符串
“>等待下一行以双引号开始的字符串
`>等待下一行以反引号开始的字符串
/>等待下一行以/开始的字符串
ctrl-c关闭程序
\c并回车忽略输入的一切
常用的mysql命令:
ALTER修改数据库或表
BACKUP备份表
CREATE创建数据库或表
DELETE删除行
DESCRIBE说明表的列
DROP删除库或表
EXIT(CTRL-C)退出
GRANT修改用户权限
HELP(\h,\?)帮助信息
INSERT插入数据
LOCK锁柱表
QUIT(\q)退出
RENAME重命名表
SHOW列出项目说明
SOURCE从文件名执行命令
STATUS(\s)显示当前状态
TRUNCATE清空表
UNLOCK解锁表
UPDATE更新数据
USE打开数据库

CREATE DATABASE database_name;USE database_name;GRANT PRIVILEGES ON database.object TO 'username' @'hostname' IDENTIFIED BY 'password';
对于database.object:如果是*.*,则表示所有数据库及其对象,database.*仅为调用了database的数据库及其所有对象,database.object为调用了database的数据库及其调用了object对象的对象。如:
GRANT ALL ON database_name.* TO 'jim@localhost' IDENTIFIED BY 'password';

创建表:

CREATE TABLE classics(    author VARCHAR(128),    title VARCHAR(128),    type VARCHAR(16),    year CHAR(4)) ENGINE MyISAM;

可输入DESCRIBE classics查看新表是否已被创建
碎玉INT数值类型指定数值参数表明的是这些数据被检索时在字段中的显示宽度,可与ZEROFILL一起使用来补零。

CREATE TABLE tablename(fieldname INT(4) ZEROFILL);

mysql还支持与时间、日期相关的数据类型:
DATETIME,DATE,TIMESTAMP,TIME,YEAR
TIMESTAMP很有用,可以让mysql自动设置值,修改时可让mysql更新TIMESTAMP列
AUTO_INCREMENT数据类型可以让当前行自动加一,
ALTER TABLE classics ADD id INT UNSIGNED NOT NULL AUTO_INCREMENT KEY;
删除id列:
ALTER TABLE classics DROP id;
向表中添加数据:
INSERT INTO classics (author ,title,type,year) VALUES(‘mark’,’Adventure’,’Fiction’,’1811’);
查看表信息:
SELECT * FROM classics;
重命名表:
ALTER TABLE classics RANAME pre1900;
改变表中的数据类型:
ALTER TABLE classics MODIFY year SMALLINT;
添加新列:
ALTER TABLE classics ADD pages SMALLINT UNSIGNED;
重命名列:
ALTER TABLE classics CHANGE type category VARCHAR(16);
删除列:
ALTER TABLE classics DROP pages;
DESCRIBE table_name;查看表的信息

创建索引:
ALTER TABLE classics ADD INDEX(author(20));//20限制了索引只能为前20个字符
也可以使用CREATE INDEX创建索引——
CREATE INDEX author ON classics (author(20));
可在创建表时添加索引——

CREATE TABLE table_name(author VARCHAR(20),title VARCHAR(128),INDEX(author(10)))ENGINE MyISAM;

使用主键:
ALTER TABLE classics ADD isbn CHAR(13) PRIMARY KAY;
为表中的列增加索引:
ALTER TABLE classics ADD PRIMARY KAY(isbn);

Mysql的FULLTEXT索引允许快速检索文本中的所有列,在每个数据字符串中存储作为专用索引的单词,以实现用”自然语言“进行检索,类似方式使用搜索引擎。
FULLTEXT索引只用于MyISAM表,是MySQL默认的存储引擎使用的类型,将表转换为MyISAM可使用:
ALTER TABLE tablename ENGINE=MyISAM;
FULLTEXT索引只适用于CHAR,VARCHAR,TEXT列
在创建表时,可通过CREATE TABLE 定义FULLTEXT索引,或之后使用ALTER TABLE/CREATE INDEX加入
对于一个大型数据集,将数据加载到一个没有FULLTEXT索引的表中后再创建索引,要比将数据加载到一个已经有全文索引的表中快得多。
ALTER TABLE classics ADD FULLTEXT(author,title);

MySQL数据库查询:
SELECT something FROM tablename;
SELECT author,title FROM classics;
SELECT COUNT(*) FROM classics;
DISTINCT关键字可以清除重复的数据
SELECT DISTINCT author FROM classics;
删除一行:
DELETE FROM classics WHERE title=’dong’;

WHERE:可使用LIKE限定词为检索做模式匹配,允许搜索部分字符串,%代表任意字符串,并可匹配空字符串,LIMIT限定词用来限定选择在一次查询中返回的行数,以及从表的什么位置开始返回,当传入一个参数时,通知MySQL从结果的头部开始,并返回参数指定的行数,传入两个参数则第一个表示从开始显示点算起的偏移量,第二个表示返回的数量,
SELECT author,title FROM classics LIMIT 3;//返回前3行
SELECT author,title FROM classics LIMIT 1,2;//跳过第一行,返回之后两行
MATCH…AGAINST:
用于FULLTEXT索引的列,可使用自然语言进行搜索,允许在一个查询中输入多个单词,并对FULLTEXT列中的所有单词进行核对,不区分大小写。
SELECT author ,title FROM classics WHERE MATCH(author,title)AGAINST(‘word1 word2’);//要求word1与word2都在文本中
布尔模式下的MATCH…AGAINST(不要求所有搜索词都在列中):
SELECT author ,title FROM classics WHERE MATCH(author,title)AGAINST(‘+word1 -word2’)IN BOOLEAN MODE);//必须有word1,不能有word2
SELECT author ,title FROM classics WHERE MATCH(author,title)AGAINST(‘”wor wor”’)IN BOOLEAN MODE);//精确检索短语

UPDATE …SET:
更新字段
UPDATE classics SET author=’name’ WHERE author=’oldname’;

ORDER BY:
通过一个或多个列按升序或降序形式将返回结果进行排序,SELECT author,title FROM classics ORDER BY author,title [DESC];//使用DESC为降序,且只是用于title,可在author后加ASC,结果不变

GROUP BY:
SELECT category,COUNT(author)FROM classics GROUP BY category;

插入多行数据可以用:
INSERT INTO name (name1,name2)VALUES
(‘1’,’2’),(‘3’,’4’);

连接表:
SELECT name FROM table1,table2 WHERE table1.isbn=table2.isbn;

使用NATURAL JOIN将两个有相同列名的表自动合并:
SELECT name FROM table1 NATURAL JOIN table2;

如果要指定一个列将两个表连接在一起,使用JOIN… ON结构,
SELECT name,author FROM table1 JOIN table2 ON
table1.isbn=table2.isbn;

可以使用AS创建别名,
SELECT name FROM table1 AS tabletemp tabel2 AS tablea WHERE tabletemp.isbn=table1.isbn;

WHERE查询中可以使用逻辑运算符AND,OR,NOT

数据库建立原则

为了设置主键,很多情况下使用AUTO_INCREMENT创建任意键。
将数据分开置于表中与创建主键的过程被称为规范化,目的是确保每条信息在数据库中出现一次
第一范式:
不能有包含相同类型数据的重复列出现;
所有列都是单值的;
有一个主键唯一标识每一行
第二范式:
第一范式处理多列间的重复数据,第二范式处理多行间的冗余。为了达到第二范式,必须已经是第一范式。
第三范式:
要求数据不直接依赖于主键,但根据相关性,要将依赖于表中其他值的数据移到其他单独表中。

一般而言,一对一联系可置于一个表中,一对多联系分为两个表,多对多联系使用中间表。

为了使用mysql的事务功能,必须使用InnoDB引擎,在mysql中事务以BEGIN或START TRANSACTION开始:

BEGIN;UPDATE accounts SET balance =balance+25.11 WHERE number=12345;COMMIT;

使用COMMIT:
COMMIT将所有的更改提交给数据库,收到COMMIT之前,mysql认为所做的任何更改是暂时的,这个功能提供了撤销事务的机会,不发送COMMIT而是ROLLBACK便可撤回。

使用EXPLAIN可以得到任何查询快照来确定是否能以更好的方式查询:

EXPLAIN SELECT * FROM acconts WHERE number='12345';

备份与恢复:
使用mysqldump命令,将数据库或数据库集合转储到一个或多个文件,文件中包含所有重新创建表的指令与重新填充的数据,也可以生成CSV文件与其他带分割符的文本格式,甚至是XML格式,主要缺点是必须确保在备份时没有人向表中写入任何数据,可以在执行mysqldump前关闭mysql服务器,完成后重启,或者在执行命令前锁定要备份的表,为了将表锁定为只读,可使用:

LOCK TABLES tablename1 READ,tablename2 READ;

执行完命令后释放锁:
UNLOCK TABLES;
默认情况下mysqldump的输出是屏幕,可使用重定向>在文件中进行捕捉

mysqldump的基本命令格式是:
mysqldump -u user -p password database;

创建备份文件:
mysqldump -u user -p password database > file.sql;
备份一个独立表:

LOCK TABLES database.table READ;mysqldump -u user -p password database table>table.sql;UNLOCK TABLES;

备份所有表:

mysql -u user -p password --all -databases>all_databases.sql;

恢复数据库集:
mysql -u user -p password < all_databases.sql;
恢复数据库:

mysql -u user -p password -D database<database.sql;

恢复一张表到一个数据库中:

mysql -u user -p password -D database<table.sql;

用CSV格式转储数据:

mysqldump -u user -p password --no-create-info --tab=c:/temp --fields-terminated-by=',' database;

使用PHP访问mysql

使用php访问mysql的步骤是:
连接mysql,选择数据库;
创建查询字符串;
执行查询语句;
检索出结果并在网页上显示;
断开连接

创建登陆文件login.php:

<?php$db_hostname='localhost';$db_database='db_name';$db_username='username';$db_password='password';?>

连接数据库:

<?phprequire_once 'login.php';$conn=new mysqli($hn,$un,$pw,$db);if($conn->connect_error)die($conn->connect_error);//友好的显示信息函数function mysql_fatal_error($msg){$msg2=mysql_error();echo <<<ENDWe are sorry,but it was not possible to complete the requested task.The error message we got was:<p>$msg:$msg2</p>Please click the back button on your browser and try again.If you are still having problems,please <a href="mailto :admin@server.com">email our administrator</a>.Thanks.END;}?>

创建执行查询:

$query="SELECT * FROM table";$result=$conn->query($query);if(!$result)die($conn->error);

获取结果:

<?php // query.php  require_once 'login.php';  $conn = new mysqli($hn, $un, $pw, $db);  if ($conn->connect_error) die($conn->connect_error);  $query  = "SELECT * FROM classics";  $result = $conn->query($query);  if (!$result) die($conn->error);  $rows = $result->num_rows;  for ($j = 0 ; $j < $rows ; ++$j)  {    $result->data_seek($j);    echo 'Author: '   . $result->fetch_assoc()['author']   . '<br>';    $result->data_seek($j);    echo 'Title: '    . $result->fetch_assoc()['title']    . '<br>';    $result->data_seek($j);    echo 'Category: ' . $result->fetch_assoc()['category'] . '<br>';    $result->data_seek($j);    echo 'Year: '     . $result->fetch_assoc()['year']     . '<br>';    $result->data_seek($j);    echo 'ISBN: '     . $result->fetch_assoc()['isbn']     . '<br><br>';  }  $result->close();  $conn->close();?>

获取一行数据:

<?php //fetchrow.php  require_once 'login.php';  $conn = new mysqli($hn, $un, $pw, $db);  if ($conn->connect_error) die($conn->connect_error);  $query  = "SELECT * FROM classics";  $result = $conn->query($query);  if (!$result) die($conn->error);  $rows = $result->num_rows;  for ($j = 0 ; $j < $rows ; ++$j)  {    $result->data_seek($j);    $row = $result->fetch_array(MYSQLI_ASSOC);    echo 'Author: '   . $row['author']   . '<br>';    echo 'Title: '    . $row['title']    . '<br>';    echo 'Category: ' . $row['category'] . '<br>';    echo 'Year: '     . $row['year']     . '<br>';    echo 'ISBN: '     . $row['isbn']     . '<br><br>';  }  $result->close();  $conn->close();?>

插入删除:

<?php // sqltest.php  require_once 'login.php';  $conn = new mysqli($hn, $un, $pw, $db);  if ($conn->connect_error) die($conn->connect_error);  if (isset($_POST['delete']) && isset($_POST['isbn']))  {    $isbn   = get_post($conn, 'isbn');    $query  = "DELETE FROM classics WHERE isbn='$isbn'";    $result = $conn->query($query);    if (!$result) echo "DELETE failed: $query<br>" .      $conn->error . "<br><br>";  }  if (isset($_POST['author'])   &&      isset($_POST['title'])    &&      isset($_POST['category']) &&      isset($_POST['year'])     &&      isset($_POST['isbn']))  {    $author   = get_post($conn, 'author');    $title    = get_post($conn, 'title');    $category = get_post($conn, 'category');    $year     = get_post($conn, 'year');    $isbn     = get_post($conn, 'isbn');    $query    = "INSERT INTO classics VALUES" .      "('$author', '$title', '$category', '$year', '$isbn')";    $result   = $conn->query($query);    if (!$result) echo "INSERT failed: $query<br>" .      $conn->error . "<br><br>";  }  echo <<<_END  <form action="sqltest.php" method="post"><pre>    Author <input type="text" name="author">     Title <input type="text" name="title">  Category <input type="text" name="category">      Year <input type="text" name="year">      ISBN <input type="text" name="isbn">           <input type="submit" value="ADD RECORD">  </pre></form>_END;  $query  = "SELECT * FROM classics";  $result = $conn->query($query);  if (!$result) die ("Database access failed: " . $conn->error);  $rows = $result->num_rows;  for ($j = 0 ; $j < $rows ; ++$j)  {    $result->data_seek($j);    $row = $result->fetch_array(MYSQLI_NUM);    echo <<<_END  <pre>    Author $row[0]     Title $row[1]  Category $row[2]      Year $row[3]      ISBN $row[4]  </pre>  <form action="sqltest.php" method="post">  <input type="hidden" name="delete" value="yes">  <input type="hidden" name="isbn" value="$row[4]">  <input type="submit" value="DELETE RECORD"></form>_END;  }  $result->close();  $conn->close();  function get_post($conn, $var)  {    return $conn->real_escape_string($_POST[$var]);  }?>

创建表:

<?php  require_once 'login.php';  $conn = new mysqli($hn, $un, $pw, $db);  if ($conn->connect_error) die($conn->connect_error);  $query = "CREATE TABLE cats (    id SMALLINT NOT NULL AUTO_INCREMENT,    family VARCHAR(32) NOT NULL,    name VARCHAR(32) NOT NULL,    age TINYINT NOT NULL,    PRIMARY KEY (id)  )";  $result = $conn->query($query);  if (!$result) die ("Database access failed: " . $conn->error);?>

描述表:

<?php  require_once 'login.php';  $conn = new mysqli($hn, $un, $pw, $db);  if ($conn->connect_error) die($conn->connect_error);  $query  = "DESCRIBE cats";  $result = $conn->query($query);  if (!$result) die ("Database access failed: " . $conn->error);  $rows = $result->num_rows;  echo "<table><tr><th>Column</th><th>Type</th><th>Null</th><th>Key</th></tr>";  for ($j = 0 ; $j < $rows ; ++$j)  {    $result->data_seek($j);    $row = $result->fetch_array(MYSQLI_NUM);    echo "<tr>";    for ($k = 0 ; $k < 4 ; ++$k) echo "<td>$row[$k]</td>";    echo "</tr>";  }  echo "</table>";?>

删除表:

<?php  require_once 'login.php';  $conn = new mysqli($hn, $un, $pw, $db);  if ($conn->connect_error) die($conn->connect_error);  $query  = "DROP TABLE cats";  $result = $conn->query($query);  if (!$result) die ("Database access failed: " . $conn->error);?>

添加数据:

<?php  require_once 'login.php';  $conn = new mysqli($hn, $un, $pw, $db);  if ($conn->connect_error) die($conn->connect_error);  $query  = "INSERT INTO cats VALUES(NULL, 'Lion', 'Leo', 4)";  $result = $conn->query($query);  if (!$result) die ("Database access failed: " . $conn->error);?>

检索数据:

<?php  require_once 'login.php';  $conn = new mysqli($hn, $un, $pw, $db);  if ($conn->connect_error) die($conn->connect_error);  $query  = "SELECT * FROM cats";  $result = $conn->query($query);  if (!$result) die ("Database access failed: " . $conn->error);  $rows = $result->num_rows;  echo "<table><tr> <th>Id</th> <th>Family</th><th>Name</th><th>Age</th></tr>";  for ($j = 0 ; $j < $rows ; ++$j)  {    $result->data_seek($j);    $row = $result->fetch_array(MYSQLI_NUM);    echo "<tr>";    for ($k = 0 ; $k < 4 ; ++$k) echo "<td>$row[$k]</td>";    echo "</tr>";  }  echo "</table>";?>

更新数据:

<?php  require_once 'login.php';  $conn = new mysqli($hn, $un, $pw, $db);  if ($conn->connect_error) die($conn->connect_error);  $query  = "UPDATE cats SET name='Charlie' WHERE name='Charly'";  $result = $conn->query($query);  if (!$result) die ("Database access failed: " . $conn->error);?>

删除数据:

<?php  require_once 'login.php';  $conn = new mysqli($hn, $un, $pw, $db);  if ($conn->connect_error) die($conn->connect_error);  $query  = "DELETE FROM cats WHERE name='Growler'";  $result = $conn->query($query);  if (!$result) die ("Database access failed: " . $conn->error);?>

使用AUTO_INCREMENT:

<?php  require_once 'login.php';  $conn = new mysqli($hn, $un, $pw, $db);  if ($conn->connect_error) die($conn->connect_error);  $query  = "INSERT INTO cats VALUES(NULL, 'Lynx', 'Stumpy', 5)";  $result = $conn->query($query);  if (!$result) die ("Database access failed: " . $conn->error);  echo "The Insert ID was: " . $conn->insert_id;?>

要通过运用插入的ID实现表间的完全连接就要使用锁,具体步骤:
将第一个表格锁起来;
向第一个表格插入数据;
查询第一个表格中唯一的id;
解锁第一个表格;
向第二个表格插入数据

执行附加查询:

<?php  require_once 'login.php';  $conn = new mysqli($hn, $un, $pw, $db);  if ($conn->connect_error) die($conn->connect_error);  $query  = "SELECT * FROM customers";  $result = $conn->query($query);  if (!$result) die ("Database access failed: " . $conn->error);  $rows = $result->num_rows;  for ($j = 0 ; $j < $rows ; ++$j)  {    $result->data_seek($j);    $row = $result->fetch_array(MYSQLI_NUM);    echo "$row[0] purchased ISBN $row[1]:<br>";    $subquery  = "SELECT * FROM classics WHERE isbn='$row[1]'";    $subresult = $conn->query($subquery);    if (!$subresult) die ("Database access failed: " . $conn->error);    $subrow = $subresult->fetch_array(MYSQLI_NUM);    echo "  '$subrow[1]' by $subrow[0]<br>";  }?>

也可使用NATURAL JOIN 查询得到相同结果:
SELECT name,isbn,title,author FROM customers NATURAL JOIN classics;

防止黑客攻击:

$user=$_POST['user'];$pass=$_POST['pass'];$query="SELECT * FROM users WHERE user='$user' AND pass='$pass'";

黑客可以用$user=admin’#获取admin权限,原因是#代表一段解释的开始。

我们应该使用real_escape_string方法调用mysql,如对字符串进行净化:

<?php  function mysql_fix_string($conn, $string)  {    if (get_magic_quotes_gpc()) $string = stripslashes($string);    return $conn->real_escape_string($string);  }?>

使用净化方法:

<?php  require_once 'login.php';  $conn = new mysqli($hn, $un, $pw, $db);  if ($conn->connect_error) die($conn->connect_error);  $user  = mysql_fix_string($conn, $_POST['user']);  $pass  = mysql_fix_string($conn, $_POST['pass']);  $query = "SELECT * FROM users WHERE user='$user' AND pass='$pass'";  // Etc...  function mysql_fix_string($conn, $string)  {    if (get_magic_quotes_gpc()) $string = stripslashes($string);    return $conn->real_escape_string($string);  }?>

使用占位符:

PREPARE statement FROM "INSERT INTO classics VALUES(?,?,?,?,?)";SET @author   = "Emily Brontë",    @title    = "Wuthering Heights",    @category = "Classic Fiction",    @year     = "1847",    @isbn     = "9780553212587";EXECUTE statement USING @author,@title,@category,@year,@isbn;DEALLOCATE PREPARE statement;

或者:

<?php  require_once ;   = new mysqli;  if  die;   = ->prepare;  ->bind_param;     = ;      = ;   = ;       = ;       = ;  ->execute;  printf;  ->close;  ->close;?>'login.php'$conn(, , , )$hn$un$pw$db(->connect_error)$conn(->connect_error)$conn$stmt$conn()'INSERT INTO classics VALUES(?,?,?,?,?)'$stmt(, , , , , )'sssss'$author$title$category$year$isbn$author'Emily Brontë'$title'Wuthering Heights'$category'Classic Fiction'$year'1847'$isbn'9780553212587'$stmt()(, ->affected_rows)"%d Row inserted.\n"$stmt$stmt()$conn()

注意第一个参数’sssss’是一个表示每个变量类型的字符串,i-整数型,d-双精度型,s-字符串型,b-BLOB型。

防止HTML注入:
尽量使用htmlentities函数,剥去所有的html标记并以一种显示字符的形式替换,不允许浏览器操作它们。
防止sql与xss注入攻击的函数:

<?php  function mysql_entities_fix_string($conn, $string)  {    return htmlentities(mysql_fix_string($conn, $string));  }      function mysql_fix_string($conn, $string)  {    if (get_magic_quotes_gpc()) $string = stripslashes($string);    return $conn->real_escape_string($string);  }?>

使用上述函数:

<?php  require_once 'login.php';  $conn = new mysqli($hn, $un, $pw, $db);  if ($conn->connect_error) die($conn->connect_error);  $user  = mysql_entities_fix_string($conn, $_POST['user']);  $pass  = mysql_entities_fix_string($conn, $_POST['pass']);  $query = "SELECT * FROM users WHERE user='$user' AND pass='$pass'";  //Etc…  function mysql_entities_fix_string($conn, $string)  {    return htmlentities(mysql_fix_string($conn, $string));  }      function mysql_fix_string($conn, $string)  {    if (get_magic_quotes_gpc()) $string = stripslashes($string);    return $conn->real_escape_string($string);  }?>
0 0