关于Deny 和 Allow 的说明
[总则]:
影响最终判断结果的只有两点:
order语句中allow、deny的先后顺序;
allow、deny语句中各自包含的范围。
修改完配置后要保存好并重启Apache服务,配置才能生效;
开头字母不分大小写;
allow、deny语句不分先后顺序,谁先谁后不影响最终判断结果,但都会被判断到;
当地址栏中的域名与配置中的不匹配时,浏览器默认显示的是第一个站点的结果,因为Apache是尽力而为的服务机制。
静态网页:就是不会“变化”的网页(内容);
动态网页:就是会因浏览的时间或不同的人而呈现不同的网页(内容)。
重要理念:后台程序的运行结果(动态程序),最终的目的,是"输出"前台的静态网页(前端代码)。
WAMP环境: Windows + Apache + MySQL + PHP
LAMP环境: Linux + Apache + MySQL + PHP
LNMP环境: Linux + Nginx + MySQL + PHP
一个重要理念:
所谓一个网站,就是一个文件夹!
所谓一个网页,就是一个文件!!
****默认站点配置:
httpd.conf里配置ServerName(网站域名,默认为localhost),DocumentRoot(网站所在位置即文件夹),Directory(路径设为网站所在位置对应的文件夹并设置访问权限);
权限里的那些事:options indexs followsymlinks(当没有网页显示时列出当前目录),options -indexs (不显示当前目录)
在httpd.conf里在 中可以设置默认网页,可以设置多个,前者找不到可以载入后者。
****多站点配置:
首先在httpd.conf里用Include conf/extra/httpd-vhosts.conf载入虚拟主机配置;
其次在httpd-vhosts.conf里的 中逐个创建站点:1.ServerName指定域名;2.DocumentRoot配置站点实际路径即文件夹;3.Directory配置访问权限。
最后在hosts(本地DNS文件)里修改IP地址和站点对应域名的映射关系。
特别注意:
当我们使用的虚拟主机配置文件来配置多站点,则原来httpd.conf中的默认站点就被“覆盖了”!
要想恢复它,只要把它当做多站点中的一个站点去重新配置就好了!
重新赋值;unset销毁;析构函数销毁(当前PHP代码执行末尾)
C/S架构:
1.一般我们使用的软件都是C/S架构;
2.比如系统的中的软件QQ、360、office、XMind;
3.C表示客户端,用户通过客户端来使用软件;
4.S表示服务器,服务器负责处理软件的业务逻辑;
C/S特点:
1.软件使用前必须得安装;
2.软件更新时,服务器和客户端得同时更新;
3.C/S架构的软件不能跨平台使用;
4.C/S架构的软件客户端和服务器通信采用的是自有协议,相对来说比较安全。
B/S架构:
1.B/S本质上也是C/S,只不过B/S架构的软件,使用浏览器作为软件的客户端;
2.B/S架构软件通过使用浏览器访问网页的形式,来使用软件;
3.比如:京东 淘宝 12306 知乎 新浪微博;
B/S特点:
1.软件不需要安装,直接使用浏览器访问指定的网址即可;
2.软件更新时,客户端不需要更新;
3.软件可以跨平台,只要系统中有浏览器,就可以使用;
4.B/S架构的软件,客户端和服务器之间通信采用的是通用的HTTP协议,相对来说不安全。
在Web系统中,常常需要记录用户的有关信息,以供用户再次以此身份对Web服务器提起请求时进行确认。
在PHP中,通常采用的方式就是使用Cookie或Session来保存用户信息。
Web系统是采用HTTP协议进行数据传输的。而该协议是一个无状态协议,无法得知用户的浏览状态,也就是说,客户端与服务器的每一次连接都被当成是一次单独的操作。
用户在前一张网页的数据不能在第二张网页上使用。因此,产生了两种用于保持连接状态的技术,它们就是Cookie和Session。
Cookie是一种在远程浏览器端储存数据并以此来跟踪和识别用户的机制。当相同的计算机通过浏览器请求一个页面时,原先存储的Cookie也会发送到服务器。
由于Cookie是保存在客户端的,因此可以随意地设置Cookie的保存时间。为了能够永久的保持用户信息,使用Cookie是最为便捷的方式。
要使用Cookie,必须知道其工作原理。一般来说,Cookie通过HTTP Headers从服务器端返回到浏览器上。首先,服务器端在响应中利用Set-Cookie header来创建一个Cookie。
然后,浏览器在它的请求中通过Cookie header包含这个已经创建的Cookie,并且将它返回至服务器,从而完成浏览器的验证。
Session是保存用户信息的另一种方式。它将用户信息以文件的形式存储在服务器,然后通过客户端提交的session_id识别客户端的信息。
使用该方式,访问网站的每一位来客将会被分配一个唯一的标识符,即所谓的SessionID。它可以存放在客户端的Cookie中,也可以经由URL进行传递。
cookie的操作:Cookie可用于使用保存用户状态。在PHP中,可直接对Cookie进行操作,如将状态信息写入Cookie、从Cookie读取状态信息、设置用户状态等信息的保存时间等。
session的操作:与Cookie一样,在PHP中一样可以直接对Session进行操作,如设置Session的存储位置、检测变量是否在Session注册、设置Session的生命周期等。
如果使用了Seesion,或者在PHP文件使用Session变量,那么就必须在调用之前启动Session。启动Session只需要在PHP脚本中使用session_start()函数,PHP将自动完成Session文件的创建。该函数的语法格式如下所示。
bool session_start(void)。其中,void表示函数没有参数。该函数将开始一个Session或者恢复已存在的基于由POST、GET或者Cookie提交的当前SessionID的Session。函数总是返回布尔值true。
(1)语法:CREATE TABLE table_name SELECT 字段列表 FROM 旧表名
举例:CREATE TABLE news SELECT * FROM student
说明:表的结构和数据都会复制,但主键和自增长属性不会复制。
(2)语法:
//复制表结构
CREATE TABLE new_ table_name LIKE [db_name.]old_table_name;
//插入数据
INSERT INTO new_table_name SELECT * FROM old_table_name;
说明:先复制表结构,再插入数据。
注意:使用LIKE关键字,可以复制表的结构和主键,但没有数据。
举例:CREATE TABLE student2 LIKE student;
INSERT INTO student2 select * from itcast.student;
(1)MyISAM存储引擎:MySQL中的数据用各种不同的技术存储在文件(或者内存)中。这些技术中的每一种技术都使用不同的存储机制、索引技巧、锁定水平并且最终提供广泛的不同的功能和能力。
通过选择不同的技术,你能够获得额外的速度或者功能,从而改善你的应用的整体功能。
MyISAM拥有较高的插入和查询速度,但不支持外键和事务处理;
MyISAM支持高速存储和检索,以及全文搜索能力;
MyISAM是独立于操作系统的,可以轻松的移动和复制文件;
MyISAM安全性稍低些;
当创建一个MyISAM存储引擎表时,就会在磁盘上建立三个文件:.frm 表的定义;.MYD 存储数据;.MYI 表的索引。
(2)InnoDB存储引擎:
InnoDB:支持ACID事务,支持行级锁定和外键约束;
InnoDB存储引擎特别适合处理多重并发的更新请求;
InnoDB存储引擎是支持事务的标准MySQL存储引擎;
与其它存储引擎不同,InnoDB表能够自动从灾难中恢复;
MySQL支持外键的存储引擎只有InnoDB;
支持自动增加列AUTO_INCREMENT属性;
InnoDB安全性较高;
InnoDB在插入数据时效率低些。
InnoDB存储引擎,具备较好的性能和自动崩溃恢复特性,目前应用极为广泛。
InnoDB存储引擎支持:事务、支持行锁、支持非锁定读、支持外键。
InnoDB存储引擎更新和查询速度比较快,对于海量数据尤其明显。
InnoDB存储引擎目前不支持全文检索,但MySQL5.5版本支持。
InnoDB存储引擎是当前MySQL中默认的存储引擎。
InnoDB的数据都保存在ibdataN文件中(索引、数据、表结构)。
创建一个InnoDB表,多了一个表结构文件,所有的InnoDB表数据都放在一起,文件名是ibdata。如果数据量很大,数据库自动的将表数据文件分为ibdata1、ibdata2、ibdata3…。
MyISAM存储引擎和InnoDB存储引擎,为数据库设计存储引擎时需要考虑未来的数据扩充。MyISAM支持全文索引,数据文件独立于操作系统,便于移动和复制。但存储引擎的不同总归有利有弊,可根据实际情况选择。
MySQL的扩展属性有unsigned和zerofill,其他类型数据库不一定支持。如果为一个整数列指定zerofill,会自动为该列添加unsigned属性。
float和double表示近似数值类型。decimal表示精确数值类型。
M参数表示数值总位数,D表示数值的小数位数。小数点和符号位不含在其中。例如:float(5,2)可以显示-999.99,可见小数点和符号位没有计算在内。
参数M和D可以省略,float不带参数,则总位数(M)为6位(包括小数部分),超出部分进行四舍五入;而double不带参数,则总位数(M)为17位(包括小数部分),超出部分直接截取。
Float和double距离最大表示范围时,开始不精确了。
decimal默认是decimal(10,0),不带小数。decimal小数位数可以自己设定,取值0-30之间。Decimal一直是精确的。
float小数位数最多6位,超过6位要进行四舍五入;而double小数位数最多15位,超过15位要进行四舍五入。
默认是有符号的,如果要声明无符号的,则使用unsigned,此时负号被去掉了,正数部分不变。注意和整型的区别。
Char和varchar共同点:都是用来表示字符串的,声明的时候必须定义其长度。
如果分配给CHAR或VARCHAR列的值超过列的最大长度,则对值进行裁剪以使其适合。如果被裁掉的字符不是空格,则会产生一条警告。
char的处理效率高,但不灵活,而varchar很灵活,但是效率稍低,容易产生碎片。
char的应用场景:手机号、邮编,身份证号等;varchar的应用场景:邮箱地址,新闻标题,家庭住址等。
举例:INSERT INTO student(name,sex) VALUES(‘admin’,‘男’)
举例:INSERT INTO student(name,sex) VALUES(‘admin’,1)
SET为每个元素是用位来表示的。MySQL为每个集合的元素分配一个固定的值,分配方式从前往后按20、21、22、23来排列。如果选择多个爱好,是按位或的关系。
这时我们可以用heredoc,nowdoc两种定界字符串。heredoc的写法如下:
<<<标识符
中间写大段的文本
标识符;
注意:
1:标识符的名称和变量名的要求一样.
2:heredoc的标识符,一定是独占一行,而且前面没有任何其他字符,连空格都不行就是打头写.
3:heredoc对文本的处理,和 双引号一样,即\r\n\t,变量,等,能解析出来.
// heredoc写大段文本挺方便,但是对内部的字符解析,和双引号一样.
// 如果我不想这样,有没有类似heredoc写大段文本,
// 但是,对文本的解析又像 单引号那样简单.
// 有没有这样的用法呢?
// 答: 有
// 到了5.3.0之后, 又新增了nowdoc方式,能达到如上效果.
echo '
';
$str = <<<'cont'
我来写一行,
再来第2行, ' " \,
dsafd abc \t \r\n haha
$age
cont;
echo $str;
/***
nowdoc写法和heredoc一样,唯独在标识符两边用单引号包起来,
这样,大段文本的解析,就和单引号一样的效果.
不转义 \n \r \t,变量等等
***/
几个常识:
a,1字节(B)就是8个bit位(最小的存储空间),1KB=1024B,1MB=1024KB,1GB=1024MB。。
b,一个英文字符占据1字节空间,gbk编码中1个汉字占据2个字节,utf8编码1个汉字占3字节。
strlen 计算字符串长度,一个中文当2字符
mb_strlen根据它的字符编码模式,统计字符quot
count计算数组中的元素数目或对象中的属性个数
在gb2312中,strlen计算字符长度时,一个中文字符算2个长度。
在strlen计算时,对待一个UTF8的中文字符是3个长度,所以“中文a字1符”长度是3*4+2=14。
在mb_strlen计算时,选定内码为UTF8,则会将一个中文字符当作长度1来计算,所以“中文a字1符”长度是6 。
如碰到中英文混合的字符串时尽量避免采用中文字符集,此时或许会发生长度计算错误。
可以使用任意整数,也可以不显式使用下标,此时默认就是整数下标。
而且,从前往后,每一个没有使用下标的单元,系统给其分配的下标为之前所用过的整数下标的最大值+1(对于第一个是0)。
$arr1 = array(‘a’, 2=>’b’, ‘c’, ‘x’=>’d’, ‘e’); // 其下标分别为:0, 2, 3, ‘x’, 4
$arr2 = array(5=>‘a’, 2=>’b’, ‘c’, ‘x’=>’d’); // 其下标分别为:5, 2, 6, ‘x’
$arr3[‘x’] = 5; //这一行,会自动创建一个数组,
$arr3[ ] = 6; //此时下标就是0
$arr3[ ] = 16; //此时下标就是1。
实际上,由于PHP的数组值可以是“任意数据”,因此,PHP数组的维数其实没有太大实际意义的。
所谓维数,其实是另一些编程语言中的数组的“整齐”格式的说法:一维数组类似排成一排的格子(线);二维数组类似排成一个平面的格子(面);三维数组类似堆满了一屋子的格子(体)。
而php数组,却可以更为灵活,类似这样:array(1, 2, array(31, 32, ), 4,array(51, 52, 53, array(541, 542, 543, 544) ), 6, array(71, 72, 73), );
这种数组就不好说几维的了,而可以称为“异形数组。
//这里,$key和$value只是变量,它会在遍历数组的过程中,按顺序依次取得数组每个单元的下标和值。
TEXT列有一个字符集,并且根据字符集的 校对规则对值进行排序和比较。
BLOB可以用来存储多媒体(图片、视频、音乐)。
但实际项目中,我们并不用BLOB来存储多媒体。那么,多媒体如何存储呢?一般是在数据库中存储多媒体文件的路径,而具体文件存储在网站的虚拟目录中。
这样做的好处是:可以节省数据库的空间。
将文件的路径地址存储到数据库中;
将文件存储到自己虚拟空间中;
这样做的好处:节省数据库空间,提高查询数据库的速度。
数据库本身没有容量限制,能存多少数据由服务器磁盘量决定。
使用日期时间类型的时候,要加引号,year可以不加。
Timestamp具备默认值和自动更新功能
任何标点符号都可以用于date之间的分割号,但数据库中,同样是中划线。
Date、time、datetime之间也可以没有分割号,但必须是合法的日期格式。
如果插入的date、time、datetime数据超出范围,则报错,并插入失败。
可以使用函数 now() 或 current_date变量、current_time变量、current_timestamp变量插入当前日期时间信息。
TIMESTAMP列的显示格式与DATETIME列相同。换句话说,显示宽度固定在19字符,并且格式为YYYY-MM-DD HH:MM:SS。
在实际开发中,我们经常使用int来存储日期时间,一般都会用int(10)。
在MySQL中,now()函数获取当前时间戳,current_date()获取当前日期,current_time()获取当前时间,时间戳格式:YYYY-mm-dd HH:mm:ss,秒值是1524526897.
插入的字段个数,必须与值的个数一致。
插入的字段顺序,可以与表中的字段顺序不一致。
插入的字段可以省略,省略的条件是:插入的值的个数和顺序和表中的个数和顺序一致。
字段值如果是字符串,请用引号引起来。
自动增长型字段,不要人为去添加,请用null(建议) 代替。
可以通过 default 关键字插入默认值。
可以通过 null 关键字插入空值。
蠕虫复制的原理就是用inset ... select批量插入,批量插入也可以用于压力测试。
mysql>insert into student(name,sex,age,edu,salary,bonus,city) select name,sex,age,edu,salary,bonus,city FROM student;//id不能插入,因为不能重复。
语法:TRUNCATE [TABLE] tbl_name
说明:快速删除表中数据,重新设置AUTO_INCREMENT计数器。
举例:TRUNCATE news
DELETE FROM和TRUNCATE的区别:
TRUNCATE 删除操作会取消并重新创建表,这比一行一行的删除行要快很多;AUTO_INCREMENT将从头开始计数。
DELETE FROM删除全部数据,是一行一行的删除,速度慢的多,并且auto_increment不会重新设置,添加一条记录时,id值是在最大auto_increment上加上。
显示所有记录:SELECT * FROM WHERE true
不显示任何记录:SELECT * FROM news WHERE 0
mysql> select distinct city,count(*) as '人数' from student group by city;按照城市分组计算所在地区的人数。
mysql> select city,count(*) as 人数,max(salary) 最大工资,min(salary) 最小工资,avg(salary) 平均工资 from student group by city;计算各城市的人数及工资情况。
mysql> select edu as 学历,count(*) as 人数 from student group by edu having count(*)>10;计算某项学历超过10人的学历。
mysql> select * from student where city like '%南%';查询学生所在城市包括”南“的学生记录。
mysql> select * from student where city in('山东省','河南省');查询学生是山东省或河南省的记录。
mysql> select count(*) as 人数 from student where salary>(select avg(salary) from student);计算高于平均工资的人数。
mysql> update news set hits=hits*10 where id<50 order by id limit 2;更新排序靠前的2条记录的单击率。
mysql> update article set title=replace(title,'袁贵仁','张三丰') where aid =1;更新字段中某些字符。
having后可以跟别名做判断条件,而where后不可以跟别名做判断条件。
LIMIT [startrow,]pagesize
[startrow]表示开始行号,可以省略,默认值为0 ;
pagesize表示每次显示多少条记录;
说明:
startrow表示从第n行起,但不包括第n行;
startrow表示的开始行号,是“自然行号”,与数据表中的记录顺序无关;
数据分页的startrow的公式: ($page-1)*$pagesize
举例:
SELECT * FROM students LIMIT 10; //从第0行起,取10条记录
SELECT * FROM students LIMIT 10,10; //从第10行起,取10条记录
SELECT * FROM students LIMIT 20,10; //从第20行起,取10条记录
描述:对字符类型的数据,进行“模糊查询”
语法:WHERE col_name LIKE ‘目标字符’
说明:在’目标字符’中可以使用通配符
“_”表示任意一个字符。如:“张_军”查找张某军;
“%”表示任意多个字符。如:“张%”查找姓张的人名;
提示:如果要查找“_”或“%”,则需要用转义字符。
举例:
查找张某军:SELECT * FROM student WHERE name like “张_军”;
查找姓张的:SELECT * FROM student WHERE name like “张%”;
查找下划线:SELECT * FROM student WHERE name like “%\_%”;
查找百分号:SELECT * FROM student WHERE name like “%\%%”
(1)建表:
create table testintdate(
id int not null auto_increment,
p_date int(10),
primary key(id));
(2)插入测试数据:
插入时用UNIX_TIMESTAMP()函数将日期串转换成int(UNIX时间戳)
insert testintdate
values(null,UNIX_TIMESTAMP('2009-08-06'));
insert testintdate
values(null,UNIX_TIMESTAMP('2015-12-06'));
insert testintdate
values(null,UNIX_TIMESTAMP('2009-08-06 11:12:46'));
insert testintdate
values(null,UNIX_TIMESTAMP('2015-12-06 18:15:50'));
(3)查询数据:
用FROM_UNIXTIME(p_date)将int转换成日期串
select id,FROM_UNIXTIME(p_date) from testintdate;
select id,FROM_UNIXTIME(p_date,'%Y-%m-%d') from testintdate;
描述:replace()函数主要应用于UPDATE语句中
语法:update table_name set title=replace(字段,源字符串,目标字符串)[where条件];
视图与表不同,视图是一个虚表,即视图所对应的数据不进行实际存储,数据库中只存储视图的定义,对视图的数据进行操作时,系统根据视图的定义去操作与视图相关联的基本表。视图一经定义,就可以像表一样被查询、修改、删除和更新。
为用户集中数据,简化用户的数据查询处理。有时用户所需要的数据分散在多个表中,定义视图可将它们集中在一起,从而方便用户的数据查询和处理。
屏蔽数据库的复杂性。用户不必了解复杂的数据表结构,并且数据表的更改也不影响用户对数据库的使用。
简化用户权限的管理。只需要授予用户使用视图的权限,也增加了安全性。
便于数据共享。各用户不必都定义和存储自己所需的数据,可共享数据库的数据,这样同样的数据只需存储一次。
可以重新组织数据以便输出到其它应用程序中。
语法一:SELECT col_list FROM table1 INNER JOIN table2 [ON condition]
语法二:SELECT col_list FROM table1,table2 [WHERE condition]
mysql> select * from stu_info as a inner join stu_depart as b on a.depart =b.id;
左连接:描述:以左表为准,取得左表完整记录;如果左表记录少于右表,则右表多余的记录被过滤;如果左表记录多于右表,则多余的字段用NULL代替。没找到匹配的数据用NULL代替。
语法:SELECT col_list FROM table1 [AS 别名] LEFT JOIN table2 [AS 别名] [ON condition]
参数:ON关键字指定左右两表关联的条件。
注意:必须要指定左右两个表的连接条件,否则报错。
mysql> select a.aid,b.username,a.title,a.hits,a.addate from article as a left join user as b on a.uid=b.uid;查询文章的发布者信息。
mysql> select a.classname 分类名称 ,count(b.category_id) 数量 from category a left join article b on a.id=b.category_id group by a.classname;计算各类别对应的文章数,此时需要分组否则只会输出一行统计数据,不指定分组会统计所有记录数。
右连接:描述:以右表为准,取得右表完整记录;如果右表记录少于左表,则左表多余的记录被 过滤;如果右表记录多于左表,则多余的字段用NULL代替。
语法:SELECT col_list FROM table1 [AS 别名] RIGHT JOIN table2 [AS 别名] [ON condition]
参数:ON关键字指定左右两表关联的条件。
注意:必须要指定左右两个表的连接条件,否则报错。
语法:SELECT语句 UNION [ALL | DISTINCT] SELECT语句 [UNION [ALL | DISTINCT] SELECT ...]
参数:ALL不消除重复行,DISTINCT消除重复行(默认值)
说明:
UNION 用于合并两个或多个 SELECT 语句的结果集;
UNION 内部的 SELECT 语句必须拥有相同数量的列;
UNION内部的列也必须拥有相似的数据类型;
同时,每条 SELECT 语句中的列的顺序必须一致;
UNION 结果集中的列名总是以第一个 SELECT 语句中的列名为准。
mysql> select * from student where salary>30000 union select * from student where salary<1000;
mysql> select * from student where city='河南省'
-> union
-> select * from student where city='山东省';
如果每个select语句都要进行单独排序时,请把每个select语句用小括号包起来,order by字句必须与limit一起使用否则排序无效。
对整个结果集排序就在最后添加order by字句。
mysql> (select * from student where salary<=3000 order by salary limit 20)
-> union
-> (select * from student where salary>20000 order by salary desc limit 20);
提示:使用联合查询时order by字句必须和limit一起使用,否则排序无效。
将一个查询的结果,作为另一个查询的条件时,该查询称为“子查询”;
子查询一般用在where子句中,子查询要用小括号()括起来;
子查询是一个 SELECT 语句,它嵌套在一个 SELECT、SELECT...INTO 语句、INSERT...INTO 语句、DELETE 语句、或 UPDATE 语句或嵌套在另一子查询中。
mysql> select count(*) as 人数 from student where salary>(select avg(salary) from student) and city='山东省';查询高于平均工资且为山东省的人数 。
mysql> select * from student where salary=(select max(salary) from student);查询最高工资的学生信息。
mysql> select sex,count(*) as 人数 from student where age<(select avg(age) from student) group by sex;查询低于平均年龄的男女生人数并以性别分组。
mysql> select * from student where age<(select avg(age) from student) and sex='男';查询低于平均年龄的男生人数。
mysql> select * from student where salary<(select avg(salary) from student) limit 1;查询低于平均工资的第一条记录。
mysql> select * from student where salary<(select avg(salary) from student) order by salary desc limit 1;查询最接近平均工资的第一条记录。
标量子查询
描述:返回结果是1行1列,即单一的值。可以使用 = > < >= <= <> 这些操作符对子查询的标量结果进行比较,通常子查询的位置在比较式的右侧。
例题:查询工资最高的学生信息
代码:select * from student where salary=(select max(salary) from student);
列子查询
描述:子查询返回的结果集是 N 行1列,该结果来自对表的某个字段查询返回。可以使用 IN、ANY、SOME 和 ALL 操作符,不能直接使用 = , > , < , >= , <= , <> 等操作符。
mysql> select * from student where city in(select city from student where city='山西省' or city='山东省');
使用ANY的列子查询(OR)
描述:与比较操作符联合使用,表示与子查询返回的任意一个值比较为TRUE ,则返回 TRUE 。只要有一个值大于子查询中的值,则符合条件。
语法:FROM table WHERE col_name 比较运算符 ANY(列子查询)
例如:id>ANY(1,3,5),表示与任意一个值比较为TRUE,则结果为TRUE。
例如:idselect * from student where id>any(select id from student where id in(30,40));
使用ALL的列子查询(AND)
描述:与比较操作符联合使用,表示与子查询返回的单列的所有值比较都为 TRUE ,则返回 TRUE 。
语法:FROM table_name WHERE col_name 比较运算符 ALL(列子查询)
例如:id>ALL(1,3,5),与每一个值比较都为TRUE,换句话说:就是大于最大值。
例如:idALL”的别名,两者一样。
注意:如果table2为空表,则ALL后的结果为TRUE。
mysql> select * from student where id>all(select id from student where id in(30,40,50));
行子查询
描述:行子查询是指子查询返回的结果集是1行 N 列,该子查询的结果通常是对表的某行数据进行查询而返回的结果集。
语法:SELECT * FROM table1 WHERE (column1,column2) = (SELECT column1, column2 FROM table2)
说明:
在该例子中,在保证子查询返回单一行数据的前提下,如果 column1=1 且 column2=2 ,则该查询结果为 TRUE。
where后的多个字段列表,必须放在()中,中间用逗号隔开;单个字段,可以不用放在小括号()内。
where后的字段列表,必须与子查询的字段列表,顺序和个数一致;
举例:SELECT * FROM student WHERE (city)=(SELECT city FROM student WHERE city='北京市'LIMIT 1);
mysql> select * from student where (salary,city)=(select salary,city from student where salary=12300 and city='北京');查询工资为12300且为北京市的学生信息。
表子查询(where之后)
描述:表子查询是指子查询返回的结果集是 N 行 N 列的一个表数据。
语法:SELECT * FROM student WHERE (city) IN (SELECT city FROM student WHERE city=‘北京市’or city=‘上海市’)
说明:将中间的条件由“=”变成“in”,则由行子查询,变成表子查询。
表子查询(from之后)
描述:FROM 子查询是指 FROM 的子句作为子查询语句,主查询再到子查询结果中获取需要的数据。
语法:SELECT ... FROM (subquery) AS name ...
说明:子查询会生成一个临时表,这样有利于数据的保护,避免对原数据的误操作。由于 FROM 子句中的每个表必须有一个名称,因此 AS name 是必须的。FROM 子查询也称为衍生数据表子查询。
举例:SELECT * FROM (SELECT id,name,salary,bonus,salary+bonus AS total FROM student) AS a WHERE total>40000;
mysql> select * from (select id, name, salary+bonus 实发工资 from student where salary+bonus>40000);
ERROR 1248 (42000): Every derived table must have its own alias //临时表需要指定别名
mysql> select * from (select id, name, salary+bonus 实发工资 from student) as a where 实发工资>40000;
使用exists(存在)和not exists(不存在)的子查询
描述:可以理解为,将主查询的数据,放到子查询中做条件验证,根据验证结果(TRUE 或 FALSE)来决定主查询的数据结果是否得以保留。
语法:SELECT ... FROM table WHERE EXISTS (subquery)
举例(1):查出 article 表中的数据,但要求 uid 必须在 user 表中存在。
代码(1): SELECT * FROM article WHERE EXISTS(SELECT * FROM user WHERE article.uid=user.uid); //如果两个表中都存在,则返回TRUE
举例(2):查出 article 表中的数据,但要求 uid 不在 user 表中存在。
代码(2): SELECT * FROM article WHERE NOT EXISTS(SELECT * FROM user WHERE article.uid=user.uid); //如果不同时存在两个表中的,则返回FALSE
描述:在CMD模式下,调用MySQL客户端程序 mysqldump.exe 来实现备份(到处数据)。
语法:mysqldump [-h主机名][-p端口号] –u用户名 –p密码 [-d] dbname [tblname] > file.sql
参数:
-h主机名,可以省略,默认为localhost;
-p端口号,可以省略,默认为3306;
-u用户名,不能省略;
-p密码,可以先不输,回车后再输入,此时为星号;
-d数据表结构,如果添加该参数,则只导出数据表的结构,不含数据;
“>”将数据库及其数据表,导出到指定的SQL文件中;
导入数据(MySQL客户端):source c:/mysql/article.sql
备份数据
导出数据库:mysqldump –uuser -p dbname > dbname.sql
导出数据库结构:mysqldump -uuser -p -d dbname > dbname.sql
导出数据表:mysqldump -uuser -p dbname tblname > tblname.sql
导出数据表结构:mysqldump -uuser –p -d dbname tblname > tblname.sql
提示:导出数据表时,一定要指定所在的数据库名称;
注意:在导入前,一定要先创建一个空的数据库。
恢复数据
描述:使用mysql.exe客户端程序,来导入数据。
语法:mysql.exe [-h主机名][-p端口] –u用户名 –p密码 dbname < back.sql
提示:只需要指定dbname即可,而不能指定tblname,否则,导入失败。
举例:mysql -uroot -proot itcast < back.sql
注意:授予全局权限在user表里,授予局部权限在db表里。
header("Content-Type:text/html;charset=utf-8");
设置跳转路径:
header("Location:http://www.itcast.cn");
header('location:formnian.php');
如果目录不为空,从内向外递归删除。
rename同级目录为改名,不同级目录为移动,移动的同时可以重命名。
header(“content-type:image/jpeg”);
第1步:PHP连接MySQL服务器,mysql_connect()函数;
第2步:选择当前数据库,mysql_select_db()函数;
第3步:设置字符集,mysql_query(“set names utf8”);
第4步:执行各种SQL语句,mysql_query(“SELECT * FROM student”);
第5步:从结果集中取一行数据,mysql_fetch_row()、mysql_fetch_assoc()、mysql_fetch_array();
第6步:获取记录数:mysql_num_rows()、mysql_afftected_rows()。
PHP 支持一个错误控制运算符:@。当将其放置在一个 PHP 表达式之前,该表达式可能产生的任何错误信息都被忽略掉(不包括语法错误)。
@ 运算符只对表达式有效。
对新手来说一个简单的规则就是:如果能从某处得到值,就能在它前面加上 @ 运算符。
例如,可以把它放在变量,函数和 include调用,常量,等等之前。
不能把它放在函数或类的定义之前,也不能用于条件结构例如 if 和 foreach 等。
2)隐藏域用于存储一些服务器需要的数据,不想在网页上显示的数据;
3)ac就是action,表示用户动作。用来判断用户的操作。
4)PHP中chmod()不能用于远程文件。
Windows下文件的只读权限为:0444,文件夹只读权限0555。
用法如下:
self.location.href=”/url” 当前页面打开URL页面;
this.location.href=”/url” 当前页面打开URL页面;
parent.location.href=”/url” 在父页面打开新页面;
top.location.href=”/url” 在顶层页面打开新页面。
Javascript中的location.href有很多种用法,主要如下:
self.location.href=”/url” 当前页面打开URL页面,
location.href=”/url” 当前页面打开URL页面,
windows.location.href=”/url” 当前页面打开URL页面,前面三个用法相同。
此外,window.location.href=window.location.href;和window.location.Reload()和都是刷新当前页面。
区别在于是否有提交数据。当有提交数据时,window.location.Reload()会提示是否提交,window.location.href=window.location.href;则是向指定的url提交数据。
“window.location.href”、”location.href”是本页面跳转,”parent.location.href”是上一层页面跳转,”top.location.href”是最外层的页面跳转。
1).打开目录opendir():
描述:打开目录句柄,可用于之后的 closedir(),readdir() 和 rewinddir() 调用中。
返回值:如果成功则返回目录句柄的 resource,失败则返回 FALSE。
2).读取目录中条目readdir():
描述:从目录句柄中读取条目 ;
语法:string readdir ([ resource $dir_handle ] )
说明:返回目录中下一个文件的文件名。文件名以在文件系统中的排序返回。
返回:成功则返回文件名 或者在失败时返回 FALSE 。
3).显示中文目录或文件iconv():
描述:字符串按要求的字符编码来转换
语法:string iconv ( string $in_charset , string $out_charset , string $str )
参数:$in_charset,输入的字符集;
$out_charset,输出的字符集;
$str,要转换的字符串;
返回:返回转换后的字符串, 或者在失败时返回 FALSE。
4).关闭目录句柄closedir():
描述:关闭由 dir_handle 指定的目录流。流必须之前被 opendir() 所打开。
语法:void closedir ( [resource $dir_handle] )
提示:如果省略$dir_handle,则默认为最后由opendir()打开的目录句柄。
$flag=mkdir($dirname,0777,true);
结果中有’true’表明递归创建成功,’false’表明递归创建失败,此时可能文件夹路径已经存在。
1)创建新目录mkdir();
2)判断是否是一个目录is_dir();
3)判断目录或文件是否存在file_exists();
4)删除目录rmdir();
5)重命名或移动文件或目录rename();
6)打开目录opendir():
7)读取目录中条目readdir();
8)显示中文目录或文件iconv();
9)关闭目录句柄closedir();
1)打开文件fopen() :resource fopen ( string $filename , string $mode );
提示:为移植性考虑,在用 fopen()打开文件时总是使用 ‘b’ 标记。
返回值:成功时返回文件指针资源,如果打开失败,本函数返回 FALSE。
2)关闭文件fclose():bool fclose ( resource $handle );
$handle必须是由fopen()打开的文件指针。
3)读取指定大小文件内容fread():
描述:读取文件(可安全用于二进制文件)
语法:string fread ( resource $handle , int $length )
参数:$handle是由fopen()创建的handle;$length最多读取的字节数。
提示:在区分二进制文件和文本文件的系统上(如 Windows)打开文件时,fopen() 函数的 mode 参数要加上 ‘b’。
返回值:返回所读取的字符串, 或者在失败时返回 FALSE。
4)读取一行内容fgets():
描述:从文件指针中读取一行
语法:string fgets ( resource $handle [, int $length ] )
参数:$handle:文件指针必须是有效的;
$length:从 handle指向的文件中读取一行并返回长度最多为 length - 1 字节的字符串。碰到换行符(包括在返回值中)、EOF 或者已经读取了 length - 1 字节后停止(看先碰到那一种情况)。如果没有指定 length,则默认为 1K,或者说 1024 字节。
5)读取文件内容到数组中file():
描述:把整个文件读入一个数组中
语法:array file ( string $filename [, int $flags = 0 ] )
参数:
$filename,文件的路径;
$flags,附加选项;
FILE_USE_INCLUDE_PATH(1):在include_path 中查找文件;
FILE_IGNORE_NEW_LINES(2):在数组每个元素末尾不添加换行符;
FILE_SKIP_EMPTY_LINES(4):跳过空行。
注意:不需要打开文件和关闭文件。
6)读取文件内容到字符串中file_get_contents():
描述:将整个文件读入一个字符串
语法:string file_get_contents ( string $filename [, bool $use_include_path = false]] )
参数:
$filename指定文件路径;
$use_include_path,是否读取include中的文件内容,默认值为FALSE。
返回:返回读取的数据,或在失败时返回false。
注意:不需要打开和关闭文件。
7)写入文件fwrite():
描述:写入文件(可安全用于二进制文件)
语法:int fwrite ( resource $handle , string $string )
返回:返回写入的字符数,出现错误时则返回 FALSE 。
8)将一个字符串写入文件file_put_contents():
语法:int file_put_contents ( string $filename , mixed $data [, int $flags = 0] )
参数:
$filename要被写入数据的文件名。
$data要写入的数据。类型可以是 string,array(一维数组)。
$flags附加选项。
FILE_USE_INCLUDE_PATH(1) 在 include 目录里搜索 filename
FILE_APPEND(8)如果文件 filename已经存在,追加数据而不是覆盖。
LOCK_EX(2)在写入时获得一个独占锁。
提示:如果文件不存在,则会自动创建。如果文件过大,不能一次性处理。
返回:该函数将返回写入到文件内数据的字节数,失败时返回FALSE。
9)拷贝文件copy():
描述:将文件从 source 拷贝到 dest。
语法:bool copy ( string $source , string $dest )
提示:如果目标文件存在,则会覆盖。
10)删除文件unlink():
语法:bool unlink ( string $filename )
返回:成功时返回 TRUE, 或者在失败时返回 FALSE。
提示:可以删除虚拟空间之外的文件,但必须使用相对路径(../),但必须有权限。
注意:删除的文件不会进入回收站。
11)其它的文件操作函数
filesize(),可以获取文件大小,单位为字节。
is_writable(),判断文件是否可写。
is_readable(),判断文件是否可读。
feof(),判断文件指针是否到达文件结尾。
filectime(),获取创建文件的时间。
fileatime(),获取文件最新访问时间。
filemtime(),获取文件最后修改时间。
每页条数 pagesize
总记录数 records
总页数 pages
当前页码 currentpage
开始行号 startrow
200——OK 成功返回
301——Moved Permanently 永久跳转
302——Move Temporary 临时跳转
302状态码,主要涉及header()函数的refresh和location。
403——Forbidden 拒绝访问
404——Not Found 找不到指定页面
408——Request Timeout 请求超时
500——Internal Server Error 服务器错误
502——Bad Gateway 坏的网关
503——Services Unavailable 服务不可用
504——Gateway Timeout 网关超时
1)请求报文:
请求行(请求方法,URL,协议版本);
请求头(客户端信息,Content-type和Content-Length);
空行(无内容仅为分隔);
请求报文主体(GET方法没有请求报文主体,POST方法才有)
注:请求报文主体中包括了要发送给Web服务器的数据信息。
2)响应报文:
起始行:协议版本号,数字状态码,状态信息;
响应头部:常见的是Content-type和Content-Length;
空行(无内容仅为分隔)
响应主体:装载要返回给客户端的数据。
服务端向客户端浏览器发送文件时,如果是浏览器支持的文件类型,一般会默认使用浏览器打开,比如文本或图片等,会直接在浏览器中显示,如果需要提示用户保存,就要利用Content_disposition进行一下处理,关键在于一定要加上attachment。
当使用Content-Disposition来确保浏览器弹出下载对话框的时候,一定要确保没有做过关于禁止浏览器缓存的操作。
1)通信传输用明文不加密,容易被窃听;
2)不验证通信方身份,容易被伪装;
3)无法验证报文完整性,容易被篡改。
HTTPS是身披SSL外壳的HTTP。HTTPS比HTTP要慢2到100倍。HTTP+通信加密+数字证书+完整性保护=HTTPS。
1)因为cookie保存在浏览器上,所以安全性低
2)可控性比较差,只能存放字符串,不能存放数组和对象
3)因为数据存放在头信息中,所以增加请求数据的负载。
4)大多数的浏览器对cookie有4K的限制。
5)Cookie可以被浏览器阻止——浏览器禁用缓存禁用Cookie,这样的话Cookie功能就失效。
如果是通用的Cookie(登录账户和密码)则在主域名下设置,在主域名和子域名下皆可获取。如果有些Cookie设为子域名下有效,则只能在子域名下设置在子域名下使用,在其他域名下不可使用。
Session是保存用户信息的另一种方式。它将用户信息以文件的形式存储在服务器,然后通过客户端提交的session_id识别客户端的信息。
使用该方式,访问网站的每一位来客将会被分配一个唯一的标识符,即所谓的SessionID。它可以存放在客户端的Cookie中,也可以经由URL进行传递。
Session对象存储特定用户的会话数据;
Session将会话数据存储在服务器端;
Session是基于Cookie技术的,没有Cookie就没有Session;
Session在整个用户会话中,一直存在下去;
一个用户会话时效:从用户登录开始,到用户登录结束;
Session存储的数据量要比cookie大的多;
Session存储的内容类型,不限于字符串;
Session数据存储在服务器端,更安全,可靠。
相同点》
都是会话技术,都有生命周期;
都是无状态性(当服务器执行完毕返回给客户端,服务器不再记录客户端的状态)
不同点》
cookie客户端技术,session是服务器端技术;
cookie保存的数据类型只有字符串,session可以保存除了资源以外的数据类型;
cookie的大小有4K限制,session没有限制;
cookie可以被浏览器禁用,session不能被浏览器禁用;
首先以1440s为周期间隔(sessioin.gc_maxlifetime默认为1440s),如果1440s内,登录了1000个用户,即按照比例(session.gc_probability/session.gc_divisor的比值决定)删除前相应比例批次的session文件。
按时间排序,不使用的为垃圾session文件。session_name()取session名称,session_id()取sessionID。
1)覆盖:在子类中重写父类的方法,而在子类的对象中虽然调用的是父类中的方法,但默认调用的是子类的方法。
2)重载:是类的另一种实现。函数重载指一个标识符被用作多个函数名,且能够通过函数的参数个数或参数类型将这些同名的函数区分开来,以使调用不发生混淆。其好处是可实现代码重用,即不用为了对不同的参数类型或参数个数而写多个函数。
1)抽象类是一种不能被实例化的类,只能作为其他类的父类使用。抽象类使用abstract关键字来声明,抽象类至少要包含一个抽象方法。抽象方法没有方法体,其功能的实现只能在子类中完成。抽象方法也是使用abstract关键字来修饰的,并且在抽象类中的抽象方法后面要在分号";"。
2)接口:PHP只支持单继承,如果想实现多重继承,就要使用接口。PHP可以实现多个接口。接口类通过interface关键字来声明,并且类中只能包含未实现的方法和一些成员变量,格式如下:interface interfaceName{function interfaceName1();function interfaceName2();... ... }
子类是通过implements关键字来实现接口的,如果要实现多个接口,每个接口之间使用逗号。而且接口类中的所有未实现的方法需要在子类中全部实现,否则PHP将会出现错误。
上传文件,就是将文件从浏览器端传到服务器端;
上传文件,必须使用
在JS中,使用this关键字来代替当前对象,例如:this.src = './a.jpg'
在PHP中,使用$this变量来代替当前对象,例如:$this->name = '张三'
$this代表当前对象,是到当前对象的一个引用;
$this更像是一个对象指针,指向当前对象;
$this只能用在对象方法定义中,去调用对象的成员属性或成员方法。
只有创建对象后,$this变量才存在。类不会自动运行。
$this是指向当前对象的指针,而self是指向当前类的指针;
$this关键字用来调用对象的属性和方法;
self用来调用类常量、静态属性、静态方法;
$this关键字只能在成员方法中使用;
self关键字可以在成员方法和静态方法中使用;
单例设计模式:一个类只能创建一个实例对象,不管用什么办法都无法创建第2个对象(可以节省内存),屏蔽掉new和clone相关的操作;
工厂设计模式:生产不同类对象的工厂;
单例设计模式的要求:三私一公
一私:私有的静态的保存对象的属性;
一私:私有的构造方法,阻止类外new对象;
一私:私有的克隆方法,阻止类外clone对象;
一公:公共的静态的创建对象的方法。
判断当前类的对象是否存在:
if(!self::$obj instanceof self)
{
self::$obj=new self;
}
return self::$obj;
异常处理用于在指定的错误(异常)情况发生时改变脚本的正常流程。这种情况称为异常。
当异常被触发时,通常会发生: 当前代码状态被保存 代码执行被切换到预定义的异常处理器函数。
根据情况,处理器也许会从保存的代码状态重新开始执行代码,终止脚本执行,或从代码中另外的位置继续执行脚本 。
我们将展示不同的错误处理方法: 异常的基本使用 创建自定义的异常处理器 多个异常 重新抛出异常 设置顶层异常处理器。
第一步:定义异常类,如果不定义就用系统默认的异常类;
第二步:当出现异常时用 throw 抛出异常,例如 ex1($num2);异常的参数是$num2用该异常的getMessage()获取;
第三步:触发异常,用try子句,当满足条件时 throw new ex1($num);
第四步:catch捕获异常 catch (ex2 $e),相当于实例化一个定义好的异常类ex2为$e;
注意,异常可以定义多个,但是只能触发一个,也就是说只能用catch捕获一个异常.
面向过程是以过程(步骤)为中心的编程思想,面向对象是事务(对象)为中心的编程思想。
对象是专业对象,是一个功能方方面面的总和。例如:数据库对象、分页对象、图像处理等。
一个项目由若干个功能模块构成,包括:用户管理、新闻管理、产品管理、文章管理、学生管理等。
每个功能模块是一个对象,包括:用户对象、新闻对象、产品对象、文章对象、学生对象等。
每个对象对应一个类:包括:用户类、新闻类、产品类、文章类、学生类等。
当然,每个模块还有一些公共对象:数据库对象、分页对象、上传对象、图像处理、验证码对象等。
类的封装性,主要通过权限控制符来实现。
public:公共的权限,在任何地方都可以访问,主要是本类中、子类中、类外。
Protected:受保护的权限,只能在本类和子类可以访问,在类外不能访问。
private:私有的权限,只能在本类中访问,在类外和子类中无法访问。
根据传递不同的类名参数,返回不同类的对象;
工厂模式,就是生产各种的不同类的对象;
工厂模式,改变了在类外使用new关键字创建对象的方式,改成了在工厂类中创建类的对象。
在类的外部我们无法控制类的行为,但在类内部自己可以控制类的行为。
类比:工厂(模式)本身不创建对象,但可以根据订单生产对象(产品)并完成交付。单例工厂模式类似满足需求的个性化个人化。
工厂类中的方法,应该是公共的静态的方法;
工厂类中有一个私有的静态的保存对象的属性(单例工厂模式);
该方法功能:就是根据传递的不同参数,去创建不同的类实例;
提示:工厂设计模式,一般会与单例设计模式搭配使用。
PHP所提供的"重载"(overloading)是指动态地"创建"类属性和方法,我们是通过魔术方法来实现的。
当调用当前环境下未定义或不可见的类属性或方法时,重载方法会被调用。屏蔽错误。
所有的重载方法都必须被声明为 public。
属性重载只能在对象中进行。在静态方式中,这些魔术方法将不会被调用。所以这些方法都不能被 声明为 static。
这些魔术方法的参数都不能通过引用传递。
(1)__get()魔术方法
描述:读取不可访问属性的值时,__get() 会被调用。
语法:public mixed __get ( string $name )
(2)__set()魔术方法
描述:在给不可访问属性赋值时,__set() 会被调用。
语法:public void __set ( string $name , mixed $value )
(3)__isset()魔术方法
描述:当对不可访问属性调用 isset() 或 empty() 时,__isset()会被调用。
语法:public bool __isset ( string $name )
(4)__unset()魔术方法
描述:当对不可访问属性调用 unset() 时,__unset()会被调用。
语法:public void __unset ( string $name )
(1)__call()魔术方法
描述:在对象中调用一个不可访问方法时,__call() 会被调用。
语法:public mixed __call ( string $name , array $arguments )
(2)__callStatic()魔术方法
描述:用静态方式中调用一个不可访问方法时,__callStatic() 会被调用。
语法:public static mixed __callStatic ( string $name , array $arguments )
序列化是将变量转换为可保存或传输的字符串的过程;
反序列化就是在适当的时候把这个字符串再转化成原来的变量使用;
这两个过程结合起来,可以轻松地存储和传输数据,使程序更具维护性;
序列化有利于存储或传递 PHP 的值,同时不丢失其类型和结构。
1)序列化函数serialize():
描述:产生一个可存储的值的表示;
语法:string serialize ( mixed $value )
参数:$value可以是任何类型,除了资源外;
返回:返回序列化之后的字符串,可以存储于任何地方。
2)反序列化函数unserialize():
描述:从已存储的表示中创建 PHP 的值
语法:mixed unserialize ( string $str )
说明:对单一的已序列化的变量进行操作,将其转换回 PHP 的值。
参数:$str为序列化后的字符串;
返回:返回的是转换之后的值,可为 integer、float、string、array或 object。 如果传递的字符串不可序列化,则返回 FALSE,并产生一个 E_NOTICE。
对象的序列化过程,与其它变量数据一样;
对象序列化的内容只能包含成员属性;
当序列化对象时,serialize()函数会检查类中是否存在一个魔术方法 __sleep()。如果存在,该方法会先被调用,然后才执行序列化操作。此功能可以用于清理对象,并返回一个包含对象中所有应被序列化的变量名称的数组。
对象的反序列化过程,与其它变量数据一样;
当对象反序列化时,unserialize()函数会检查类中是否存在一个__wakeup()方法。如果存在,则会先调用 __wakeup 方法,预先准备对象需要的资源。 __wakeup() 经常用在反序列化操作中,进行一些初始化操作,例如重新建立数据库连接,或执行其它初始化操作。
__LINE__:当前行号
__FILE__:当前文件
__DIR__:当前目录
__FUNCTION__:当前函数
__CLASS__:当前类
__METHOD__:当前方法
__NAMESPACE__:当前命名空间
class_exists() 检查类是否已定义
method_exists() 检查类的方法是否存在
property_exists() 检查对象或类是否具有该属性
interface_exists() 检查接口是否已被定义
get_class() 返回对象的类名
get_parent_class() 返回对象或类的父类名
PHP中,命名空间用于解决在编写类库或应用程序时名称冲突的问题。
当前项目已经接近尾声,在引用外部公共类(支付类)时,却发现与自己大范围使用过的类冲突,因为外部的类不支持更改,自己大范围使用的类改动不现实,这时最好的解决方式无非是采用命名空间。
命名空间的声明必须是脚本的第一行代码。
命名空间里的函数,类,常量可能会受到命名空间的影响,因此在使用时需要添加前缀为命名空间名。
空间名是类名称的一部分,App\Student。
项目中把冲突的类放在命名空间中,引用时用"空间名\类名"。
使用"/"斜线来分割子文件夹。C:windows/System32/drivers/hosts.text;
使用"\"斜线来分割子命名空间。$obj=new Home\Control\Student();
第一种:简单组合法,在上一个命名空间外另外再定义个命名空间,此时命名空间外的命名空间之间的普通代码可以在其他文件中访问。
第二种:大括号法(像定义类class的大括号一样)此时普通代码在其他文件中不可以使用,会报错。这是可以声明另外的命名空间(匿名空间),匿名空间主要存放全局代码和普通代码。
1)相对文件名形式,如foo.txt。它会被解析为:curdir/foo.txt;
2)相对路径名形式,如subdir/foo.txt。它会被解析为:curdir/subdir/foo.txt;
3)绝对路径名形式,如/main/foot.txt。它会被解析为:/main/foo.txt。
访问命名空间中元素的方式:
1)非限定名称(不带任何前缀)。$obj=new User(),解析为$obj=new current\User();
2)限定名称(带相对空间前缀)。$obj=new Home\User,解析为$obj=new current\Home\User();
3)完全限定名称(从根空间开始)。$obj=new \Home\User(),解析为$obj=new \Home\User();
PHP不支持导入函数或常量,只能导入类名和空间名(两者都可以起别名);
use \App\Home\Controller\Student as Stu; //不冲突的话则不必起别名,不起别名的话默认别名就是最后单词
$obj1=new Stu();//创建App\Home\Controller\Student类对象,不导入起别名的话则$obj1=new App\Home\Controller\Student()创建对象但太过繁琐;
$obj2=new Student(); //创建当前空间中的Student类的对象;
关键字 namespace 可用来显式访问当前命名空间或子命名空间中的元素。它等价于类中的 self 操作符。
魔术常量 __NAMESPACE__ 返回字符串的空间名称。
PDO扩展为PHP访问数据库定义了一个轻量级的、一致性的接口;
PDO作用是统一各种数据库的访问接口,PDO让跨数据库的使用更具亲和力;
PDO是一个第三方的数据库类,默认已经集成到PHP中了。
创建PDO类的对象
描述:创建一个表示数据库连接的 PDO 对象。
语法:PDO::__construct ( string $dsn [, string $username [, string $password]] )
参数:
$dsn,数据源名称或叫做 DSN,包含了请求连接到数据库的信息。通常,一个 DSN 由 PDO 驱动名、紧随其后的冒号、以及具体 PDO 驱动的连接语法组成。
例如:$dsn = “mysql : host=127.0.0.1; port=3306; dbname=db; charset=utf8”
静默模式下,当有错误发生时,不会显示在页面上。
默认报错模式是静默模式,如果想设置警告报错模式,必须使用setAttribute()方法提前设置。
1)静默模式(Silent):PDO::errorCode()和PDO::errorInfo()方法;
$PDOStatement=$pdo->query($sql);
echo "静默模式输出错误
";
echo "错误编号:".$pdo->errorCode();
echo "错误信息:";
print_r($pdo->errorInfo());
2)警告模式(Warning):setAttribute()方法提前设置,setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_WARNING),但此时会暴露自己的相关文件信息。
echo "警告模式输出错误
";
$pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_WARNING);
$PDOStatement=$pdo->query($sql);
3)异常模式(Exception):PDO::Exception类抛出、捕获和处理,setAttribute(PDO::ATTR_ERRMODE,PDO::EXCEPTION);
echo "错误模式输出错误
";
$pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
try{
$sql="select * from student where id=agg";
$PDOStatement=$pdo->query($sql);
}catch(PDOException $e)
{
echo "错误状态码:".$e->getCode();
echo "
错误行号:".$e->getLine();
echo "
错误文件:".$e->getFile();
echo "
错误信息:".$e->getMessage();
}
SQL语句的执行,分成两个阶段:编译和执行。
如果SQL语句,是第1次执行,先编译再执行。编译过程十分复杂,耗用系统资源,相对不太安全。
如果SQL语句是第2次执行,直接从缓存中读取,无疑执行效率是最高的,也是比较安全的,可以有效避免SQL注入安全。
如果第2次以后执行的SQL语句,与第1次SQL语句结构相同,省略编译过程,直接执行即可。
//制作相同结构的SQL语句,把数据部分用占位符代替
$sql="INSERT INTO news(title,content) VALUES(:title,:content)";
$sql="INSERT INTO news(title,content) VALUES(?,?)";
//预编译相同结构的SQL语句(带有占位符的SQL语句)
$PDOStatement=$pdo->prepare($sql);
//给占位符(命令参数)绑定数据
$PDOStatement->bindValue(":title","全栈6期就业班");
$PDOStatement->bindValue(":content","新闻内容");
//给占位符(问号)绑定数据
$PDOStatement->bindValue("1","全栈6期就业班");//1代表第一个"?";
$PDOStatement->bindValue("2","新闻内容");//1代表第一个"";
$PDOStatement->execute();
变量序列化作用:方便存储或传递变量,PHP与第三方应用进行数据交互;
变量序列化:将变量转成可保存或传输的字符串;
变量反序列化:将序列化字符串,还原成原始变量;
对象序列化时,魔术方法__sleep()自动调用,__sleep()完成对象属性清理工作;
对象反序列化时,魔术方法__wakeup()自动调用,__wakeup()完成对象初始化工作。
先提取相同结构的sql部分!(将数据部分,可变的部分去掉)
编译这个相同的结构!将编译结果保存!
再将不同的数据部分进行替换!
执行即可!
如果两个文件定义同样的空间名称,在使用时它会把两个空间中的内容合在一起。因此,命名空间名称不存在冲突问题。
提示:一个文件只定义一个空间,不要定义多个空间名。一个空间中是一个类的定义。
Smarty的目的:就是要使PHP程序员同前端人员分离,
使程序员改变程序的逻辑内容不会影响到前端人员的页面设计,前端人员重新修改页面不会影响到程序的程序逻辑,这在多人合作的项目中显的尤为重要。
smarty常用目录介绍:
目录类别 | 默认目录 | 修改方法 | 查看方法 |
---|---|---|---|
Smarty默认模板目录 | ./templates | $smarty->setTemplateDir() | $smarty->getTemplateDir() |
Smarty默认配置目录 | ./configs | $smarty->setConfigDir() | $smarty->getConfigDir() |
Smarty默认编译目录 | ./templates_c | $smarty->setCompileDir() | $smarty->getCompileDir() |
Smarty默认缓存目录 | ./cache | $smarty->setCacheDir() | $smarty->getCacheDir() |
Smarty默认插件目录 | ./libs/plugins | $smarty->setPluginsDir() | $smarty->getPluginsDir() |
PHP获取秒值:<{time()}>
PHP格式化时间戳:<{date("Y-m-d",time())}>
Smarty获取秒值:<{$smarty.now}>
Smarty格式化时间戳:<{$smarty.now|date_format:'%Y-%m-%d %H:%M:%S'}>
视图文件(模板):纯HTML代码的文件,包括HTML代码、CSS代码、JS代码,扩展名为.html
在Smarty中,默认使用 "{" 和 "}" 作为变量的定界符。但这样,会与CSS、JS中的大括号冲突。
修改左定界符:$smarty->left_delimiter = "string"
修改右定界符:$smarty->right_delimiter = "string"
PHP中的所有变量,都可以在视图文件中使用;
使用 $smarty->assign() 向Smarty模板传递普通变量;
使用 $smarty->display() 显示指定的视图文件;
在Smarty模板中,使用"[ ]"或点"."来访问数组元素;
在Smarty模板中,使用"->"来访问对象的属性和方法。
提示:在视图文件中,一般不会用到对象和资源数据。
(1)Smarty页面请求保留变量
{ $smarty.get} 访问$_GET数组
{ $smarty.post} 访问$_POST数组
{ $smarty.request} 访问$_REQUEST数组
{ $smarty.cookie} 访问$_COOKIE数组
{ $smarty.session} 访问$_SESSION数组
{ $smarty.server} 访问$_SERVER数组
{ $smarty.files} 访问$_FILES数组
(2)访问PHP的预定义常量
语法:{ $smarty.cost.预定义常量}
(3)Smarty时间戳保留变量
语法:{ $smarty.now}
(1)配置文件变量概述
网站上有一些比较简单的变量信息,美工人员可以自行定义并调用。这样可以脱离程序员的依赖,工作比较有主动权。例如:网站名称、ICP备案号、公司地址等。
(2)定义配置文件
配置文件默认目录:./configs
设置配置文件目录:$smarty->setConfigDir()
读取配置文件目录:$smarty->getConfigDir()
配置文件扩展名:.ini或.conf
配置文件中注释:#
语法格式:配置名 = 变量值
变量不带 $ 符号,变量值不带引号
(3)访问Smarty配置文件变量
载入配置文件:{config_load file = “配置文件路径”}
语法格式一:{#配置文件变量名#}
(4)配置文件变量分组
配置文件变量分组:[ ]
载入配置文件分组变量:{config_load file = “配置文件路径” section = “分组名”}
例如:多语言网站
1、foreach语法格式
语法格式1:{foreach $arr as $key=>$value} {/foreach}
语法格式2:{foreach from=$myarr key="mykey" item="myitem"}{/foreach}
提示:foreach可以遍历所有类型的数组,包括:枚举数组、关联数组、混合数组。
2、foreach常用属性应用
@key:输出当前值的索引,可能是整型索引,也可能是字符索引;
@index:当前数组索引,从0开始计算;
@iteration,当前循环的次数,从1开始计算;
@first:当首次循环时,值为true;
@last:当最后一次循环时,值为true;
@total:是整个循环的次数,可以在foreach内部或外部使用;
1、section语法格式
Section循环就是PHP中的for循环。
PHP中的for循环对于foreach来说,有什么特点?
for循环可以控制循环起点,而foreach不可以;如:$i = 1 或 $i = 3
for循环可以指定步长值,而foreach不可以;如:$i += 2 或 $i += 3
for循环可以控制循环次数,而foreach不可以;如:$count = 10 或 $count = 5
1、Smarty变量调节器概述
变量修饰器可以用于格式化变量;
使用修饰器,需要在变量的后面加上|(竖线)并且跟着修饰器名称。
修饰器可能还会有附加的参数以便达到效果。
参数会跟着修饰器名称,用:(冒号)分开。
同时,默认全部PHP函数都可以作为修饰器来使用 (不止下面的),而且修饰器可以被联合使用。
修饰器可以作用于任何类型的变量,数组或者对象。
2、truncate调节器参数及应用
smarty中的truncate调节器,对应PHP的substr()函数或mb_substr()函数。
substr()函数是按字节截取字符串;
MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写;
MVC是一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码;
MVC中,每个模块只做自己范围内的事情,不是自己的事情千万不做;
Model(数据模型)用于处理应用程序数据逻辑的部分。通常模型对象负责在数据库中存取数据。
View(视图)是用于处理数据显示的部分。通常视图是依据模型数据创建的。
Controller(控制器)是应用程序中处理用户交互的部分。通常控制器负责从视图读取数据,控制用户输入,并向模型发送数据。主要负责与客户打交道(GET、POST)、调用Model获取数据、调用View来显示数据。控制器就是调度中心。
一个项目由多个功能模块构成:学生管理、新闻管理、用户管理、产品管理
一个功能只有一个控制器:StudentController、NewsController、UserController、ProductController
一个控制器对应一个模型类:StudentModel、NewsModel、UserModel、ProductModel
一个模型类对应一张数据表操作:student、news、user、product
一个控制器对应多个视图:StudentIndexView.html、StudentAddView.html、StudentEditView.html
栈内存,又称快速内存。主要存储标量数据类型的变量名和变量值;存储对象和资源的变量名和数据地址。代码区主要用来存储各种代码,包括函数代码、方法代码、类代码等。
堆内存主要用来存储数组的元素,对象的属性。对于海量数据的变量来说,值传递和引用传递,引用传递更快。静态区用来存储常量和静态属性。
self代表当前类,parent代表父类。
self和parent可以存在于所有方法(成员方法和静态方法)中。
self用来调用本类的内容,包括:类常量、静态属性、静态方法、成员方法;
parent用来调用父类的内容,包括:类常量、静态属性、静态方法、成员方法;
self和parent都使用范围解析符"::"来调用其它内容。
语法:parent::类常量 | 静态属性 | 静态方法 | 成员方法
子类中重写的方法,要与父类中的方法同名;
子类中重写的方法形参个数,要与父类中的同名方法形参个数一致;
子类中重写的方法类型,要与父类中同名方法类型一致;
子类中重写的方法的访问权限,不能低于父类中同名方法的访问权限;
父类方法权限为public,子类同名方法权限只能是public;
父类方法权限为protected,子类同名方法权限可以是protected和public;
父类方法权限为private,子类无法继承,也无法重写。
注意:对于重写构造方法,就比较特殊,就没有形参个数的要求。
Final关键字修饰的类,就是最终类;
Final关键字修饰的方法,就是最终方法;
最终类:该类只能实例化,不能被继承。该类十分完善了,不需要升级和扩展。
最终方法:该方法可以被继承,但不能重写。该方法十分完善了,不需要重写了。
abstract关键字修饰的类,就是抽象类;
abstract关键字修饰的方法,就是抽象方法;
抽象类:该类不能直接实例化,必须先继承后再实例化。常用在基础类。
抽象方法:方法必须先继承后重写。
抽象方法就是方法的命名规范、命名规则,也可以理解为一种监督机制。
所有的抽象方法都必须重写,少一个都不行。
抽象方法没有方法体,必须在子类重写后,再定义方法体。
如果一类中有一个抽象方法,该类必须是抽象类。
抽象方法权限不能是private,因为要先继承再重写。
抽象方法只能是成员方法,而不能是静态方法。
抽象类中,可以包含其它成员:常量、成员属性、成员方法、静态属性、静态方法。
方法代码是在代码,每个方法都有一个前缀,该前缀就类名,例如:Student::showInfo
如果在没有对象的前提下,如何调用静态方法、成员方法?使用self关键字可以调用。
提示:并不是每个类都必须要创建对象。
self可以调用本类的,除了成员属性外,都可以调用;
parent可以调用父类的,除了成员属性外,都可以调用;
但是,一般情况下,成员属性和成员方法,还是用对象去调用,如果没有对象了,可以使用self;
self主要用类的东西,成员方法一般不建议调用;
PHP 类是单继承,也就是不支持多继承。
当一个类需要多个类的功能时,单继承就无能为力了,为此 PHP 引入了类的接口技术。
多人合作开发项目时,需要规范各个功能的名称,就需要用到接口技术。
接口就是一种标准,一种规范。类的功能实现,按照标准接口实现即可;
接口就是特殊的抽象类。接口可以理解为类的领导者,或者类中方法的目录大纲。
interface关键字定义接口;
implements关键字用来实现接口;
类可以继承类,接口可以继承接口,但是类只能实现(implements)接口。
接口中方法权限必须是public;
接口中方法默认是抽象的,所以不需要在方法名前面加 abstract ;
接口中方法可以是成员方法,也可以是静态方法;
接口中也可以定义常量,但常量不能重写;
类可以实现(implements)多个接口(相当于把多个功能集于一身,如手机实现了小灵通、MP3、MP4的功能);
----index.php //前台入口文件(请求分发)
----admin.php //后台入口文件
----Frame/ //公共类文件目录
------Libs/ //自定义类目录
------Vendor //第三方类目录
----App //应用总目录
------Home/ //前台应用目录
--------Controller/ //控制器目录
--------Model/ //模型目录
--------View/ //视图目录
--------Conf/ //配置目录
------Admin/ //后台应用目录
--------Controller/ //控制器目录
--------Model/ //模型目录
--------View/ //视图目录
--------Conf/ //配置目录
-----Public/ //静态资源目录
--------Home/ //前台静态资源
-----------Images/ //图片目录
-----------CSS/ //CSS目录
-----------JS/ //JS目录
--------Admin/ //后台静态资源
-----------Images/ //图片目录
-----------CSS/ //CSS目录
-----------JS/ //JS目录
框架是基础、架构,各个功能,就是框架内容。例如:学生管理、新闻管理。
框架本身包括:入口文件、配置文件、初始类文件。
每一个功能模块:学生管理,一个功能由MVC三个部分构成。
1)首先建立学生控制器类:StudentController.class.php
2)再建立学生模型类:StudentModel.class.php
3)最后学生视图文件:index.html、add.html、edit.html;
常量在任何地方都可以使用,而变量只能在其作用域下使用;
我们把MVC中常用的目录路径定义成常量,可以简化目录路径的编写。
所谓“常量不能修改”,就是指在一次HTTP请求过程中不变。第2次HTTP请求和第1次没关系。
DIRECTORY_SEPARATOR获取目录分隔符;
框架搭建:入口文件、配置文件、初始类文件
功能模块:控制器文件、模型类文件、视图文件
获取表单提交数据;
判断验证码是否一致;
判断用户名和密码是否和数据库里一致;
更新用户登录IP、登录时间、登录次数;
把用户信息存入session;
用户验证成功跳转页面;
JS没有生成图片的功能,验证码却不能存在前端文件下(不安全)。
视图:是保存在数据库中的select查询,也有人称它为虚拟表。使用视图可以简化查询操作,视图能够从多个数据表中提取数据,并以单个表的形式显示查询结果。这样,就可以把针对多表的数据查询转变为对视图的单表查询。
存储过程:是预编译SQL语句的集合,这些语句存储在一个名称下并作为一个单元来处理。存储过程代替了传统的逐条执行SQL语句的方式。一个存储过程中可包含查询、插入、删除、更新等操作的一系列SQL语句。
触发器:是一种特殊类型的存储过程,当指定表中的数据发生变化时触发器自动生效。触发器会自动执行,对表中的数据进行修改后,会立即激活触发器。触发器能实现比CHECK约束更为复杂的数据完整性约束。
索引:索引是与表或试图关联的磁盘结果,可以加快从表或视图中检索行的速度。索引可以强制表中的行具有唯一性,从而确保表数据的数据完整性。
事务:是由一系列语句构成的逻辑工作单元,事务和存储过程等批处理有一定程度上的相似之处,通常都是为了完成一定业务逻辑而将一条或多条语句封装起来,形成相对独立的一个工作单元。有效地使用事务不但可以提高数据的安全性,而且还可以增强数据的处理效率。
__autoload():
(1)类自动加载的应用场景
在 PHP 5 中,定义一个 __autoload() 系统函数,它会在试图使用尚未被定义的类时自动调用。通过调用此函数,脚本引擎在 PHP 出错失败前有了最后一个机会加载所需的类。
提示:由于__autoload()不太灵活,在以后的版本中它可能被弃用。
(2)__autoload()函数详解
__autoload()函数,需要自已定义该函数的内容;
__autoload()函数,名称是固定的;
__autoload()函数,会在创建类对象时自动调用,并自动传递类名称作参数;
__autoload()函数,需要用户自定义加载指定类文件的代码。
__autoload()函数,参数一般是加载的类名称;
(3)__autoload()函数何时调用?
当试图使用未定义的类时自动调用,使用一个类的几种情况:
使用new关键字创建不存在类的对象时,__autoload()自动调用;例如:$obj = new Student()
当使用静态化方式访问一个不存在的类时,__autoload()自动调用,例如:Student::show();
当继承一个不存在的类时,__autoload()自动调用,例如:class Stu extends Parent{}
当实现一个不存在的接口时,__autoload()自动调用,例如:class Stu implements Inter
(4)类文件的命名规范
一个类要单独定义成一个独立的类文件;
类文件扩展名,要以”.class.php”结尾,是一种约定,不是必须的;
类文件主名,要与类名一致;
例如:Db.class.php、UserController.class.php、UserModel.class.php
spl_autoload_register():
(1)为什么要使用spl_autoload_register()加载类文件?
如果加载的类文件,位于不同的目录中,命名方式也不尽相同,__autoload()就显得不灵活了。
spl_autoload_register()提供了一种更加灵活的方式来实现类的自动加载。
注意:在PHP7中,__autoload()已经被屏弃了。
(2)语法格式:
创建新对象有两种方式:a. 使用new关键字; b. 使用 clone 关键字
描述:当复制完成时,如果定义了 __clone()方法,则新创建的对象(复制生成的对象)中的 __clone()方法会被调用,可用于修改属性的值(如果有必要的话)。
语法:void __clone ( void )
__toString():当对象转成字符串时,__toString()会自动调用;echo $obj;
invoke:当把一个对象当成函数调用时,魔术方法可以自动调用。
常用的设计模式有哪些?
单例设计模式:一个类只能创建一个实例对象,不管用什么办法都无法创建第2个对象;
工厂设计模式:生产不同类对象的工厂;
策略设计模式:定义一组算法,将每个算法都封装起来,并且使它们之间可以互换。
观察者设计模式:定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新。
一私:私有的静态的保存对象的属性。
一私:私有的构造方法,阻止类外new对象。
一私:私有的克隆方法,阻止类外clone对象。
一公:公共的静态的创建对象的方法。
count —计算数组中的单元数目或对象中的属性个数;
int count (mixed$var [, int$mode ] ), 如果 var 不是数组类型或者实现了Countable 接口的对象,将返回 1,有一个例外,如果 var 是NULL 则结果是 0。
不限于WEB开发,主攻后端。
echo date('Y-m-d',strtotime("now")) ."\n";
echo date('Y-m-d',strtotime('+1 day'))."\n";
echo date('Y-m-d',strtotime('+1 week'))."\n";