欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

PHP

程序员文章站 2022-05-26 22:30:03
...

PHP

1. 认识PHP

1.1 什么是PHP

  • PHP 是 “PHP Hypertext Preprocessor(超级文本预处理器)” 的首字母缩略词,动态网页编程语言
  • PHP文件可包含文本,HTML,JavaScript代码和PHP代码
  • PHP代码在服务器上执行,结果以纯HTML形式返回给浏览器
  • PHP文件的默认文件扩展名是“ .php”

1.2 PHP做什么

  • PHP可以生成动态页面内容
  • PHP可以创建,打开,读取,写入,关闭服务器上的文件
  • PHP可以收集表单数据
  • PHP可以发送和接收cookie
  • PHP可以添加,删除,修改您的数据库中的数据
  • PHP可以限制用户访问您的网站上的一些页面
  • PHP可以加密数据

通过PHP,您可以不再输出HTML。您可以输出图像,PDF文件,甚至Flash电影。您还可以输出任意的文本,例如XHTML和XML

1.3 为什么使用PHP

  • PHP可在不同的平台上运行(Windows,Linux,Unix,Mac OS X等)
  • PHP与当前几乎所有的正在被使用的服务器相兼容(Apache,IIS等)
  • PHP提供了广泛的数据库支持
  • PHP是免费的,可从官方的PHP资源下载它: www.php.net
  • PHP易于学习,尽可能高效地运行在服务器端

1.4 架构

  • bs架构: 基于浏览器的,无需安装与升级,性能低安全低
  • cs架构: 需要下载不同的安装包,更新不方便,安全,性能高

总结: 不管是bs架构或者cs架构都会有一个客户端和服务端

1.4 模拟服务器

wampServer这个集成了Apache,mysql,php等服务,先现在然后传统安装,安装完成进入文件bin目录,就可以看见apache,mysql,php三个目录进入Apache目录,然后在进去,找到conf目录,在这个目录下有文件httpd.conf,打开

httpd.conf文件中第178行有: DocumentRoot "D:/SQLUI/wamp/www/",把这里面的路径修改自己代码示例的路径,还有205行<Directory "D:/SQLUI/wamp/www/">这里面的路径保持一样,保存然后重启服务,浏览器中输入127.0.0.1,如果目录中的文件有index开始的文件,就会启动index,如果没有就会展示目录

在浏览器中输入: localhost会展示出You don't have permission to access / on this server也是要在上面的配置文件中的234行Allow from 127.0.0.1下添加Allow from all显示的就会和127.0.0.1显示的页面一样

如果想要展示多个文件,就把httpd.conf的文件注释打开,在468行,然后去当前文件夹的extra文件中的httpd-vhosts.conf这个文件,并且把localhost的文件改成要屏蔽网站的域名

<VirtualHost *:80>
    DocumentRoot "E://./././" //这里的目录一定要和前面的`httpd-vhosts.conf`修改后的路径保持一致
    ServerName jd.com
    ServerAlias www.jd.com
</VirtualHost>

解析: http://www.jd.com/文件,首先解析的是C盘文件的host文件, 使用文件中的127.0.0.1 jd.com实际上找的是127.0.0.1实际上找本机,然而是访问apache修改的的根目录下的文件,如果根目录下的文件httpd.conf下的468行未打开,那么就直接访问修改目录,如果打开就进入当前文件(extra)下的httpd-vhosts.conf文件下,但是httpd-vhosts.conf里面的DocumentRoot这个路径必须和httpd.conf要修改的路径必须一致,访问的就是这里的链接

1.5 资源

客户端去请求服务器,实际上请求的是服务器上面的资源,资源就是一些文件

  • 资源分为两种类型资源
    • 静态资源: 可以直接被浏览器解析的html,css,js,img,video
    • 动态资源: php,jsp,asp

客户端请求服务器,实际上请求的是服务器上面的资源,资源就是一些文件
服务器就会根据我访问的地址进行查找
如果找到的是静态资源就直接响应给浏览器客户端
如果找到的是动态资源,就会在服务器把动态资源转换为静态资源,响应给客户端浏览器

静态资源是客户端浏览器运行的
动态资源是服务器解析运行的

1.6 get与post请求区别

1: get 发送的数据都在地址栏当中,不安全
2:get 发送的数据对数据大小由限制。
3:get 没有请求体
4:post 发送的数据在请求体当中,相对安全
5:post 对请求的数据的大小没有限制
6:post 有一个特殊的请求头 Content-Type:application/x-www-form-urlencoded
7: get 的请求头相对较少,性能稍微要高一些.

2. 基本数据类型

2.1 编写位置

PHP脚本可以放在文档中的任何位置

  • PHP脚本以 <?php开始, 以?>结束

2.2 注释

  • # 单行注释
  • // 单行注释
  • /* */ 多行注释

2.3 输出

  • echo - 输出简单数据类型
    • echo 是一个语言结构,使用的时候可以不用加括号,也可以加上括号: echo 或 echo()。
  • print - 只能输出一个字符串,并始终返回 1
    • print 同样是一个语言结构,可以使用括号,也可以不使用括号: print 或 print()。
  • print_r() - 输出复杂数据类型
  • var_dump() - 输出详细信息,如数组,对象
    • var_dump() 是一个函数。向括号()中间插入变量。这个函数会打印出来数据类型,还会对应显示变量的长度和值。

注意echo比print稍微快一点,因为不返回任何东西

<?php
	// 此处文件默认是PHP代码
	/* 
		多行注释
	*/
	# 单行注释
    // 添加响应头告诉浏览器以"utf-8"的格式解析
    header("content-type:text/html;charset=utf-8");
	echo "Hello World";  // 网页输出Hello World
?>

2.4 变量

变量是存储信息的容器

PHP 变量规则:

  • 变量以 $ 符号开头,其后是变量的名称
  • 变量名称必须以字母或下划线开头
  • 变量名称不能以数字开头
  • 变量名称只能包含字母数字字符和下划线(A-z、0-9 以及 _)
  • 变量名称对大小写敏感($y 与 $Y 是两个不同的变量)

**注释:**PHP 变量名称对大小写敏感!

PHP 没有创建变量的命令。变量会在首次为其赋值时被创建

<?php
	$a = 2;
	$b = 5;
	$c = $a + $b;
	echo $c; // 7

2.5 变量作用域

PHP有四种不同的作用域: local, global, static, parameter

局部和全局作用域局部和全局作用域(loacal global)

在所有函数外部定义的变量,拥有全局作用域。除了函数外,全局变量可以被脚本中的任何部分访问,要在一个函数中访问一个全局变量,需要使用 global 关键字。

<?php
	header("Content-type:text/html;charset=utf-8");
	$a = 5; // 全局作用域
	function myTest() {
        // global $a; // 添加这一句,里层可以访问外层变量a
		$b = 10;
		if(true) {
			// echo "<p>函数内部的if上层输出c的值: $c</p>"; // 报错: 未定义
			echo "<p>函数内部的if上层输出b的值: $b</p>"; // 输出: 10
			// echo "<p>函数内部的if上层输出a的值: $a</p>"; // 报错: 未定义
			$c = 20;
			echo "<p>函数内部的if中输出c的值: $c</p>"; // 输出: 20
			echo "<p>函数内部的if中输出b的值: $b</p>"; // 输出: 10
			// echo "<p>函数内部的if中输出a的值: $a</p>";  // 报错: 未定义
		}
		echo "<p>函数内部的if上层输出c的值: $c</p>"; // 输出: 20
		echo "<p>函数内部的if上层输出b的值: $b</p>"; // 输出: 10
		// echo "<p>函数内部的if上层输出a的值: $a</p>"; // 报错: 未定义
         echo "<p>函数内部的if上层输出a的值: {$GLOBALS['a']}</p>";
		echo $GLOBALS['a'];
	}
	myTest();
	// echo "<p>函数外部输出c的值: $c</p>"; // 报错
	// echo "<p>函数外部输出b的值: $b</p>"; // 报错
	echo "<p>函数外部输出a的值: $a</p>"; // 输出5
?>

由上面可知

  • 函数中的变量不存在变量提升
  • 作用域嵌套,外层和内层不能相互访问
  • 作用域不是块级作用域,是函数作用域
  • 如果内层想要访问外层,必须在内层的函数下面声明global $a

aa 也可以写成GLOBALS[‘a’]

PHP 将所有全局变量存储在一个名为 $GLOBALS[index] 的数组中。 index 保存变量的名称。这个数组可以在函数内部访问,也可以直接用来更新全局变量。

Static作用域: 当一个函数完成时,它的所有变量都会被删除。有时不希望某个局部变量不要被删除。那就在变量前加上static , 然后,每次调用该函数时,该变量将会保留着函数前一次被调用时的值。

<?php
	function myTest() {
		$x = 0; // static  $x = 0;
		echo $x;
		$x++;
	}
	myTest(); 
	myTest(); 
	myTest(); 
	// 没有加static输出: 000
	// 加上static输出: 012
?>

参数作用域: 参数是通过将值传递给函数的局部变量。参数是在参数列表中声明的,作为函数声明的一部分

<?php
function myTest($x){
    echo $x;
}
myTest(name);
?>

2.6 数据类型

整数、浮点数、字符串、布尔、数组、对象、NULL、resource(资源)

  • gettype() : 参数1: 传入一个变量,能够获得变量类型
  • var_dump(): 参数1: 传入一个变量,输出变类型和值 (最常用)
<?php
	$a = 'b';
	$b = 15;
	$c = true;
	echo gettype($a); // string
	echo gettype($b); // integer
	echo gettype($c); // boolean
	echo '<hr />';
	echo var_dump($a); // string 'b' (length=1)
	echo var_dump($b); // int 15
	echo var_dump($c); //boolean true
?>

2.7 整形

	$a = 123; // 整形(十进制)
	$b = -123; // 负数
	$c = 012; // 8进制
	$d = 0xff; // 16进制
	echo var_dump($a); // int  123
	echo var_dump($b); // int -123
	echo var_dump($c); // int 10
	echo var_dump($d); // int 255

2.8 字符串

在PHP语言中声明字符串有三种方式:

  1. 用单引号声明

  2. 用双引号声明

  3. 用字界符声明(需要输入非常大段的字符串时使用)

<?php
	header("Content-type: text/html;charset=utf-8");
// <<<开始然后跟大写英文标记,然后回车输入信息,以大写因为标记结束,结束必须在一行的开始,前面不能有空格
	$a = <<<ABC
		<h1>how are you</h1>
		我在
			这  里
		啊!!!
ABC;
	echo $a;
?>

双引号与单引号有什么区别(面试题)

1.双引号解析变量,但是单引号不解析变量。

2.在双引号里面插入变量,变量后面如果有英文或中文字符,它会把这个字符和变量拼接起来,视为一整个变量。一定要在变量后面接上特殊字符,例如空格,感叹号等分开。

3.如果在双引号里面插变量的时候,后面不想有空格,可以拿大括号将变量包起来。

4.双引号解析转义字符,单引号不解析转义字符。但,单引号能解析’ 和\

5.单引号效率高于双引号,尽可能使用单引号

6.双号和单引号可以互插!!!双引号当中插入单引号,单引号当中插入变量,这个变量会被解析。

7.神奇的字符串拼接胶水——(.)点,用来拼接字符串。

8.我们将定界符声明字符串视为双引号一样的功能来看待。

<?php
	header("content-type: text/html;charset=utf-8");
	// 1. 双引号解析变量,单引号不解析变量
	$name = "张三";
	// 2. 如果变量后面不加空格,那么默认把整体字符串当成变量,缺陷变量名后面有空格
	echo "$name 在吃葡萄"; // 张三 在吃葡萄 双引号解析变量成功
	echo '$name 在吃葡萄'; // $name 再吃葡萄 单引号解析失败
	// 3. 用大括号解决空格
	echo "{$name}在吃葡萄"; // 张三再吃葡萄
	// 4. 解析转义字符
	echo "制\t表符"; // 制 表符   双引号解析转义字符成功
	echo '制\t表符'; // 制\t表符  双引号解析转义字符失败
	// 5. 相互嵌套
	echo "'$name'在吃葡萄"; // '张三'在吃葡萄  ,外双内单解析变量
	echo '"$name"在吃葡萄'; // "$name"在吃葡萄
	// 6. '.'拼接字符串
	echo $name."在吃葡萄"; // 张三在吃葡萄
?>

2.9 浮点型

echo和print分别输出浮点类型

	$a = 123.4567891234;
	print $a; // 123.4567891234
	echo '<br />';
	echo $a; // 123.4567891234
	echo '<br />';
	var_dump($a); // float 123.4567891234

2.10 布尔型

boolean : false / true

<?php
	$a = true;
	print $a; // 1
	echo $a; // 1
	var_dump($a); // boolean true
?>

2.11 数组(Array)

数组就是在一个变量中存储多个值

	$a = array("green","red","blue");
	var_dump($a);
	/*
		array
		  0 => string 'green' (length=5)
		  1 => string 'red' (length=3)
		  2 => string 'blue' (length=4)
	*/
	echo $a; // Array
	echo $a[0]; // green
	var_dump(Array(1));
	/*
		array
		0 => int 1
	*/

2.12 对象(Object)

对象是存储数据和有关如何处理数据的信息的数据类型。

在 PHP 中,必须明确地声明对象。首先我们必须声明对象的类。对此,我们使用 class 关键词。类是包含属性和方法的结构。然后我们在对象类中定义数据类型,然后在该类的实例中使用此数据类型:

<?php
	class Car {
		var $a;
		function f($a = 'red') {
			$this->color = $color;
		}
		function fn(){
			return $this->color;
		}
	};
$obj = new Car();
?>

2.13 NULL(空值)

空在英文里面表示是null,它是代表没有。空(null)不是false,不是0,也不是空格。

主要有以下三空情况会产生空(null)类型:

  1. 通过变量赋值明确指定为变量的值为NULL

  2. 一个变量没有给任何值

  3. 使用函数unset()将变量销毁掉

  • **empty()**可以向括号中间传入一个变量。这个变量的值如果为false或者为null的话,返回true。
  • **isset()**可以向括号中间传入一个或者多个变量,变量与变量间用逗号分开。只要有有一个变量为null,则返回false。否则,则返回true。
  • **unset()**这个函数的功能是毁掉变量。unset(变量)括号中间插入想要毁掉的变量名,这个变量就会被毁掉。
<?php
	$a = null;
	echo $a; 
	echo '<hr/>';
	var_dump($a); // 这两个只会下面一个输出null,但是把下面的代码去掉,上面也会输出null
	echo '<hr/>';
	var_dump($b);// $b是一个不存在的变量,会警告输出null
	$iphone = '乔布斯';
	// unset销毁一个变量
	unset($iphone);
	var_dump($iphone); // 警告输出: null
?>

2.14 资源类型

资源类型打印出来只能够看到一个英文的resource, 资源类型就是文件,电影,电视,音乐,数据库等文件

2.15 判断数据类型

我们使用is_* 系列函数。 is_types这一系列的函数,来进行判断某个东西是不是某个类型。如果是这个类型返回真,不是这个类型返回假。

  • is_int() 是否为整型
  • is_bool() 是否为布尔
  • is_float() 是否是浮点
  • is_string() 是否是字符串
  • is_array() 是否是数组
  • is_object() 是否是对象
  • is_null() 是否为空
  • is_resource() 是否为资源
  • is_scalar() 是否为标量,标量: 布尔值,整数浮点数,字符串
  • is_numeric() 是否为数值类型
  • is_callable() 是否为函数

注:is_types 很好记。is_ 在前后面跟类型即可。

变量:整型(int) 浮点(float)、布尔(bool)、字符串(string)

混合类型: 数组(array)、对象(object)

特殊类型:空(null)、 资源(resouce)、回调(callback)

2.16 自动类型转换(PHP7)

自动类型转换,就是数据类型在某些情况下,自动会变为其他的类型参与运算。自动类型转换的发生时机是:运算和判断的时候某些值会自动进行转换。

下面的情况是布尔值判断时的自动类型转换

1,整型的0为假,其他整型值全为真

2, 浮点的0.0,布尔值的假。小数点前为0,小数点后只要有一个非零的数值即为真。"0.0"转为字符串0.0返回true

3,空字符串为假,只要里面有一个空格都算真。

4,字符串的0,也将其看作是假。其他的都为真

5,空数组也将其视为假,只要里面有一个值,就为真。

6,空也为假

7, 未声明成功的资源也为假

8, null也会转为假

<?php
//布尔变整型参与运算
$fo = true;
$result = $fo + 10;
//$result 结果为整型的11,因为$fo布尔的true变为了1
//如果$fo的值为0
var_dump($result);
//字符串类型,字符串前面是字符串和数字相加=数字本身,字符串变为0,两个字符串相加都会转为0
$str = '419不要爱';
$result = $str + 1;
//结果为420。因为将$str变为了整型的419参与运算
//将419放在字符串中间和结尾试试
var_dump($result);
?>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wzKfRfkL-1586340423656)(C:\Users\a4244\Desktop\img\27.png)]

2.17 强制类型转换(PHP7)

强制类型转换有三种方式:

1.用后面的三个函数可以完成类型转换,intval()、floatval()、strval()

2.变量前加上()里面写上类型,将它转换后赋值给其他变量

3.settype(变量,类型) 直接改变量本身

强制类型转换三种方法

  • (int)$* 、(float)$*、(array)$*,$*、(string)$*、(object)$
  • intval()、floatval()、strval()
  • settype(变量,‘类型’) 会更改原来的数据类型
<?php
	header("Content-type: text/html;charset=utf-8");
	$a = 1.123;
	$b = true;
	$c = "123.45abc";
	$d = "abc123.456abc";
	var_dump(intval($a)); // int 1
	var_dump(intval($b)); // int 1
	var_dump(intval($c)); // int 123
	var_dump(intval($d)); // int 0
	var_dump((int)$a); // int 1
	
	var_dump(floatval($a)); // float 1.123
	var_dump(floatval($b)); // float 1
	var_dump(floatval($c)); // float 123.45
	var_dump(floatval($d)); // float 0
	var_dump((float)$c); // float 123.45
	
	var_dump(strval($a)); // string '1.123' (length=5)
	var_dump(strval($b)); // string '1' (length=1)
	var_dump(strval($c)); //string '123.45abc' (length=9)
	var_dump(strval($d)); // string 'abc123.456abc' (length=13)
	var_dump((string)$d); // string 'abc123.456abc' (length=13)
	
	var_dump((array)$a,$c);
	/*
		array
			0 => float 1.123
			string '123.45abc' (length=9)
	*/
	settype($a,'int');
	var_dump($a); // int 1
?>

以下是强制类型转换时的特点,

1.空转为整型会为整型的0

2.空转为浮点会为浮点的0

3.空转为字符串会为空字符串‘’

4.浮点的123.0转为字符串会为字符串123

5.浮点的123.2转为字符串会为字符串的123.2

6.浮点即使小数点再大,它都会被干掉,会舍掉小数点后面的值

7.如果字符串转为整型的时候,如果数值在前面,会将前面的数值拿出来做为整型的转换值。

8.settype(变量,‘null’); 等价于 unset()一个变量,毁掉变量

9.$目标变量 = (类型)$操作变量 只会改变目标变量的类型,不会改变原变量的类型,Settype是改变原值

2.18 常量define

define(常量名,常量值)

<?php
define('MY_NAME','PHP');
echo MY_NAME; // PHP
echo "我的名字是 'MY_NAME'"; // 我的名字是 'MY_NAME'
echo "我的名字是{MY_NAME}"; // 我的名字是{MY_NAME}
echo "我的名字是 MY_NAME"; // 我的名字是 MY_NAME
echo '我的名字是'.MY_NAME; // 我的名字是PHP
// 也可以这样
$res = constant("MY_NAME");
echo $res;
?>

define和const的区别:

  1. const是一个语言结构;而define是一个函数,可以通过第三个参数来指定是否区分大小写。true表示大小写不敏感,默认为false, 例子:define(‘PI’, 3.14, true);
  2. const简单易读,编译时要比define快很多。
  3. const可在类中使用,用于类成员常量定义,定义后不可修改;define不能在类中使用,可用于全局变量
  4. const是在编译时定义,因此必须处于最顶端的作用区域,不能在函数,循环及if条件中定义;而define是函数,也就是能调用函数的地方都可以定义
  5. const只能用普通的常量名,define常量名中可以有表达式
  6. const定义的常量只能是静态常量,define可以是任意表达式
  7. 此外,系统还为我们准备了一些内置的常量。这些常量都是规定好的

常量与变量的区别:

  1. $ :常量前面没有($)
  2. define: 常量只能用define()函数定义,而不能通过赋值语句
  3. 作用域: 常量可以不用理会变量的作用域而在任何地方定义和访问
  4. 重定义: 常量一旦定义就不能被重新定义或者取消定义
  5. 标量类型:常量的值只能是标量
  6. 命名空间:常量和(全局)变量在不同的名字空间中
常量名 说明
_ LINE_ 当前所在的行
_ FILE_ 当前文件在服务器的路径
_ FUNCTIOIN_ 当前函数名
_ CLASS_ 当前类名
METHOD 当前成员方法名
PHP_OS PHP运行的操作系统
PHP_VERSION 当前PHP的版本
TRAIT Trait 的名字,php5.4新加
DIR 文件所在的目录
NAMESPACE 当前命名空间的名称(区分大小写)
M_PI 圆周率常值
FALSE false
TRUE true
M_E 科学计数e
M_LOG2E 代表log2
E_ERROR 最近的错误处
E_WARNING 最近的警告处
E_PARSE 剖析语法存在问题之处
–METHOD – 类方法名,比如B::test

2.19 defined函数来做安全机制

defined(): 主是是为了防止其他人绕过安全检查文件。

函数:defined(常量)
功能:向函数的括号后面传入常量,如果常量定义了就返回true,否则返回false

【情景模拟】假设,我们的这套在线电子商城的软件需要付钱,检查是否付费是通过对软件授权检查来完成的,而文件version.php中就有检查授权的功能,我们在软件中规定,没有授权检查文件version.php就不能使用这个软件。所有的代码都包含了version.php。并且为了防止有人盗版,我还可以把version.php的代码进行了加密。

我们有两个文件:

1.一个文件中间有版本号,版本声明和授权声明。文件名为version.php

2.一个文件中有具体的业务功能。例如:用户注册、登陆等,文件名为users.php

我们该怎么做呢?——也就是说不包含 version.php文件就不让,执行users.php之后的代码。

函数:include(‘传入文件路径和文件名’)
功能:这个函数的功能是传入指定路径的文件,让PHP包含进来执行
注意:在后面的章节中会专门讲解和实验include

我们来进行实验:version.php文件

<?php

//此处是检查是否是否授权的业务部份代码xxxx
define('AUTH',true);
//略过模拟代码xxx行

?>

users.php

<?php
//尝试将include 'version.php'这一行代码注释后再执行看看,对比结果
include 'version.php';

if(!defined('AUTH')){
   echo '非法!非法!你尝试跳过授权文件';
   exit;
}
//模拟后面用户注册和用户登陆的代码xxx行
echo '用户注册';
?>

实验结果可知:version.php必须要包含 ,不然不会显示后面的echo ‘用户注册’;

2.20 可变变量

可变变量其实就是——已声明的变量前,再上变量符。

<?php
	header("Content-type: text/html;charset=utf-8");
	$a = 'biao';
	$biao = "鼠标";
	echo $$a;  // 鼠标
?>

上面的过程说明:shubiaoshu的值为字符串的'biao'。我在shu前再加上一个$(美元符号),可以理解成为以下的变形过程:

$$shu
${$shu} 分成两块来看
${‘biao’} 把变量$shu解释成了biao
$biao 而$biao也是一个变量对应的值是:鼠标

2.21 外部变量

PHP的外部变量是PHP 在使用过程中规定好的一些变量。这个变量的规定是这样规定的,就这样使用

<!--Demo18.html-->
<!doctype html>
<html lang = "zh-cn">
	<head>
		<title></title>
	</head>
	<body>
		<!--<form action="http://localhost/Demo18.php" method="get">-->
		<form action="http://localhost/Demo18.php" method="post">
			<label>
			用户名: 
				<input type="text" name="uname">
			</label>
			<br />
			<label>密码: 
				<input type="password" name = "pass">
			</label>
			<input type="submit" value="提交">
		</form>
	</body>
</html>

在这段代码的主要意思是把用户和密码,采用get方法,将数据发送给Demo18.php。reg.php想办法接收用户传过来的uname和pass这两个值。

我们得出我们的第一个外部变量:$_GET。$_GET 的主要作用是将得到get传值的数据。

// Demo18.php
<?php
	header("content-type:text/html;charset=utf-8");
/*
	// get请求
	echo $_GET['uname'].'<br />';
	echo $_GET['pass'].'<br />';
*/
/*	
	// post请求
	echo $_POST['uname'].'<br />';
	echo $_POST['pass'].'<br />';
*/
/*
	// request请求,网页get请求
	echo $_REQUEST['uname'].'<br />';
	echo $_REQUEST['pass'].'<br />';
*/
	// request请求,网页POST请求
	echo $_REQUEST['uname'].'<br />';
	echo $_REQUEST['pass'].'<br />';
?>

链接地址: http://localhost/Demo18.php?uname=张三123&pass=1234567

从地址栏可以表单的用户名输入的是张三123,密码是:1234567中间&符号隔开,密码可见,伪类保证安全密码要用POST请求,这样密码就不可见

用了post的请求地址栏: http://localhost/Demo18.php,问好,用户名,密码等信息没有了

$REQUEST来接受数据

  • 网页get请求数据,地址栏: http://localhost/Demo18.php?uname=张三123&pass=1234567
  • 网页post请求数据,地址栏: http://localhost/Demo18.php

通过上面的实验你会发现$_REQUEST即可以接收get传值也可以接收post传值。

另外,我们总结一些外部变量,要求知识点的学习级别:了解含义,默写这个单词的写法和作用。

全局变量名 功能说明
$_COOKIE 得到会话控制中cookie传值
$_SESSION 得到会话控制中session的值
$_FILES 得到文件上传的结果
$_GET 得到get传值的结果
$_POST 得到post传值的结果
$_REQUEST 即能得到get的传值结果,也能得到Post传值的结果

请再记一句话:以上这些变量全是超全局的。

2.22 环境变量

环境变量我们主要用的有$_SERVER和$_ENV两个环境变量 , 不过,$_ENV逐渐被PHP的新版本给废弃了。

我们来了解一些常用的环境变量的键名和值对应的意思:

phpinfo();打印出来了一批乱乱的东西,今天来看看其中的环境变量部份。

键名 含义
$_SERVER[“REQUEST_METHOD”] 请求当前PHP页面的方法
$_SERVER[“REQUEST_URI”] 请求的URI
$_SERVER[“SERVER_SOFTWARE”] 用的是哪一种服务器
$_SERVER[“REMOTE_ADDR”] 客户的IP地址
$_SERVER[“SERVER_ADDR”] 当前服务器的IP地址
$_SERVER[“SCRIPT_FILENAME”] 主前请求文件的路径
$_SERVER[“HTTP_USER_AGENT”] 当前访问这个网址的电脑和浏览器的情况
$_SERVER[“HTTP_REFERER”] 上级来源(用户从哪个地址进入当前网页的)
$_SERVER[“REQUEST_TIME”] 当前的时间

URI 和URL都是网址,但是URL带有了主机地址部份,而URI不带主机地址部份,例如:
http://www.php.cn/abc.php?username=php 上面是一个URL(统一资源定位符),而URI是不带主机和(http://)

协议的部份:abc.php?username=php

2.23 变量引用

<?php
$fo = 5;
//$fo的值为5,将5赋值
$bar = $fo;
//$bar的值原来为5,现在将值改为6
$bar = 6;
//$bar的结果为6
echo $bar.'<br />';
//$fo的结果为5
echo $fo.'<br />';
?>

PHP

<?php
$fo = 5;
//注意,加上了一个&符哟
$bar = &$fo; // 表示$bar 和 $fo 引用了同一个变量,&相当于C语言的指针:$bar = *$fo;
$bar = 6;
//$bar的结果为6
echo $bar.'<br />';
//$fo的结果为6
echo $fo.'<br />';
?>

PHP

3. 运算

3.1 算术运算

算数运算符,就是大家小学所学绝大多数知识:

符号 说明 举例
+ 加号 $x + $y
- 减号 $x - $y
* 乘号,乘以 $x * $y
/ 除号,除以 $x / $y
% 取余也叫取模、求模 $x % $y

3.2 赋值运算符

符号 举例 等价式
+= $x += $y $x = $x + $y
-= $x -= $y $x = $x - $y
*= $x *= $y $x = $x * $y
/= $x /= $y $x = $x / $y
%= $x %= $y $x = $x % $y
.= $x .= $y $x = $x . $y

3.3 自加自减

符号 说明
$x++ 先赋值后加
$x– 先赋值后减
++$x 先加后赋值
–$x 先减后赋值

3.4 比较运算符

说明 符号
大于 >
小于 <
大于等于 >=
小于等于 <=
不等于 !=
等于 ==(赋值是=号,所以==规定为等于)
全等(判断类型等于) ===
全不等(判断类型不等于) !==

3.5 逻辑运算符

举例 说明 详细说明
$x and $y 逻辑与(并且关系) xx 和y 为真则返回真
$x && $y 同上 同上
$x or $y 逻辑或 x,x,y均为false时为假,其他情况全为真
$a || $b 同上 同上
! $x 逻辑非 取反,即true变为false,false变为true
$x xor $y 逻辑异或 相同取false,相异为true

&&与&的区别

  • &&如果前面一句为假,后面的一句就会忽略,不进行计算
  • & 不管前面是真是假,前后都会计算

|| 与 | 的区别

  • || 如果前面是true,则后面的代码直接忽略,不进行计算
  • | 不管前后的返回值,前后都会计算
<?php // 典型的短路与
//如果为defined('AUTH')存在AUTH常量则为true,不访问后面的exit了。如果为false则执行exit
defined('AUTH') or exit('存在安全因素不准访问');
?>

exit 的意思是指在此处停止运行,退出。后面的PHP代码不再执行了。它有两种用法:
1,直接exit; 就是直接退出,终止程序
2,exit(‘提示内容’),退出的时候还给出一段提示内容

3.6 位运算

举例 说明 详细说明
$a & $b And(按位与) 将把 $a 和 $b 中都为 1 的位设为 1。
$a | $b Or(按位或) 将把 $a 和 $b 中任何一个为 1 的位设为 1。
$a ^ $b Xor(按位异或) 将把 $a 和 $b 中一个为 1 另一个为 0 的位设为 1。
~ $a Not(按位取反) 将 $a 中为 0 的位设为 1,反之亦然。
$a << $b 左移 将 $a 中的位向左移动 $b 次(每一次移动都表示“乘以 2”)。
$a >> $b 右移 将 $a 中的位向右移动 $b 次(每一次移动都表示“除以 2”)。

3.7 三元运算符和其他运算符

符号 说明
$x? 真代码段:假代码段 判断是否为真假 ? 真情况 : 假情况;
``(反引号) 反引号中间插代命令,执行系统命令,等价于shell_exec函数
@ 单行抑制错误,把这一行的错误不让它显示出来了,效率低不建议使用
=> 数组下标访问符,array(‘sina’ =>‘新浪’ ,‘sohu’ => ‘搜狐’);
-> 对象访问符,$obj -> username = ‘PHP’;(相当于别的语言的obj.username)
instanceof 判断某个对象是否来自某个类,如果是的返回true,如果不是返回false

3. 控制语句

  • if(判断条件){true:执行语句 }
  • if(判断条件){true:执行语句}else{false: 执行语句}
  • if(判断条件)…else if(判断条件)…else if(判断条件)else{} 条件相互弥补
  • switch(变量) {case 具体值: 执行语句;break;case 具体值: 执行语句;break;…;default:}
  • while(判断条件) {true:执行语句}
  • do{执行语句}while(条件判断) 先执行do,然后while判断
  • for(表达式1; 表达式2;表达式3){true:执行的代码}
    • exit(‘提示语’) : 从当前处停止后续执行 ,程序终止
    • break : 跳出循环或者跳出结构体执行后续代码
    • continue: 跳出此次循环,下次循环继续
  • goto: 使用 goto 来跳出循环
<?php
for($i=0; $i<100; $i++) {
    echo '第'. $i .'周往返北京大连<br />';
    if($i == 17){
            goto end; // 输出到17的位置,直接跳到,end:执行以下代码,不管中间有多少代码
     }
}

end:
echo '集团公司要求停止此项';
?>

**注意:**PHP 中的 goto 有一定限制,目标位置只能位于同一个文件和作用域,也就是说无法跳出一个函数或类方法,也无法跳入到另一个函数。也无法跳入到任何循环或者 switch 结构中。可以跳出循环或者 switch,通常的用法是用 goto 代替多层的 break。

4. 函数

4.1 自定义函数

function 函数名(参数[=值],参数[=值]) {函数功能体; [return 返回值]}

  • 函数以function开始
  • function后面接空格,空格后跟函数名
  • 函数名与变量名的规则基本一样,但是不同的是: 函数名不区分大小写
  • 所谓的参数其实就是变量
  • 函数名后跟括号,括号内跟参数, 函数体的参数若是定义了,未传参数,代码会报错
  • 如果有参数的话,参数后可以接(=)等号,等号接默认值 可选,如果是有默认值,函数可以不用传参,传参则会覆盖默认值,写参数时,无默认值的参数写在前面
  • 函数后的参数变量,主要功能是把函数体外的变量值,传入函数体内来使用,函数体的变量和函数体外的变量通常是两个不同的变量。
  • 函数中的具体功能(功能体)用大括号括起来,代表这是一个函数的功能区间
  • 函数可以有返回值也可以没有返回值,
  • return后接空格,空格后接返回值,若有return,return后的代码均不执行
  • 函数的执行没有顺序关系,可以在定义处之前的位置调用
  • 函数不能被定义两次,即函数不能被重载

4.2 回调函数

回调函数,可以配合匿名函数和变量函数实现更加优美、复杂的一种函数结构。

回调函数,就是在处理一个功能的时候,我让让这个功能自定义能力再强一些,我准许调用这个函数的时候,还可以传入一个函数配合、协助进行处理。

4.3 变量函数

可变函数仅仅是可变变量的一个变种、变形表达。

可变变量

<?php 
$hello = 'world';
$world = '你好';
//输出的结果为:你好
echo $$hello; 
?>

变量函数

<?php
function demo(){
    echo '天王盖地虎';
}
function test(){
    echo '小鸡炖蘑菇';
}
$fu = 'demo';
//把$fu变为了demo,把demo后加上了一个括号,就执行函数了
$fu();
//把$fu的值改为test字符串再试试?
?>

4.4 匿名函数

  • 所谓匿名,就是没有名字。
  • 匿名函数,也就是没有函数名的函数。
  • 匿名函数的第一种用法,直接把赋数赋值给变量,调用变量即为调用函数。
  • 匿名函数的写法比较灵活。

变量式匿名函数

<?php
$greet = function($name) // 匿名函数
{
 echo $name.',你好';
};
$greet('明天');
$greet('PHP');
?>

回调式匿名函数

<?php
function woziji($one,$two,$func){
       //我规定:检查$func是否是函数,如果不是函数停止执行本段代码,返回false
       if(!is_callable($func)){
               return false;
       }
       //我把$one、$two相加,再把$one和$two传入$func这个函数中处理一次
       //$func是一个变量函数,参见变量函数这一章
       echo $one + $two + $func($one,$two);
}
woziji(20,30,function( $foo , $bar){ // 回调式匿名函数
               $result = ($foo+$bar)*2;
               return $result;
           }
);
?>

4.5 内部函数

内部函数,是指在函数内部又声明了一个函数。

注意事项:

1.内部函数名,不能是已存在的函数名

2.假设在函数a里面定义了一个内部函数,不能定用两次函数a。

<?php
function foo()
{
 echo '我是函数foo哟,调一下我才会执行定义函数bar的过程<br />';
 function bar()
 {
 echo '在foo函数内部有个函数叫bar函数<br />';
 }
}

//现在还不能调用bar()函数,因为它还不存在
// bar();

foo();

//现在可以调用bar()函数了,因为foo()函数的执行使得bar()函数变为已定义的函数
bar();

//再调一次foo()看看是不是会报错?
// foo();
?>
  • foo() 调用两次会出错,连续,不间隔也会出错
  • 如果不调用foo()函数,就无法执行内部函数bar,因为bar是在foo内部,只要foo运行了,bar可以运行无数次

4.6 变量作用域

  • 函数定义时后括号里面接的变量是形式上的参数(形参),与函数体外的变量没有任何关系。仅仅是在函数内部执行

  • 函数内声明的变量也与函数外的变量没关系。

但是,我们实际的处理情况中会遇到这样的一个情况:

  • 我想在函数体内定义的变量在函数体外用

  • 我想把函数体外的变量拿到函数体内来使用

这个时候我们就需要用到超全局变量

全局变量名 功能说明
$_COOKIE 得到会话控制中cookie传值
$_SESSION 得到会话控制中session的值
$_FILES 得到文件上传的结果
$_GET 得到get传值的结果
$_POST 得到post传值的结果
$_REQUEST 即能得到get的传值结果,也能得到Post传值的结果
<?php
header("Content-type: text/html;charset=utf-8");
$hello = 10;
echo $GLOBALS['hello'].'<br />'; // 10

$GLOBALS['hello'] = '我爱你';
echo $hello; // 我爱你
?>

你会发现变量名是等价于GLOBALS[‘变量名’] 。所有的变量都放到了GLOBALSGLOBALS里面了。而GLOBALS也是全局的

将函数体内的变量(局部变量)在函数外部使用。也可以让函数外的变量到函数里面来使用

  • 通过$GLOBLAS来读取外部变量
  • 通过$GLOBLAS在函数内修改变量
  • 通过$GLOBLAS,在函数内创建全局变量 ,需要访问,必须调用函数先
<?php
header('Content-type: text/html; charset=utf-8');
$hongniu = '我是一个兵,来自老百姓';
function test(){
   echo '执行了函数test哟<br />'; // 1. 执行了函数test哟
   //调用test()函数,将通过$GLOBALS['hongniu'],把$hongniu的值改变掉

	$GLOBALS['hongniu'] = '帮助别人很快乐'; 
	echo $GLOBALS['hongniu'].'<br/>';  // 2. 帮助别人很快乐;注意$hongniu访问不了

	$GLOBALS['a'] = '123456';  // 局部变量声明全局变量,有个限制,就是要调用这函数才能访问
}
test(); 
echo $hongniu.'<br/>'; // 3. 帮助别人很快乐
echo $a; // 123456
?>

4.7 参数的引用

变量引用

<?php
$a = 10;
$b = &$a; // $b = *$a
$a = 100;
echo $a.'---------'.$b;  // 100
?>

变量引用有讲述,是指变量aa和b指向到了同一个存储位置,来存值。而函数的参数引用,也是这个意思,将形参和实参指向到同一个位置。如果形参在函数体内发生变化,那么实参的值也发生变化。我们来通过实验来看看:

<?php
$foo = 100;
//注意:在$n前面加上了&符
function demo(&$n){ // 形参与全局变量指向同一地址引用
       $n = 10;
       return $n + $n;
}
echo  demo($foo).'<br />';
//你会发生$foo的值变为了10
echo $foo;
?>

4.8 递归函数

自己调用自己, 递归在实际工作中主要是用在:文件和文件夹操作的时候有使用到。

1.代码是从上到下执行的,所有代码没有exit等停止符,函数必须执行完。

2.如果函数从函数A跳至函数B后,必须把函数B执行完成再执行函数A余下的代码。

3.递归函数必须要能执行完有结束条件,不然函数就会限入死循环。函数会永远的自我执行下去。

4.9 静态变量

函数内声明:static $a = 0;

静态变量的特点是:声明一个静态变量,第二次调用函数的时候,静态变量不会再初始化变量,会在原值的基础上读取执行。

5.10 文件包含函数

在实际开发中,常常需要把程序中的公用代码放到一个文件中,使用这些代码的文件只需要包含这个文件即可。这种方法有助于提高代码的重用性,给代码的编写与维护带来很大的便利。在PHP中, 有require、require_once、include、include- once四种方法包含一个文件。

函数 包含失败 特点
Inlcude 返回一条警告 文件继续向下执行。通常用于动态包含
Require 一个致命的错 代码就不会继续向下执行。通常包含极为重要的文件,整个代码甭想执行
Include_once 返回一条警告 除了原有include的功能以外,它还会做once检测,如果文件曾经已经被被包含过,不再包含
Require_once 一个致命的错 除了原的功能一外,会做一次once检测,防止文件反复被包含
<?php
//functions.php文件
function demo(){ echo 'aaaa';}
function test(){ echo 'cccdddd';}
?>
<?php
//user.php
include 'functions.php';
//可以直接调用
demo();
test();
?>

require和include都是导入模块,如果include导入不存在的模块,会警告并且会继续执行后面的代码,但是require会直接报错,后面代码就无法执行

  • include_once: 检测是否重复包含一个模块文件,如果包含在重复包含一次,意思是只会执行一次., 而include_once不报错的原因是因为:他检测了functions.php曾经包含过,不再进行包含引入了。
  • include: 不管有没有包含,会再执行一遍,重复包含会报错

5.11 获取时间信息

  • 设置时区

    • date_default_timezone_get()
    • date_default_timezone_set()
  • 获取时间戳

    • time()
  • date函数用于将一个时间进行格式化输出,以方便时间的显示或存储

string date ( string $forrnat [, int $tirnestamp] )

$timestamp是一个时间戳,函数将这个时间戳按$format规定的格式输出 , 如果$timestamp没有输入值,则默认为当前的时间

$format是一个时间输出格式的字符串,需要使用规定的字符构造输出格式。 API,date查询

<?php
	header('Content-type: text/html;charset=utf-8');
	echo date_default_timezone_get().'<br/>'; // 获取时区: UTC

	// 定义时区常量: Asia 亚洲上海
	define('TIME_ZH','Asia/shanghai');
	date_default_timezone_set(TIME_ZH);
	echo date('Y-m-d H:i:s').'<br/>'; // 2020-02-28 11:06:31

	echo time(); //获取当前nuix事件戳: 1582859258
?>
  • getdate用来获取当前系统的时间,或者获得一个时间戳的具体含义。时间戳是一个长整数

array getdate ([ int $timestamp = time() ] )

函数的返回值是一个根据timestamp得到的包含有时间信息的数组。如果没有参数,则会返回当前的时间。getdate返回的数组,键名包括时间和日期的完整信息。

<?php
    echo getdate().'<br/>'; // Array
	print_r(getdate()); // print_r()输出复杂数据类型
	echo '<br/>';
	/* 
	Array(
		[seconds] => 1 // 秒
		[minutes] => 21  // 分
		[hours] => 11  // 时
		[mday] => 28   // 日
		[wday] => 5  // 星期中的第几天
		[mon] => 2  // 月
		[year] => 2020  // 年
		[yday] => 58  // 年中第几天
		[weekday] => Friday  // 星期
		[month] => February  // 月份
		[0] => 1582860112 // 事件戳
	)
	*/
	$timer = getdate();
	echo $timer['minutes'].'<br/>';
?>

5.12 日期验证函数

checkdate可以判断一个输出的日期是否有效 ,在实际的工作中,我们需要经常用于检测常用于用户提交表单的数据验证。例如:验证用户输入的时间是否正确。

函数的语法格式如下:

bool checkdate ( int $month , int $day , int $year )

// 判断2020年2月有没有29,30日
var_dump(checkdate(2,29,2020));  // boolean true
var_dump(checkdate(2,30,2020));  // boolean false

5.13 指定时间

mktime()简称:make time.创建时间,可以对一个日期和时间获得一个本地化时间戳

int mktime (int $hour [, int $minute [, int $second [, int $month [, int day[.intday [. intyear [, int $.is_dstl.l } ] ] 31 )

函数的参数分别表示:时、分、秒、月、日、年、是否为夏令时

<?php
	// 2020-2-27 11:38:25 到1970-1-1 0:0:0的时间毫秒差
	echo mktime(11,38,25,2,27,2020).'<br/>';  // 1582774705
	echo date("Y-m-d h:i:s")."<br/>"; // 2020-02-28 11:02:53
	// 参数1: 时间格式,mktime(时,分,秒,现在年,现在月,现在日)
	echo date("Y-m-d h:i:s",mktime(10,1,59,date('m'),date('d'),date('Y'))).'<br />';
	// 2020-02-28 10:02:59
	echo date("Y-m-d h:i:s",mktime(11,1,59,date('m'),date('d'),date('Y'))).'<br/>';
	// 2020-02-28 11:02:59
?>

strtotime() 它能将将英文文本的日期时间描述解析为 Unix 时间戳。

int strtotime ( string $time [, int $now = time() ] )

  • 参数1: 传入一个字符串的时间

  • 参数2: 可选参数为是否传入unix时间戳,如果不传则是当前的unix时间戳。

//now为现在的当前时间
echo strtotime("now")."<br />";  // 1582862251
//2000年9月10日
echo strtotime("10 September 2000")."<br />"; // 968515200
//当前时间加一天
echo strtotime("+1 day")."<br />"; // 1582948651
//当前时间加一周
echo strtotime("+1 week")."<br />"; // 1583467051
//当前时间加一周2天4小时2秒
echo strtotime("+1 week 2 days 4 hours 2 seconds")."<br />"; // 1583654253
//下一个星期四
echo strtotime("next Thursday")."<br />";  // 1583337600
//上一个星期一
echo strtotime("last Monday")."<br />"; // 1582473600

5.14 程序执行时间

microtime()这个函数,能够返回当前 Unix 时间戳和微秒数。

mixed microtime ([ bool $get_as_float ] )

如果你传入true的话,将会返回一个浮点类型的时间,这样方便参与运算。

<?php
//开始时间
$time_start = microtime(true);
//循环一万次
for($i = 0 ; $i < 10000 ; $i++){
}
//结整时间
$time_end = microtime(true);
//相减得到运行时间
$time = $time_end - $time_start;
echo "这个脚本执行的时间为 $time seconds\n"; // 0.00019502639770508 seconds
?>

mktime() 生成一个昨天的时间,再用strtotime() 生成一个昨天的时间,对比两个函数认的效率高

$a = microtime(true);
	// 2020-02-27 12:14:18
	echo date('Y-m-d h:i:s',mktime(date('h'),date('i'),date('s'),date('m'),date('d')-1,date('Y'))).'<br/>';
	$b = microtime(true);

	$aa = microtime(true);
	// 2020-02-27 12:14:18
	echo strtotime("last day").'<br />';
	$bb = microtime(true);
	
	$c = $a - $b;
	$cc = $aa - $bb;
	
	if($c > $cc) {
		echo 'microtime 大于 strtitime执行时间';
	}else {
		echo 'microtime 小于 strtitime执行时间';
		// microtime 小于 strtitime执行时间
	}

5. 数组定义

5.1 基本操作

  • 数组可以存入多个不同类型的数据,是一个复合数据类型。
  • 数组的英文是array,学下最简单的数组声明。
  • 数组下标不一定从0,开始
  • 索引数组若不强制声明他的下标,他的下标是从0开始的。(我们的第一个数组的值:只有不断努力才能博得未来。这个值的下标为0)
  • 向索引数组中增加元素用: 数组变量名[]、数组变量名[键值]这两种方式来增加元素
  • 键值的增长规则与之前的规则一样。都是最大值加1的原则
  • 使用unset删除变量的方式来删除数组里面的值。
  • 删除了中间的值,并不会让后面的下标向前自动移动。而是原来的值为多少就为多少
  • 删除掉其中的某个值,新加入的值不会替换掉原来的位置,依然遵循最大值加1的原则
  • 用变量名[键] = 新值。就把数组中的值定的值修改了
<?php
	header('Content-type: text/html;charset=utf-8');
	$arr = array(1,1.5,true,'您好啊');
	var_dump($arr);
	/*
	数组 
  0 =>  整数 1 
  1 =>  浮点数 1.5 
  2 =>  布尔值 true 
  3 =>  字符串 '您好啊'  (length = 9)
	*/
	$arr01 = array(2=>'Hello',10 => 'NoAlike','PHP',19=>'Good','love');
	var_dump($arr01);
	/*
array
  2 => string 'Hello' (length=5)
  10 => string 'NoAlike' (length=7)
  11 => string 'PHP' (length=3)
  19 => string 'Good' (length=4)
  20 => string 'love' (length=4)
  */
	$minren = array('杨幂','王珞丹','刘亦菲', '黄圣依');
	$minren[] = '范冰冰';
	$minren[100] = '范爷';
	$minren[] = '李晨';
	var_dump($minren);
	/*
	array
	  0 => string '杨幂' (length=6)
	  1 => string '王珞丹' (length=9)
	  2 => string '刘亦菲' (length=9)
	  3 => string '黄圣依' (length=9)
	  4 => string '范冰冰' (length=9)
	  100 => string '范爷' (length=6)
	  101 => string '李晨' (length=6)
	*/
	unset($minren[3]);
	var_dump($minren);
	/*
array
  0 => string '杨幂' (length=6)
  1 => string '王珞丹' (length=9)
  2 => string '刘亦菲' (length=9)
  4 => string '范冰冰' (length=9)
  100 => string '范爷' (length=6)
  101 => string '李晨' (length=6)
	*/
?>

5.2 其他声明方式

**1. 直接用之前未声明的变量,用变量名后面接中括号的方式声明数组 **

<?php
    //直接写一个变量后面加上中括号,声明变量
    $qi[] = '可口可乐';
    $qi[10] ='百事可乐';
    var_dump($qi);
/*
array
  0 => string '可口可乐' (length=12)
  10 => string '百事可乐' (length=12)
*/
?>

**2. 每次用array()写的太麻烦了,还可以不用写array哟,更简单 **

<?php // php版本5.4以后有的
$qi = ['可口可乐',10 => '百事可乐']
    var_dump($qi);
/*
array
  0 => string '可口可乐' (length=12)
  10 => string '百事可乐' (length=12)
*/
?>

5.3 关联数组

  • 声明关联数组是 键名 => 值
  • 在关联数组可以有索引数组的元素
  • 关联数组中的索引数组的元素后再声明了无下标的元素,依然是最大值+1原则
	$qi[] = '可口可乐';
    $qi[10] ='百事可乐';
    var_dump($qi);
	$arr02 = array(
		'hello' => '超级玛丽',
		'住哪' => '蘑菇岛',
		'年龄' => '30岁',
		100 => '...继续中',
		'小矮人',
	);
	var_dump($arr02);
	/*
array
  'hello' => string '超级玛丽' (length=12)
  '住哪' => string '蘑菇岛' (length=9)
  '年龄' => string '30岁' (length=5)
  100 => string '...继续中' (length=12)
  101 => string '小矮人' (length=9)
	*/

5.4 数组计算

count — 计算数组中的单元数目,或对象中的属性个数,可以用于for循环

int count ( array,mode)

  • mode

    • 0 - 默认。不对多维数组中的所有元素进行计数
    • 1 - 递归地计数数组中元素的数目(计算多维数组中的所有元素)

对于数组,返回其元素的个数,对于其他值,返回 1。如果参数是变量而变量没有定义,则返回 0。

如果 mode 被设置为 COUNT_RECURSIVE(或 1),则会递归底计算多维数组中的数组的元素个数。

<?php
	$a[0] = 2;
	$a[1] = 3;
	$a[2] = 5;
	echo count($a).'<br/>'; // 3
	for($i = 0; $i < count($a); $i++) {
		echo $a[$i].' , ';  // 2,3,5,
	};

	$b[0]  = '迪奥和奥迪我都爱';
	$b[5]  = '努力开创未来';
	$b[10] = '为了未来而努力';
	echo count($b).'<br/>'; // 3
	
	$c = array(
		1 => array(
			1 => 'HTML',
			2 => 'CSS',
			3 => 'JS',
		),
		2 => array(
			1 => 'Java',
			2 => 'JavaWeb',
			3 => 'JSON',
		),
		3 => array(
			1 => '汇编',
			2 => 'C',
			3 => 'C++',
		),
		4 => array(
			1 => 'python',
		),
	);
	echo count($c,0).'<br />'; // 4 浅度,下面深度
	echo count($c,1).'<br />'; // 14 = 大数组4个 + 大数组中的小数组10个
?>

5.5 foreach遍历数组

for循环可以遍历连续下标数组,但是遍历不了关联数组和下标不联系的数组,会乱码警告

这时候亦可用foreach循环

foreach( 要循环的数组变量 as [键变量 =>] 值变量){ }

<?php
header('Content-type: text/html;charset=utf-8');
$arr01= array('李某',3 => '18','人妖');
foreach($arr01 as $key => $val) {
	echo $key.'-------'.$val.',';
	// 0 -------李某,3 ------- 18,4 -------人妖
}
// 二维数组
$arr02 = array(
       0 => array(
           '中国' => 'china',
           '美国' => 'usa',
           '德国' => ' Germany',
       ),
       1 => array(
           '湖北' => 'hubei',
           '河北' => 'hebei',
           '山东' => 'shandong',
           '山西' => 'sanxi',
       ),
);
echo '<br/>';
foreach($arr02 as $val){
	foreach($val as $k => $v) {
		echo $k.'-------'.$v.',';
		// 中国-------china,美国-------usa,德国------- Germany,
		// 湖北-------hubei,河北-------hebei,山东-------shandong,山西-------sanxi,
	}
	echo '<br />';
}
echo '<br />';
// 三维
$arr03=array(
	'教学部'=>array(
		 array('李某','18','人妖'),
		 array('高某','20','男'),
		 array('张某','21','妖人'),
	 ),
	 '宣传部'=>array(
		 array('李某','18','人妖'),
		 array('高某','20','男'),
		 array('张某','21','妖人'),
	 ),
	 '财务部'=>array(
		 array('李某','18','人妖'),
		 array('高某','20','男'),
		 array('张某','21','妖人'),
	 ),
);
foreach($arr03 as $ke => $val) {
	echo $ke.'<br/>';
	foreach($val as $value){
		foreach($value as $k => $v){
			// var_dump($value);
			// var_dump($k);
			echo "-----".$k.'-----'.$v.'<br />';
		}
		echo ' <br/>';
	}
	echo ' <br/>';
}
?>

5.6 list、each函数遍历数组

list ( mixed $变量1 [, mixed $变量n ] )

它的功能:将索引数组下标为0的对应变量1,下标1的对应变量2,依此类推。如果是没有的变量就会警告继续运行, 和JS里面对象解构赋值一样,

<?php
	header("Content-type: text/html;charset=utf-8");
	list($one,$two,$three) = array('张三','李四','王五');
	// 单引号不解析变量
	echo '$one----'.$one.'<br />';  // $one----张三
	echo '$two----'.$two.'<br />';  // $two----李四
	echo '$three----'.$three.'<br />';  // $three----王五

	list($one1,$two1,$three1) = array('芹芹',2=>'勤勤','琴琴');
	echo '$one1----'.$one1.'<br />';  // $one1----芹芹
	echo '$two1----'.$two1.'<br />';  
	echo '$three1----'.$three1.'<br />';  // $ three1 ----勤勤
?>

1.因为是一一对应原则,$one1找到标为0的数组元素,$two1找不到下标为1的数组元素,$three找到了下标为2的数组元素

3.在list($one1, $two1, $three1),我只写了三个变量。对应完成,而后面的’琴琴’对应的是4

array each ( array &$array )

传入一个数组。它会将其中的一个元素拆为个新数组。每次执行这样操作一个元素。执行一次先后移动一次,同样的方式操作下一个数组元素。执行到最后,返回false。

<?php
	header('Content-type: text/html;charset=utf-8');
	$kongjie=array(
	   'gao'=>'穿黑衣服的',
	   'shou'=>'退特别长特别细',
	   'mei'=>'好白',
	   'pl'=>'五官端正',
	   'type'=>'那就是女神',
	   '我是吊丝不敢跟女神搭讪'
   );
	echo each($kongjie); // Array
	var_dump(each($kongjie)); // 在执行一次,就会读取分解第二个
?>
/*
array
  1 => string '穿黑衣服的' (length=15)
  'value' => string '穿黑衣服的' (length=15)
  0 => string 'gao' (length=3)
  'key' => string 'gao' (length=3)    
*/

总结

  • 读取了$kongjie中的第一个元素,将第一个元素(‘gao’=>‘穿黑衣服的’)分解开了
  • 分解后第一个元素变成了一个新数组。
  • 在新数组里面,将原值(穿黑衣服的)放了索引下标1里面,同时放到了关联下标value里面
  • 在新数组里面,将原键(gao),放到了关联下标key里面,放到了索引下标0里面。

PHP

list和each配合

list(key,key,value) = each($array);

<?php
	header('Content-type: text/html;charset=utf-8');
	$arr = array(
		'name'=> 'nice',
		'age'=> 18,
		'adree' => '九江',
		);
	// list($key,$value) = each($arr);
	// echo $key.'---'.$value.'<br />';
	while(list($key,$value) = each($arr)){
		echo $key. '-----' .$value .'<br />';
		/*
			name-----nice
			age-----18
			adree-----九江
		*/
	}
?>

总结:

  • each 把变量拆成了4个元素
  • 而list把0 =>gao 赋值给了变量$key
  • list把1 => 穿黑衣服的 赋值给了变量 $value
  • 如果一直调用,调用完就会返回false
  • 可以通过each和list配合实现foreach一样的效果。

5.7 其他API

  • in_array(‘key’,arr) 判断数组中是否存在某个元素
  • array_key_exists(‘key’,arr) 检测数组是否存在key

6. 正则

6.1 定界符

定界符,就是定一个边界,边界已内的就是正则表达示,不能用a-zA-Z0-9\ 其他的都可以用。必须成对出现,有开始就有结束

例子 说明
/中间写正则/ 正确
中间写正则 正确
%中间写正则% 正确
中间写正则 正确
@中间写正则@ 正确
(中间写正则) 错误
A中间写正则A 错误

6.2 原子

原子是正则表达示里面的最小单位,原子说白了就是需要匹配的内容。一个成立的正则表达示当中必须最少要有一个原子。

所有可见不可见的字符就是原子

说明:我们见到的空格、回车、换行、0-9、A-Za-z、中文、标点符号、特殊符号全为原子

preg_match

int preg_match ( string $正则 , string KaTeX parse error: Expected 'EOF', got '&' at position 14: 字符串 [, array &̲结果] )

功能:根据$正则变量,匹配$字符串变量。如果存在则返回匹配的个数,把匹配到的结果放到$结果变量里。如果没有匹配到结果返回0。

<?php
	header('content-type: text/html;charset=utf-8');
	$regexp = '/a/';
	$str = 'sahdjsahdjkklj';
	if(preg_match($regexp,$str,$match)){
		echo '匹配了';
		var_dump($match);
	}else {
		echo '再接再厉';
	}
/*
匹配了
array
  0 => string 'a' (length=1)
*/
?>
原子 说明
\d 匹配一个0-9
\D 除了0-9以外的所有字符
\w a-zA-Z0-9_
\W 除了0-9A-Za-z_以外的所有字符
\s 匹配所有空白字符\n \t \r 空格
\S 匹配所有非空白字符
[ ] 指定范围的原子
^ 相当于非,对条件进行否定,不匹配该居间的字符

6.3 元字符

上面的原子只能匹配一个字符,想要匹配一堆字符只能使用元字符, 需要借助元字符来帮我们修饰原子,实现更多的功能。

字符 功能说明
* 是代表匹配前面的一个原子,匹配0次或者任意多次前面的字符。
+ 匹配一次或多次一个字符
? 前面的字符匹配一次或者没有
. 更标准一些应该把点算作原子。匹配除了\n以外的所有字符
| 或者。注:它的优先级最低了。
^ 必须要以抑扬符之后的字符串开始
$ 必须要以$之前的字符结尾
\b 词边界
\B 非边界
{m} 有且只能出现m次
{n,m} 可以出现n到m次
{m,} 至少m次,最大次数不限制
() 改变优先级或者将某个字符串视为一个整体,匹配到的数据取出来也可以使用它
$zz = '/gg.+gg/'; 
// 中间点: 匹配一个字符\n除外
// 中间+: 匹配多个字符
// 结果: gg(任意多个字符,\n除外)gg

$zz = '/ABC\d?ABC/'
// \d: 0-9一个数字
// ? : 匹配一次或没有
// 结果: ABC(中间的数字只能出现一次要么不出现)ABC

$zz = '/\w*/';
// *: 匹配0次以上
// \w: A-Za-z0-9_: 只要有这个就正确不管多少次

$zz = '/abc|bcd/';
// | : 或者
// 只要字符串中有abc或者bcd就可以,不管在哪,但要连续

$zz = '/^猪哥好帅\w+/';
// ^: 以'猪哥好帅'字符串开始
// \w+: 匹配a-zA-Z0-9_,匹配一次以上

$zz = '/\d+努力$/';
// $: 以努力结尾
// \d+: 0-9 匹配一次以上 

$zz = '/\w+\b/';
// \w+: 匹配: 0-9a-zA-Z_,多次
// \b: 以空格分隔单词,单词开始以'\w'匹配
// 匹配不成功: "$sad $hja$"; \w不在词的边界

$zz = '/\w+\B/';
// \B: 以空格分隔单词,单词除去首尾字符,中间匹配\w
// 匹配不成功: "A----B B+++++A",\w在词的边界

$zz = '/喝\d{3}酒/';
// \d{3}: 匹配'\d'3次

$zz = '/喝\d{3,9}酒/'
// \d{3,9}: 匹配'\d'3-9次

$zz = '/喝\d{3,}酒/';
// \d{3,}: 至少3次,最多不限制

6.4 模式修正字符

用法:

/ 正则表达示/模式匹配符

模式匹配符 功能
i 模式中的字符将同时匹配大小写字母.
m 字符串视为多行
s 将字符串视为单行,换行符作为普通字符.
x 将模式中的空白忽略.#后面的字符全部忽略
A 强制仅从目标字符串的开头开始匹配.
D 模式中的美元元字符仅匹配目标字符串的结尾.
U 匹配最近的字符串.
$zz = '/ABC/i';
// '/ABC/'只要字符串里面有abc就可以了
// i : 不区分大小写

$zz = '/^a\d+/m';
// /^a\d+/: 以a开始,后面匹配\d
// m: 如果字符串换行,每一行尅是都进行匹配

$zz = '/新的未来.+\d+/s';
// 字符串内容之一: 新的未来(\n除外,其他都可以)(0-9,1次以上)
// s: 多行当成一行来识别,\n就不存在了

$zz = '/a b c /x';
// x: 忽略空白字符,匹配abc

preg_replace("/{(\w+) (\d+), (\d+)}/i","\$2","{April 15, 2003}")
// 正则,替换项,查找字符串
// 替换项: \$1-> (\w+), \$2 -> (\d+), \$3 -> (\d+)
// 替换时: /{(\w+) (\d+), (\d+)}/i -> /{(\w+) (\$2), (\d+)}/i,将匹配项提取出来

$zz = '/<div>.*<\/div>/U';
// 正则表达式有多少匹配多少,但是末尾加上U,就是匹配最前面的一个

$zz = '/this/A';// 以this开始,和^元子符,不是原子符

6.5 常用正则

我们常用的正则函数有:

函数名 功能
preg_filter 执行一个正则表达式搜索和替换
preg_grep 返回匹配模式的数组条目
preg_match 执行一个正则表达式匹配
preg_match_all 执行一个全局正则表达式匹配
preg_replace_callback_array 传入数组,执行一个正则表达式搜索和替换使用回调
preg_replace_callback 执行一个正则表达式搜索并且使用一个回调进行替换
preg_replace 执行一个正则表达式的搜索和替换
preg_split 通过一个正则表达式分隔字符串

7. 文件系统

7.1 读取文件

readfile读取文件

int readfile ( string $文件名)

功能:传入一个文件路径,输出一个文件。

文件分隔符: linux: / ; windows: ‘’\’ ; 单斜杠代表转义,双斜杠就行了

<?php
	header('Content-type: text/html;charset=utf-8');
	$rf = readfile('.//a//123.txt','r'); // 直接显示文件内容
?>

file_get_contents打开文件

string file_get_contents ( string filename)

功能:传入一个文件或文件路径,打开这个文件返回文件的内容。文件的内容是一个字符串

<?php
	$path = './/a//123.txt';
	$file = file_get_contents($path);
	echo $file; // 打开文件,输出文件内容
?>
<?php
	$path = './/a//123.txt';
	$fl = file_get_contents($path);// asdasjhdjkashfjksdhajkfsdh
	// 字符串以a分隔,a就不会在显示了
	$flString = explode('a',$fl);
	var_dump($flString);
	while(list($key,$val) = each($flString)){
		++$key;
		 $val = trim($val);
		 print $key .':'.  $val.'<br />';
		 /*
			1:
			2:sd
			3:sjhdjk
			4:shfjksdh
			5:jkfsdh
		 */
	}
?>

fopen、fread、fclose操作读取文件

resource fopen ( string $文件名, string 模式) 打开文件

  • 参数1: 打开文件的路径
  • 参数2: 打开文件的参数

返回类型是一个资源类型,基础类型的时候讲到的资源类型。资源类型需要其他的函数来操作这个资源。所有的资源有打开就要有关闭。

string fread ( resource $操作资源, int 读取长度)

读取打开的文件资源。读取指定长度的文件资源,读取一部份向后移动一部份。至到文件结尾。

bool fclose ( resource $操作资源 )

关闭资源。资源有打开就有关闭

资源类型的通常操作:

  • 打开资源
  • 使用相关函数进行操作
  • 关闭资源
模式 说明
r 只读方式打开,将文件指针指向文件头。
r+ 读写方式打开,将文件指针指向文件头。
w 写入方式打开,将文件指针指向文件头并将文件大小截为零。如果文件不存在则尝试创建
w+ 读写方式打开,将文件指针指向文件头并将文件大小截为零。如果文件不存在则尝试创建
a 写入方式打开,将文件指针指向文件末尾。如果文件不存在则尝试创建
a+ 读写方式打开,将文件指针指向文件末尾。如果文件不存在则尝试创建之
x 创建并以写入方式打开,将文件指针指向文件头。如果文件已存在,则 fopen() 调用失败并返回 FALSE,并生成一条 E_WARNING 级别的错误信息。如果文件不存在则尝试创建
x+ 创建并以读写方式打开,将文件指针指向文件头。如果文件已存在,则 fopen() 调用失败并返回 FALSE,并生成一条 E_WARNING 级别的错误信息。如果文件不存在则尝试创建

其他注意事项:

模式 说明
t windows下将\n转为\r\n
b 二进制打开模式
<?php
	header('Content-type:text/html;charset=utf-8');
	$path = './a/123.txt';
	// fopen('打开文件路径','模式');
	$openfile = fopen($path,'r');
	echo $openfile; // 打印资源:Resource id #3
	// fread('操作打开的资源', 文件读取的长度);
	$readfile = fread($openfile,50);
	echo $readfile;  // 打印出内容
	// fclose(操作资源);
	fclose($openfile);
?>

7.2 创建和修改文件内容

file_put_contents 写入文件

int file_put_contents ( string $文件路径, string $写入数据])

功能:向指定的文件当中写入一个字符串,如果文件不存在则创建文件。返回的是写入的字节长度

<?php
	header('Content-type: text/html; charset=utf-8');
	// 写入的数据
	$str = '这是我写入的数据';
	// 文件路径
	$path = './a/123.txt';
	// 把数据写入文件中,成功与否
	$bool = file_put_contents($path, $str);
	if($bool) {
		echo '写入成功我们读取以下试试<br/>';
		// echo file_get_contents($path);
		$open = fopen($path, 'r');
		$read = fread($open, 50);
		fclose($open);
		echo $read;
	}else {
		echo '写入失败或者是没有权限,中途发生错误';
	}
?>

fwrite配合fopen进行写入操作

fwrite的别名函数是fputs

int fwrite ( resource $文件资源变量, string $写入的字符串 [, int 长度])

<?php
	header('Content-type: text/html; charset=utf-8');
	$path = './a/123.txt';
	$str = 'fwrite与fopen一起操作';
	$open = fopen($path,'r+'); // r+可读写,r只能读
	$write = fwrite($open,$str);
	fclose($open);
	$read = file_get_contents($path);
	echo $read;
?>

7.3 创建临时文件

临时文件用完就删,不需要去维护这个文件的删除状态

resource tmpfile ( )

功能:创建一个临时文件,返回资源类型。关闭文件即被删除。

<?php
	header('Content-type:text/html;charset=utf-8');
	// 创建一个临时文件
	$timer = tmpfile();
	// 往里面写数据
	$write = fwrite($timer,'写入临时变量'); // 18字节
	// 关闭临时文件
	fclose($timer);
	echo '向临时变量里面写入了: '.$write.' 字节';// 一文字3字节
?>

7.4 文件移动、拷贝、删除

重命名,移动文件

bool rename(,旧名,新名);

这个函数返回一个bool值,将旧的名字改为新的名字。,填路径就是剪切

<?php
	header('Content-type: text/html; charset=utf-8');
	// 旧文件
	$filename = './a/123.txt';
	// 新文件
	$newfile = './b/123.txt';
	$newname = './b/456.txt';
	// 不会创建文件夹,如果文件存在就会报错
	rename($filename,$newfile); 
	rename($newfile,$newname);
	// 剪切$filename文件到$newfile文件中,然后修改名字
?>

复制文件

bool copy(源文件,目标文件)

功能:将指定路径的源文件,复制一份到目标文件的位置。

<?php
	header('Content-type: text/html;cahrset=utf-8');
	// 旧文件
	$file = './a/123.txt';
	// 新文件名
	$target = './b/123.txt';
	// 有同名文件则会覆盖,没有则会创建文件,但是不会创建目录
	copy($file,$target);
?>

删除文件

删除文件就是将指定路径的一个文件删除,不过这个删除是直接删除。使用的是windows电脑,你在回收站看不到这个文件。

bool unlink(指定路径的文件)

<?php
	header('Content-type: text/html;charset=utf-8');
	$file = './a/123.txt';
	// 文件不存在就会报错
	unlink($file);
?>

7.5 检测文件属性

  • bool file_exists ( $指定文件名或者文件路径) 功能:文件是否存在。
  • bool is_readable ( $指定文件名或者文件路径) 功能:文件是否可读
  • bool is_writeable ( $指定文件名或者文件路径) 功能:文件是否可写
  • bool is_executable ( $指定文件名或者文件路径) 功能:文件是否可执行
  • bool is_file ( $指定文件名或者文件路径) 功能:是否是文件
  • bool is_dir ( $指定文件名或者文件路径) 功能:是否是目录
  • void clearstatcache ( void ) 功能:清楚文件的状态缓存

7.6 文件常用的函数和常量

内置分隔符,windows上是’\’,’/’,linux上是’/’,要在不同的系统上呈现不同的分隔符就需要下面常量

DIRECTORY_SEPARATOR

由于FILE是PHP的预定义常量,所以没办法改变,如果需要让FILE也自适应操作系统。
那么就是不要用FILE,可以用自定义的常量,并且把FILE处理一下,如下

<?php
// str_replace:(参数3中的部分字符替换成参数2,参数2被替换的字符,参数3原始字符) 替换字符串
// __FILE__: 文件绝对路径
// DIRECTORY_SEPARATOR: windows显示\,linux显示/
$_current_file = str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, __FILE__);
// 整体意思就是: 在window上,__FILE__绝对路径,DIRECTORY_SEPARATOR参数为\,把arr参数里面的\\替换文件路劲的DIRECTORY_SEPARATOR
define('__CUR_FILE__', $_current_file);// 

echo __CUR_FILE__;

?>

7.7 文件指针操作

rewind(resource handle)

功能:指针回到开始处

fseek ( resource handle, int offset [, int from_where])

功能:文件指针向后移动指定字符

<?php
	header('Content-type: text/html;charset=utf-8');
	$fp = fopen('./a/a.txt','r+');
	// 文件指针读取10字节位置
	echo fread($fp, 10).'<br />'; // abcdeefghi
	// 文件指针回到开始
	rewind($fp);
	// 在此读取10字节
	echo fread($fp,10).'<br />'; // abcdeefghi
	// 文件指针移动到10字节位置
	fseek($fp,10).'<br />';
	// 移动指针后读取
	echo fread($fp,10); // jklk opqr  空格占两个节
/*文件内容
abcdeefghijklkopqrst
uvwxyz
12345678
*/
?>

filesize检测文件大小

<?php
	header('Content-type: text/html;charset=utf-8');
	$filepath = './a/a.txt';
	echo filesize($filepath); // 40KB
?>
函数名 功能
file 把整个文件读入一个数组中
fgets 从文件指针中读取一行,读到最后返回false
fgetc 从文件指针中读取一个字符,读到最后返回false
ftruncate 将文件截断到给定的长度
函数 功能说明
filectime 文件创建时间
filemtime 文件修改时间
fileatime 文件上次访问时间

7.8 文件锁机制

bool flock ( resource $handle , int $operation)

功能:轻便的咨询文件锁定

锁类型 说明
LOCK_SH 取得共享锁定(读取的程序)
LOCK_EX 取得独占锁定(写入的程序)
LOCK_UN 释放锁定(无论共享或独占)
<?php
$fp = fopen("demo.txt", "r+");
// 进行排它型锁定
if (flock($fp, LOCK_EX)) { 
   fwrite($fp, "文件这个时候被我独占了哟\n");
  // 释放锁定
    flock($fp, LOCK_UN);    
} else {
   echo "锁失败,可能有人在操作,这个时候不能将文件上锁";
}
fclose($fp);
?>

7.9 目录处理函数

处理文件夹的基本思想如下:

1.读取某个路径的时候判断是否是文件夹

2.是文件夹的话,打开指定文件夹,返回文件目录的资源变量

3.使用readdir读取一次目录中的文件,目录指针向后偏移一次

4.使用readdir读取到最后,没有可读的文件返回false

5.关闭文件目录

函数名 功能
opendir 打开文件夹,返回操作资源
readdir 读取文件夹资源
is_dir 判断是否是文件夹
closedir 关闭文件夹操作资源
filetype 显示是文件夹还是文件,文件显示file,文件夹显示dir

7.10 文件权限设置

函数 功能说明
chmod 修改读取模式
chgrp 修改用户组
chown 修改权限
<?php
//修改linux  系统/var/wwwroot/某文件权限为755
chmod("/var/wwwroot/index.html", 755);  
chmod("/var/wwwroot/index.html", "u+rwx,go+rx"); 
chmod("/somedir/somefile", 0755); 
?>

7.11文件路径函数

函数名 功能
pathinfo 返回文件的各个组成部份
basename 返回文件名
dirname 文件目录部份
parse_url 网址拆解成各部份
http_build_query 生成url 中的query字符串
http_build_url 生成一个url
<?php
	header('content-type: text/html;charset=utf-8');
	var_dump(pathinfo('E:/WorkingSpace/WEB/PHP/Demo26.php'));
/*
array
// 文件目录
  'dirname' => string 'E:/WorkingSpace/WEB/PHP' (length=23)
  // 文件名
  'basename' => string 'Demo26.php' (length=10)
  // 文件扩展名
  'extension' => string 'php' (length=3)
  // 文件名不包含扩展名
  'filename' => string 'Demo26' (length=6)
  */

	var_dump(parse_url('http://localhost/Demo28file.php?name=zhangsan&age=15'));
	/*
array
  'scheme' => string 'http' (length=4) 
  'host' => string 'localhost' (length=9)
  'path' => string '/Demo28file.php' (length=15)
  'query' => string 'name=zhangsan&age=15' (length=20)
	*/
	
	//生成query内容
	echo http_build_query(array('username'=>'zhangsan','age'=>'18'));
	// username=zhangsan&age=18
?>

8. 文件上传

8.1 文件上传需要注意php.ini文件

配置项 功能说明
file_uploads on为 开启文件上传功能,off为关闭
post_max_size 系统允许的POST传参的最大值
upload_max_filesize 系统允许的上传文件的最大值
memory_limit 内存使用限制

建议尺寸: file_size(文件大小) < upload_max_filesize < post_max_size < memory_limit

另外,需要注意的是脚本执行时间。

max_execution_time

这个参数是设定脚本的最大执行时间。 单位是秒

8.2 文件上传步骤

文件上传六大步:

  • 一、判断是否有错误码
错误码 说明
0 无误,可以继续进行文件上传的后续操作。
1 超出上传文件的最大限制,upload_max_filesize = 2M php.ini中设置,一般默认为2M。可根据项目中的实际需要来修改
2 超出了指定的文件大小,根据项目的业务需求指定上传文件的大小限制
3 只有部分文件被上传
4 文件没有被上传
6 找不到临时文件夹,可能目录不存在或没权限
7 文件写入失败,可能磁盘满了或没有权限
  • 二、自定义判断是否超出文件大小范围

在开发上传功能时。我们作为开发人员,除了php.ini中规定的上传的最大值外。我们通常还会设定一个值,是业务规定的上传大小限制。

例如:
新浪微博或者QQ空间只准单张头像图片2M。而在上传图册的时候又可以超过2M来上传。所以说,它的系统是支持更大文件上传的。此处的判断文件大小,我们用于限制实际业务中我们想要规定的上传的文件大小。

  • 三、判断后缀名和mime类型是否符合

在网络世界里面也有坏人。他们会把图片插入病毒,在附件中上传病毒,他们会在网页中插入病毒或者黄色图片。我们需要对于上传的文件后缀和mime类型都要进行判断才可以。

MIME(Multipurpose Internet Mail Extensions)是多用途互联网邮件扩展类型。是设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会自动使用指定应用程序来打开。多用于指定一些客户端自定义的文件名,以及一些媒体文件打开方式。

在判断后缀和MIME类型的时候,我们会用到PHP的一个函数in_array(),该函数传入两个参数。
第一个参数是要判断的值;
第二个参数是范围数组。

我们用这个函数来判断文件的后缀名和mime类型是否在允许的范围内。

  • 四、生成文件名

我们的文件上传成功了,不会让它保存原名。因为,有些人在原名中有敏感关键词会违反我国的相关法律和法规。

我们可以采用date()、mt_rand()或者unique()生成随机的文件名。

  • 五、判断是否是上传文件

文件上传成功时,系统会将上传的临时文件上传到系统的临时目录中。产生一个临时文件。同时会产生临时文件名。我们需要做的事情是将临时文件移动到系统的指定目录中。而移动前不能瞎移动,或者移动错了都是不科学的。移动前我们需要使用相关函数判断上传的文件是不是临时文件。is_uploaded_file()传入一个参数($_FILES中的缓存文件名),判断传入的名称是不是上传文件。

  • 六、移动临时文件到指定位置

临时文件是真实的临时文件,我们需要将其移动到我们的网站目录下面了。让我们网站目录的数据,其他人可以访问到。

我们使用:move_uploaded_file()。这个函数是将上传文件移动到指定位置,并命名。
传入两个参数:
第一个参数是指定移动的上传文件;
第二个参数是指定的文件夹和名称拼接的字符串。

form表单文件上传

<form action="file.php" method="post" enctype="multipart/form-data">
           <input type="file" name="file">
           <input type="submit" value="上传">
       </form>

注意事项:

  • form 表单中的参数method 必须为post。若为get是无法进行文件上传的
  • enctype须为multipart/form-data
<!doctype html>
<html>
	<head>
		<meta charset="utf-8">
		<title>文件上传</title>
	</head>
	<body>
<!--enctype="multipart/form-data": 
	enctype: 编码类型
	multipart/form-data: 表单数据有多部分构成,既有文本数据,又有文件等二进制数据的意思
	默认值: application/x-www-form-urlencoded这个不能用于文本上传,只有上面的才能完整的传递文件
	上传文件必须是post请求
-->
		<form action="http://localhost/Demo26.php" method="post" enctype="multipart/form-data">
			<input type="file" name="file">
			<input type="submit" value="上传">
		</form>
	</body>
</html>
<?php
	header('Content-type: text/html; charset=utf-8');
	// $_FILES: 上传的所有数据都保存在这个系统函数里
	var_dump($_FILES);
	/*
array
  'file' => 
    array
		// 文件名
      'name' => string '2.png' (length=5)   
	  // 文件类型
      'type' => string 'image/png' (length=9)  
	  // 缓存文件,上传的图片暂时保存在这的
      'tmp_name' => string 'D:\SQLUI\wamp\tmp\phpB980.tmp' (length=29)
	  // 错误码,详细见上面
      'error' => int 0
	  // 上传文件大小
      'size' => int 88715
	*/
// 第一步: 判断错误码
if($_FILES['file']['error'] > 0) {
	switch($_FILES['file']['error']){
		case '1':
			echo '文件过大';
			break;
		case '2':
			echo '文件超出指定的大小';
			break;
		case '3':
			echo '只有部分文件被上传';
			break;
		case '4':
			echo '文件没有被上传';
			break;
		case '6':
			echo '找不到指定文件夹';
			break;
		case '7':
			echo '文件写入失败';
			break;
		default:
			echo '上传出错<br/>';
	}
}else { // 错误码为0,上传成功
// 第二步: 判断文件是否超出大小
	$MAX_FILE_SIZE = 204800; // 文件最大上传200KB
	if($_FILES['file']['size'] > $MAX_FILE_SIZE) {
		// 上传文件超出了我们最大的限制,退出,并产生提示
		exit('文件超出指定的大小');
	}
// 第三步: 判断文件的mime类型的正确
	$adminImg = array('jpg','png');
	$myImg = explode('.',$_FILES['file']['name']);
	var_dump($myImg);
	/*
array
  0 => string '3' (length=1)
  1 => string 'png' (length=3)
	*/
	/*
		array_pop(): 弹出数组中的最后一个单元(出栈),
		in_array() 检测数组中是否有这一项,参数2包含参数1
	*/
	$lastImg = array_pop($myImg);
	if(!in_array($lastImg,$adminImg)){
		exit('后缀名不符合,需要jpg,png格式');
	}
	// 有时候文件名不对应,用户直接修改文件后缀,导致文件不可用,mime类型也必须做出限制检查
	$allowMime = array("image/jpg","image/png");
	if(!in_array($_FILES['file']['type'],$allowMime)){
		exit('文件格式不对');
	}
// 第四步: 生成指定路径和文件
	/*
		根据当前时间生成随机文件名,本行代码是使用当前时间 + 随机一个0-9的数字组合成文件名,后缀即为前面取到的文件后缀名
	*/
	$path = 'C:\\Users\\a4244\\Desktop\\'; // 指定上传文件夹
	$name = date('Y').date('m').date("d").date('H').date('i').date('s').rand(0,9).'.'.$lastImg;
// 第五步: 判断是否是上传文件
	// is_uploaded_file()函数是专用的函数,来判断目标文件是否是上传文件。
	if(is_uploaded_file($_FILES['file']['tmp_name'])){    
// 第六步 移动文件到指定位置
		// move_uploaded_file()移动上传文件至指定位置,第一个参数为上传文件,第二个参数为我们在前面指定的上传路径和名称 
		if(move_uploaded_file($_FILES['file']['tmp_name'], $path.$name)){
			echo $path.$name;
			echo '上传成功';
		}else {
			echo '上传失败';
		}
	}else {
		echo '不是上传文件';
	}
}
?>

8.3 文件上传进度处理

  • session.upload_progress.enabled 是否启用上传进度报告(默认开启) 1为开启,0为关闭
  • session.upload_progress.cleanup 是否在上传完成后及时删除进度数据(默认开启, 推荐开启)
  • session.upload_progress.prefix[=upload_progress_] 进度数据将存储在_SESSION[session.upload_progress.prefix._POST[session.upload_progress.name]]
  • session.upload_progress.name[=PHP_SESSION_UPLOAD_PROGRESS] 如果_POST[session.upload_progress.name]没有被设置, 则不会报告进度.
  • session.upload_progress.freq[=1%] 更新进度的频率(已经处理的字节数), 也支持百分比表示’%’.
  • session.upload_progress.min_freq[=1.0] 更新进度的时间间隔(秒级)

9. 图像处理

使用PHP图像处理函数,需要加载GD支持库。请确定php.ini加载了GD库

var_dump(gd_info());

第一步: 创建画布

$img = imagecreate(500,500);

第二步: 添加颜色

$color = imagecolorallocate(resource $图片资源,int $红,int $绿, int $蓝)

第三步: 将颜色添加到背景进行填充

imagefiledrectangle(resource $图片资源 , int $点1x轴, int $点1y轴 , int $点2x轴 , int $点2y轴 , int $color)

第四步: 画线

imagline(resource $图片资源 , int $点1x轴, int $点1y轴 , int $点2x轴 , int $点2y轴 , int $color)

第四步: 画圆

imagefilledellipse(resource $图片资源 , int $圆心x , int $圆心y , int $圆的宽 , int $圆的高 , int $圆的颜色)

第五步: 保存图片

bool imagejpeg(resource $image [,string $filename])

  • $imagetype = ‘jpeg’;
  • $imagetype = ‘png’;
  • $imagetype = ‘gif’;

第六步: 销毁图片资源

imagedestroy($img);

图像缩放

函数名 函数说明
imagecopyresampled 重采样拷贝部分图像并调整大小
imagecopyresized 拷贝部分图像并调整大小
  • bool imagecopyresampled ( resource $目标图 , resource $来源图 , int $目标开始的x位置 , int $目标开始的y位置 , int $来源开始的x位置 , int $来源开始的y位置 , int $目标图片的宽 , int $目标图片的高, int $来源图片的宽 , int $来源图片的高 )

  • bool imagecopyresized ( resource $目标图 , resource $来源图 , int $目标开始的x位置 , int $目标开始的y位置 , int $来源开始的x位置 , int $来源开始的y位置 , int $目标图片的宽 , int $目标图片的高, int $来源图片的宽 , int $来源图片的高 )

图片缩放和裁剪的方法都是一样的,不同的是拷贝时拷贝的是整张图片还是部份部片。

操作方式说明:
从来源图片的开始点(x,y)起,指定的宽高的大小图片。放至到目标图片的起点(x,y),指定宽高大小的图片中。

图像水印

bool imagecopymerge ( resource $目标图片 , resource $来源图片, int $目标开始的x , int $目标开始的y, int $来源的x , int $来源的y , int $来源的宽 , int $来源的高 , int $透明度)

透明度的值为0-100的整数。imagecopy和imagecopymerge的区别在于一个有透明度,一个没有透明度。

10. 错误处理

一般出现错误都会出现在网页中,但是不想显示在网页中,就必须在php.ini文件中的display_errors这个选项设置1或者true显示在网页中,如果设置false或者0则不会显示,也可以用ini_set方法设置

ini_set(‘display_errors’,0);

错误类型 说明
E_ERROR 错误,文件直接中断
E_WARNING 警告,问题比较严重。但是还会继续向下运行
E_NOTICE 提示,有些小问题不会影响到程序。常发生在项目未定义
E_PARSE 编译时语法解析错误。解析错误仅仅由分析器产生。
E_ALL 所有的错误
E_STRICT 启用PHP对代码的修改建议,以确保代码具有最佳的互操作性和向前兼容性。
E_DEPRECATED 启用后将会对在未来版本中可能无法正常工作的代码给出警告。
错误类型 错误说明
E_CORE_ERROR 在PHP初始化启动过程中发生的致命错误。该错误类似E_ERROR,但是是由PHP引擎核心产生的
E_CORE_WARNING PHP初始化启动过程中发生的警告 (非致命错误) 。类似 E_WARNING,但是是由PHP引擎核心产生的。
E_COMPILE_ERROR 致命编译时错误。类似E_ERROR,但是是由Zend脚本引擎产生的。
E_COMPILE_WARNING 编译时警告(非致命错误)。类似E_WARNING,但是是由Zend脚本引擎产生的
E_USER_ERROR 用户自定义错误
E_USER_WARNING 用户自定义警告
E_USER_NOTICE 用户自定义提示
E_USER_DEPRECATED 用户产少的警告信息。类似E_DEPRECATED,但是是由用户自己在代码中使用PHP函数trigger_error()来产生的。
E_RECOVERABLE_ERROR 可被捕捉的致命错误。它表示发生了一个可能非常危险的错误,但是还没有导致PHP引擎处于不稳定的状态。

如果想要把所有的错误类型设置一下

error_reporting = 错误类型

显示所有错误,但是排除提示

error_reporting = E_ALL & ~ E_NOTICE

显示所有错误,但排除提示、兼容性和未来兼容性。可写为:

error_reporting = E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED

关闭了所有的错误显示

error_reporting(0);

显示所有错误

error_reporting(E_ALL);

显示所有错误,但不显示提示

error_reporting(E_ALL & ~ E_NOTICE);

10.1 错误记录日志

参数 配置项 说明
log_errors on/off 是否开启日志记录
log_errors_max_len 整型,默认1024 单行错误最大记录长度
error_log syslog或者指定路径 错误日志记录在什么地方

PHP还为我们专门准备了一个自定义的错误日志函数:

bool error_log ( string $错误消息 [, int $错误消息类型 = 0 [, string $存储目标]] )

这个函数可以把错误信息发送到web服务器的错误日志,或者到一个文件里。

常用的错误消息类型:

错误消息类型 说明
0 发送至默认的error_log指定位置
1 发送到指定的邮件位置
3 发送至指定的文件位置

用户自定义错误经常用到的两个函数:

set_error_handler ( callable $回调的错误处理函数)
设置一个用户定义的错误处理函数

trigger_error ( string $error_msg)
产生一个用户级别的 error/warning/notice 信息

10.2 cookie

1. 设置cookie

cookie 常用于识别用户。cookie 是一种服务器留在用户计算机上的小文件。每当同一台计算机通过浏览器请求页面时,这台计算机将会发送 cookie。通过 PHP,您能够创建并取回 cookie 的值。

设置cookie,setcookit()函数用于设置cookie,必须位于html标签之前

setcookie (name,value,expire,path,domain)

  • name 必需。规定 cookie 的名称。
  • value 可选。规定 cookie 的值。
  • expire 可选。规定 cookie 的有效期。
  • path 可选。规定 cookie 的服务器路径。
  • domain 可选。规定 cookie 的域名。

对于这个函数,我们一般这么用: setcookie(cookie名,cookie值,cookie有效期),三个就够了

<?php
setcookie("user","Alex Porter",time()+3600);
?>

在发送 cookie 时,cookie 的值会自动进行 URL 编码,在取回时进行自动解码(为防止 URL 编码,请使用 setrawcookie() 取而代之)

2. 取回cookie

PHP 的 $_COOKIE 变量用于取回 cookie 的值。

在下面的实例中,我们取回了名为 “user” 的 cookie 的值,并把它显示在了页面上,创建了名为php的cookie:

// 输出 cookie 值
echo $_COOKIE["user"] ."<br/>";
// 查看所有 cookie
print_r($_COOKIE); // Array (   [pgv_pvi] => 9622684672   [user] => php ) 

3. 删除cookie

当删除 cookie 时,只要使到期日期变更为过去的时间就可以

setcookie("user","",time()-3600);

10.3 Session

PHP session 变量用于存储关于用户会话(session)的信息,或者更改用户会话(session)的设置。Session 变量存储单一用户的信息,并且对于应用程序中的所有页面都是可用的。

您在计算机上操作某个应用程序时,您打开它,做些更改,然后关闭它。这很像一次对话(Session)。计算机知道您是谁。它清楚您在何时打开和关闭应用程序。然而,在因特网上问题出现了:由于 HTTP 地址无法保持状态,Web 服务器并不知道您是谁以及您做了什么。

PHP session 解决了这个问题,它通过在服务器上存储用户信息以便随后使用(比如用户名称、购买商品等)。然而,会话信息是临时的,在用户离开网站后将被删除。如果您需要永久存储信息,可以把数据存储在数据库中。

Session 的工作机制是:为每个访客创建一个唯一的 id (UID),并基于这个 UID 来存储变量。UID 存储在 cookie 中,或者通过 URL 进行传导。

1. 开启session

session_start(),这个函数没有参数。在php文件的开始使用

注释:session_start() 函数必须位于 html 标签之前:

<?php session_start(); ?>
<html>
	<body>
	</body>
</html>

2. 添加session数据

添加session数据

开启会话之后,那么在接下来的处理中,我们就可以使用SESSION_SESSION变量来存取信息了。我们要知道的是_SESSION变量是个数组。当我们要把信息存入session的时候应该这么写:

<?php
$_SESSION['userName'] = 'wang';
?>

3.读取session数据

读取很简单,就像我们使用数组一样,如下:

$userName = $_SESSION[‘userName’];

当然也可以 $_SESSION[‘userName’] 来用。和数组一样的使用。

4. 销毁session数据

我们可以使用很多种方式来销毁session数据。

a) unset函数

我们通过使用类似

unset($_SESSION[‘XXX’]);

来销毁session中的 XXX 变量。

PS:请不要!请不要!请不要unset(SESSION),使_SESSION),会导致后续无法使用_SESSION这个变量!!!

b) 空数组赋值给session变量

$_SESSION = array();

之前我们说过$ _ SESSOIN变量是个数组,那么空数组赋值的话也是相当于将当前会话的$_SESSION变量中的值销毁。

c) session_destory() 函数

这个函数会销毁当前会话中的全部数据,并结束当前会话。但是不会重置当前会话所关联的全局变量, 也不会重置会话 cookie。

5. 存储 Session 变量

实例

存储和取回 session 变量的正确方法是使用 PHP $_SESSION 变量:

<?php
 session_start();
 // 存储 session 数据
 $_SESSION['views']=100;
 ?>
 
 <html>
 <head>
     <meta charset="utf-8">
     <title>php中文网(php.cn)</title>
 </head>
 <body>
 
 <?php
 // 检索 session 数据
 echo "浏览量:". $_SESSION['views']; // 100
 ?>
 
 </body>
 </html>

11. MySQL

11.1 基本sql语法

  • 启动服务: net start mysql57
  • 登录数据库: mysql -h localhost -P 33060 -u root -p123456
  • 显示数据库: use databases;
  • 创建数据库: create database name;
  • 创建表:
mysql> create table Demo01(
    -> id INT(10) primary key, // 定义主键: 唯一,不为空,和外键关联,查询快
    -> name varchar(10),
    -> sex varchar(6),
    -> primary key(id) // 一个参数就是单字段组建,多个就是多字段组建
    -> );
Query OK, 0 rows affected (0.04 sec)
mysql> create table Demo04(
    -> id int(2) primary key auto_increment,
    // auto_increment: 自动增加
    -> name varchar(30),
    -> sex varchar(5) not null,// not null:这一字段不能为空
    -> waijian1 int(11),
    -> constraint waijian01 foreign key(waijian1) references Demo01(id) // 创建外键语法: <waijian01>: 外键名;<waijian1>: 字段名
    // Demo01: 主表名; id: 主键列
    -> );
Query OK, 0 rows affected (0.04 sec)
  • 查看当前所在的表: select database()
  • 进表: use 表名;
  • 查看表结构: desc 表名;
  • 删除表: drop table 表名;
  • 修改字段数据类型:alter table 表名 modify gender 修改后的类型
  • 修改字段名: alter table 表名 change gender 修改后字段名 修改后类型
  • 删除字段: alter table 表名drop 字段名;
  • 在指定字段后添加数据: alter table 表名 add 添加字段名 字段类型 after 在那个表后添加
  • 在表第一列添加: alter table 表名 add 添加字段名 字段类型 first
  • 表约束
约束条件 说明
proimary key 唯一,不为空,和外键关联,查询快
foreign key 外键约束
not null 非空约束
unique 唯一性约束
default 默认约束,用于设置字段默认值
auto_increment 自动增加,从1开始
  • 插入数据: insert into 表名 (name,age,work)values (‘value1’,‘value2’,‘valuen’)
  • 修改数据: update 表名 set name=‘value’ [where id = 2];
  • 删除数据: delete from 表名 where name = value1 [AND id = value2];
  • 查询数据: select name,age from 表名;
  • 统计长度: select count(*) from 表名;

11.2 连接MySQL

11.2.1 注册界面

<!DOCTYPE html>
<html lang="zh-cn">
<head>
    <meta charset="UTF-8">
    <title>注册页面</title>
</head>
<body>
    <form action="http://localhost/Demo33register.php" method="post">
        <label>
            用户名: 
            <input type="text" name="username">
        </label>
        <br /><br />
        <label>
            密码:
            <input type="text" name="password">
        </label>
        <br /><br />
        <label>
            登录名:
            <input type="text" name="loginname">
        </label>
        <br /><br />
        <input type="submit" value="注册">
    </form>
</body>
</html>

11.2.2 注册php界面

<?php
    // 解决乱码
    header('Content-type: text/html;charset=utf-8');
    // 接受请求,处理请求,完成响应
    $username = $_POST['username'];
    $password = $_POST['password'];
    $loginname = $_POST['loginname'];

    // 处理请求 把客户端的数据往数据库中放
	// 注意: 建立连接时,必须先要在数据库中创建数据库和表与创建字段,然后php操作
    // 第一步建立连接
    $connect = mysql_connect('localhost:33060','root','123456');
    if(!$connect) {
        die('Could not connect: ' .mysql_error());
    }
    // 连接那个数据库
    mysql_select_db('php',$connect);

    // 把客户端的数据往表里面添加
    $sql = "INSERT INTO user(username, password, loginname) 
        values('$username','$password','$loginname')";

    // 通过连接发送sql语句
    if(!mysql_query($sql,$connect)) {
        die('Errot: '.mysql_error);
    }
    // 关闭跟数据库的连接
    mysql_close($connect);
    echo '注册成功';
	// header("Refresh:3;url=login.html");// 3秒后跳转登录界面
?>

11.2.3 登录界面

<!DOCTYPE html>
<html lang="zh-cn">
<head>
    <meta charset="UTF-8">
    <title>登录页面</title>
</head>
<body>
    <form action="http://localhost/Demo33login.php" method="post">
        <label>
            登录名: 
            <input type="text" name="loginname">
        </label>
        <br />
        <label>
            密码:
            <input type="text" name="password">
        </label>
        <br />
        <input type="submit" value="登录">
    </form>
</body>
</html>

11.2.4 登录php界面

<?php
    // 解决乱码
    header('Content-type:text/html;charset=utf-8');
    // 接受请求, 处理请求,响应数据 
    $loginname = $_POST['loginname'];
    $password = $_POST['password'];

    // 处理请求。 获取到用户名跟密码,到数据库里面进行查询,有没有这条记录
        // 建立数据库连接,跟那个库进行连接,准备sql语句,发送sql语句,等待响应的结果,根据结果进行响应
        $connect = mysql_connect('localhost:33060','root','123456');
        if(!$connect) {
            die('Could not connect: ' .mysql_error());
        }
        // 连接那个数据库
        mysql_select_db('php',$connect);
        
        // sql语句查询数据库中的数据
        $sql = "select loginname,password from user where 
            loginName = '$loginname' and password = '$password'";
        
        // 查询,响应一个结果。返回的结果都在这里
        $result = mysql_query($sql);
        $item = array();
        // 获取结果
        if($row = mysql_fetch_array($result)){
            // 拿数据: $row: 代表一行记录,里面有多列
            $item = array(
                "loginname" => $row['loginname'],
                "password" => $row['password'],
            );
        }
        // 根据结果进行判断
        if(count($item)>0) {
            echo '登录成功';
        }else {
            echo '用户名或者密码错误';
        }
?>

12. cookie

12.1 cookie原理

Cookies就是服务器暂时存放在你的电脑里的资料(.txt格式的文本文件),好让服务器用来辨认你的计算机。当你在浏览网站的时候,Web服务器会先送一小小资料放在你的计算机上,Cookies 会把你在网站上所打的文字或是一些选择都记录下来。当下次你再访问同一个网站,Web服务器会先看看有没有它上次留下的Cookies资料,有的话,就会依据Cookie里的内容来判断使用者,送出特定的网页内容给你。

cookie是http协议定义的规定

cookie是服务器发送到客户端的响应数据:(响应首行,响应头,响应空行,响应体)

cookie大小是4kb,各个浏览器大小不同;当cookie满了,会删除前面的数据

怎么去使用:

服务端:怎么发送cookie (setcookie() 函数用于设置 cookie );

setcookie("user", "Alex Porter", time()+3600); 服务端向客户端设置cookie

客户端:怎么获取cookie

var cookies=document.cookie;

演示:

  • 第一次: 客户端请求服务器
  • 第二次: 服务器响应一个cookie发送到客户端,并保存到客户端,以后每次访问服务器,都会把cookie携带到服务器
  • 第三次: 客户端通过 setcookie(‘username’,‘zhangsan’)把数据绑定到cookie上发送给服务器端,然后响应给客户端
  • 第四次: 客户端访问cookie里面username的值

01.客户端向服务器端发送cookie

<?php // 01.php文件
    // 向客户端发送cookie
    // cookie 输出到客户端,也是以键值对的方式输出到客户端的.
    setcookie('username','zhangsan')// 第一次客户端发送请求,服务器端响应给客户端cookie,这个cookie的值是通过响应头Set-Cookie响应头的值,是设置这个值发送到服务端;客户端拿到set-Cookie之后,会按照http协议的方式去解析,把cookie进行保存下来,接下来用02.php与03.php再次访问服务器,客户端会把cookie里面的数据以Cookie:username=zhangsan请求的方式发送到服务器
?>

02.访问服务器并携带cookie给服务器,然后向客户端输出

<?php // 02.php文件
    // 01.php发送cookie给服务器端,然后服务器给出响应并发送过来cookie
    // 访问服务器端并携带01.php的cookie,响应给客户端,内容在请求头里面
    echo $_COOKIE['username'];
?>
<script>
    // 上面访问服务器,并携带cookie过去,然后服务器端响应cookie给客户端,script刚好获取
    console.log(document.cookie);
</script>

03.访问服务器并携带cookie给服务器,然后向客户端输出

<?php // 03.php文件
    // 01.php发送cookie给服务器端,然后服务器给出响应并发送过来cookie
    // 访问服务器端并携带01.php的cookie,响应给客户端,内容在请求头里面
    echo $_COOKIE['username'];
?>

12.2 cookie生命周期

http协议是基于请求,请求 —》响应,服务器与客户端就会断开,http协议是无状态的,服务器不能记住客户端的状态,cookie它是用来记住用户状态,用来进行多个请求之间的数据共享,cookie是保存在客户端

  • cookie分为三种类型
    • 内存cookie: 服务器给客户端发送cookie,这个cookie保存在客户端浏览器的内存当中,当关闭浏览器,cookie就会消失掉
    • 硬盘cookie: 服务器端给客户端发送一个cookie,这个cookie保存在用户的硬盘上(例如: 历史记录),持久化。关闭电源,重启电脑,这个cookie还在除非卸载浏览器或者清除浏览器历史记录
    • 追杀cookie:把之前写到客户端的cookie给清除

内存cookie演示

新建三个php文件

<?php    // 三个文件都是这代码
    // 发送内存cookie
    setcookie('username','lisi');
?>

启动第一个文件会发现请求头是Set-Cookie: username=lisi,启动第二个,第三个文件会发现: 响应头是Cookie: username=lisi,关闭浏览器cookie就会被销毁,再次打开请求头里面就没有cookie

硬盘cookie

文件一:

<?php
	// 发送硬盘cookie,在硬盘上的存活时间一小时
    setcookie('age',20,time()+3600);
	//setcookie('age',20,time()+60*60*24);// 一天
?>

文件2,3保证在同一服务器下,有无内容都可以访问

设置文件3追杀cookie

<?
    //追杀cookie只是把客户端上面的cookie清除,并不会清除服务器上面的,所以请求服务器,服务器还是会发送cookie过来,只不过客户端不会响应cookie过去
    setcookie('username','',-1);
?>

13. session

13.1 概念

session代表的就是一次会话.会话在我们的现实过程当中有很多,比如和10086打电话,当10086接通时,代表我的会话开始,中间我可能发送多次动作交谈,直至挂断,代表会话结束.整个会话过程当中,我们可能发送多次请求,由多次请求组成一次会话.(一个会话由多次请求组成)

web会话: 当打开网站,访问我的网站时会话开始,在这个网站当中我可能发送多次请求,直至关闭浏览器会话借宿.这整个过程当中我们可以理解成一次会话.http协议是基于请求响应的,无状态的,一次会话当中包含多个请求,每个请求都是相互独立的,会话中的多次请求,需要在请求之间共享数据,所以这时候,我们需要使用到会话

一个网站的会话由多次http请求组成,http请求时无状态的,是基于请求响应的,每个请求都是相互独立的,一次会话范围内要进行数据共享,每个请求都是独立的,就不能进行数据共享

无状态: 请求—>响应 连接就会断开,我要在一个会话范围内进行数据共享,这个时候我们就需要使用session

13.2 使用

服务器获取一个session

session_start() 会话开始

获取到session对象

$_SESSION[] 获取到对象,往里面保存数据

01.php

<?php
    // 用户登录成功
    $username = 'zhangsan';
    // 我要把这个数据保存在会话中

    // 开始一次会话
    session_start();
    // 关联数组
    $_SESSION['username'] = $username;
?>

02.php

<?php
    header('Content-type: text/html;charset=utf-8');
    // 用户可能又来请求整个,我要把这个页面判断用户登录状态
    
    // 去获取zhangsan
    // 开始一次会话
    session_start();
    echo $_SESSION['username']
?>

13.3 原理

当客户端第一次访问服务器,客户端什么都没有携带只是单纯的访问01.php服务器的时候,服务器首先执行session_start();这个方法会到session池里面查找有没有一个session,如果服务器没有session,服务器就会创建session,把session放在session池当中,然后以关联数组的形式去存放sessionID作为key,session作为值进行存储,然后生成sessionID给cookie响应给客户端Set-Cookie: PHPSESSID=r48q7gfav4vp18e51q8ou1p8p3; path=/,第二次请求,cookie会携带sessionID(PHPSESSID=r48q7gfav4vp18e51q8ou1p8p3; path=/)响应给服务端,02.php服务端会获取到客户端cookie里面的sessionID,根据sessionID从session池当中获取session,获取到之后给$_SESSION的变量赋值,这个时候我们就可以从session中拿数据

开始会话

web会话并不是浏览器开始访问一个网站会话就开始.而是服务器运行session_start()创建了session,然后向客户端响应一个cookie,cookie里面保存了sessionId,这个时候会话开始

第二次客户端访问服务器,服务器通过session_start()找到session池中的session,从客户端发送过来的cookie中的sessionID在session池中找到会话

session池: 存储在服务器的内存当中,它有一个生命周期,php当中默认是1440秒,也就是24分钟; 但是在24分钟内重新访问一下就会重新刷新时间(心跳)

结束会话

  • 服务器端的session超时
  • 清除浏览器历史记录
  • 清理cookie

14. Ajax

14.1 Ajax介绍与应用

同步交互: 客户端给服务器端发送请求,服务器端给客户端一个响应,响应回来的数据会把客户端界面给覆盖,我们把这种交互叫做同步交互

异步交互: 客户端给服务器发送一个请求,服务器端给客户端响应一个数据,响应回来的数据不会把原来的客户端界面给覆盖

原理: 浏览器给我们提供一个js对象,这个对象XMLHttpRequest,通过这个对象我们可以去发送请求,接收请求处理请求

例如: 当点击一个按钮,触发一个事件,然后通过调用send()方法区发送请求.服务器返回数据给XMLHttpRequest对象.XMLHttpRequest对象拿到数据之后,直接将数据通过DOM放在页面上,从而达到页面不刷新就可以与服务器交互

演示:

php文件: Ajax.php

<?php
    header('Content-type: text/html;charset=utf-8');
    echo '服务器端响应数据';
?>

AjaxGet.html

<input type="submit" value="发送请求">
<span></span>
<script type="text/javascript">
    document.querySelector('input').onclick = function(){
        // 利用XMLHttpRequest对象进行交互
        const xhr = new XMLHttpRequest();
        // 打开链接
        xhr.open('get','http://localhost/Ajax.php?username=zhangsan');
        // 发送数据
        xhr.send();
        // 接收数据: 通过异步的方式,就是只能通过回调函数的方式
        // 监听这服务器端状态的改变
        xhr.onload = function() {
            // xhr.readyState: Ajax状态: 0,1,2,3,4(响应完成)
            // xhr.status: Http状态,200
            if(xhr.status == 200 && xhr.readyState == 4) {
                const span = document.getElementsByTagName('span')[0];
                // 接收服务器返回的数据
                var data = xhr.responseText;
                span.innerHTML = data;
            }
        }
        /*
            xhr.onreadystatechange = function() {

            }
            */
    };
</script>

AjaxPost.Ajax

<input type="submit" value="发送请求">
<span></span>
<script type="text/javascript">
    document.querySelector('input').onclick = function(){
        // 利用XMLHttpRequest对象进行交互
        const xhr = new XMLHttpRequest();
        // 打开链接
        xhr.open('post','http://localhost/Ajax.php');
        // post提交要发送特殊的请求头到服务器
        xhr.setRequestHeader('Content-type:application/x-www-form-urlencoded');
        // 发送数据
        xhr.send('username=zhangsan');
        // 接收数据: 通过异步的方式,就是只能通过回调函数的方式
        // 监听这服务器端状态的改变
        xhr.onload = function() {
            // xhr.readyState: Ajax状态: 0,1,2,3,4(响应完成)
            // xhr.status: Http状态,200
            if(xhr.status == 200 && xhr.readyState == 4) {
                const span = document.getElementsByTagName('span')[0];
                // 接收服务器返回的数据
                var data = xhr.responseText;
                span.innerHTML = data;
            }
        }
        /*
            xhr.onreadystatechange = function() {

            }
            */
    };
</script>

14.2 XML格式

XML是一种标记语言,很类似HTML,其宗旨就是用来传递数据,具有自我描述性(固定格式的数据).一般是软件配置文件

  1. 必须有一个根元素<?xml version="1.0" encoding="utf-8">
  2. 标签不可有空格,不可以数字或开头,大小写敏感
  3. 标签不可交叉嵌套
  4. 标签属性双引号(浏览器自动修正双引号)
  5. 特殊符号要使用实体
  6. 注释和HTML一样

案例:

xml.txt

<?xml version="1.0" encoding="utf-8">
<users>
    <user>
        <id>1</id>
        <username>张三</usename>
        <adress>中国江西</adress>
        <loginName>我是登录名</loginName>
        <password>123456</password>
    </user>
	<user>
        <id>2</id>
        <username>李四</usename>
        <adress>美国旧金山</adress>
        <loginName>我是登录名</loginName>
        <password>987654</password>
    </user>
</users>

xml.html

<input type="submit" value="发送请求">
<span></span>
<script type="text/javascript">
    document.querySelector('input').onclick = function(){
        const xhr = new XMLHttpRequest();
        xhr.open('get','http://localhost/xml.php');
        xhr.send();
        xhr.onload = function() {
            if(xhr.status == 200 && xhr.readyState == 4) {
                const span = document.getElementsByTagName('span')[0];
                var dom xhr.responseXML; // 得到的就是document对象: #document
                span.innerHTML = dom.querySelectorAll('user")[0].querySelector('username').innerHTML;// 张三
            }
        }
    };
</script>

xml.php

header('Content-type:text/html;charset=utf-8');
// 把user.txt文件内容读取出来
$data = file_file_get_contents('xml.txt');
// 响应给客户端
echo $data;

14.3 JSON格式

JSON(JavaScript Object Notation),它是一种轻量级的文本数据交换格式,独立于语言

  • json的数据格式是键值对形式存在的
  • 多条数据以逗号隔开
  • 花括号保存对象,方括号保存数组
  • 使用双引号

php将关联数组转为json数据格式: json_encode(); 需要设置响应头为: text/json

JavaScript可以解析JSON的字符串: eval() 或者 JSON.parse()

//设置data是JSON的字符串格式
	// eval()方法
	eval("("+data+")");
    JSON.parse(data); 

15 跨域

浏览器会拦截跨域,但是服务器与服务器可以跨域

15.1 jsonp跨域

360搜素的智能提示

<div id="app">
	<input type="text" autofocus>
	<ul></ul>
</div>

<script type="text/html" id="tp1">
	<%for(let i = 0; i < obj.result.length; i++){%>
		<li><%=obj.result[i].word%></li>
	<%}%>
</script>
<script type="text/javascript">
function suggest_so(obj){
	html = template('tp1',{obj});
	const ul = document.getElementsByTagName('ul')[0];
	ul.innerHTML = html;
}
(function(){
	// 当input内容变化就会触发
	document.getElementsByTagName('input')[0].oninput = function() {
	const script = document.createElement('script');
	script.src=`https://sug.so.360.cn/suggest?callback=suggest_so&encodein=utf-8&encodeout=utf-8&format=json&fields=word&word=${this.value}&huid=11LyPV%2F40quxRkUykFdCqNwbOzOgMoUO7So0sL8w0LsRc%3D&llbq=A5%2CB5%2CC5%2CD5`;
	document.body.appendChild(script);

};
})();

模拟服务器处理suggest_so(),这个名字可以自定义

const express = require('express');
const server = express();
const path = require('path');
// 静态资源访问服务功能
server.use(express.static(path.join(__dirname,'public')))

server.get('/jd',(req,res) => {
    // 取到客户端getInfo请求的参数
    const getInfo = req.query.callback;
    // 向客户端输出: getInfo("我是京东首页")
    res.send(`${getInfo}("我是京东首页")`);
})
server.listen(3000);

jsonp的跨域,它只支持get方式请求,因为它是使用script标签去发送请求,而且服务端需要做处理,客户端也需要做处理.如果跨域的时候传递的数据非常多,jsonp的方式就不太可取

15.2 cors跨域

如果使用XMLHttpRequest有跨域限制,浏览器的数据接收不了,让服务器给客户端一个响应头Access-Control-Allow-Origin:https://www.jd.com,https://taobao.com,可以把后面的地址换成*,会变成所有的网站都可以

跨域资源共享,它的原理就是在请求服务器的时候,服务器给一个响应头,告诉客户端,这些数据可以访问

通过向客户端输出一个响应头
header("Axxess-Control-Allow-Origin:*"); // 跨域资源共享

这种方式是服务器直接给一个响应头Access-Control-Allow-Origin,告诉客户端浏览器,这些数据可以获取,这个Access-Control-Allow-Origin也是http协议规定的

15.3 jsonp与cors的区别

jsonp是最早的这种跨域解决方案,因为是使用script标签发送请求,所以兼容性比较好,但是只支持get方式

cors是后期的一种解决方案,它只需要改服务器的配置,设置一个响应;客户端不需要做任何处理.

其他方法: 通过后台服务器转发,通过设置代理服务器

16 前后端分离

如果前后端分离,服务端对外提供的都是json格式数据,都是提供的借口哦,提供的接口占用端口对外提供服务,就会存在接口安全问题,谁都可调用接口

解决接口安全问题: 对接口进行认证

- session认证
d>123456</password>
 </user>
	<user>
        <id>2</id>
        <username>李四</usename>
        <adress>美国旧金山</adress>
        <loginName>我是登录名</loginName>
        <password>987654</password>
    </user>
</users>

xml.html

<input type="submit" value="发送请求">
<span></span>
<script type="text/javascript">
    document.querySelector('input').onclick = function(){
        const xhr = new XMLHttpRequest();
        xhr.open('get','http://localhost/xml.php');
        xhr.send();
        xhr.onload = function() {
            if(xhr.status == 200 && xhr.readyState == 4) {
                const span = document.getElementsByTagName('span')[0];
                var dom xhr.responseXML; // 得到的就是document对象: #document
                span.innerHTML = dom.querySelectorAll('user")[0].querySelector('username').innerHTML;// 张三
            }
        }
    };
</script>

xml.php

header('Content-type:text/html;charset=utf-8');
// 把user.txt文件内容读取出来
$data = file_file_get_contents('xml.txt');
// 响应给客户端
echo $data;

14.3 JSON格式

JSON(JavaScript Object Notation),它是一种轻量级的文本数据交换格式,独立于语言

  • json的数据格式是键值对形式存在的
  • 多条数据以逗号隔开
  • 花括号保存对象,方括号保存数组
  • 使用双引号

php将关联数组转为json数据格式: json_encode(); 需要设置响应头为: text/json

JavaScript可以解析JSON的字符串: eval() 或者 JSON.parse()

//设置data是JSON的字符串格式
	// eval()方法
	eval("("+data+")");
    JSON.parse(data); 

15 跨域

浏览器会拦截跨域,但是服务器与服务器可以跨域

15.1 jsonp跨域

360搜素的智能提示

<div id="app">
	<input type="text" autofocus>
	<ul></ul>
</div>

<script type="text/html" id="tp1">
	<%for(let i = 0; i < obj.result.length; i++){%>
		<li><%=obj.result[i].word%></li>
	<%}%>
</script>
<script type="text/javascript">
function suggest_so(obj){
	html = template('tp1',{obj});
	const ul = document.getElementsByTagName('ul')[0];
	ul.innerHTML = html;
}
(function(){
	// 当input内容变化就会触发
	document.getElementsByTagName('input')[0].oninput = function() {
	const script = document.createElement('script');
	script.src=`https://sug.so.360.cn/suggest?callback=suggest_so&encodein=utf-8&encodeout=utf-8&format=json&fields=word&word=${this.value}&huid=11LyPV%2F40quxRkUykFdCqNwbOzOgMoUO7So0sL8w0LsRc%3D&llbq=A5%2CB5%2CC5%2CD5`;
	document.body.appendChild(script);

};
})();

模拟服务器处理suggest_so(),这个名字可以自定义

const express = require('express');
const server = express();
const path = require('path');
// 静态资源访问服务功能
server.use(express.static(path.join(__dirname,'public')))

server.get('/jd',(req,res) => {
    // 取到客户端getInfo请求的参数
    const getInfo = req.query.callback;
    // 向客户端输出: getInfo("我是京东首页")
    res.send(`${getInfo}("我是京东首页")`);
})
server.listen(3000);

jsonp的跨域,它只支持get方式请求,因为它是使用script标签去发送请求,而且服务端需要做处理,客户端也需要做处理.如果跨域的时候传递的数据非常多,jsonp的方式就不太可取

15.2 cors跨域

如果使用XMLHttpRequest有跨域限制,浏览器的数据接收不了,让服务器给客户端一个响应头Access-Control-Allow-Origin:https://www.jd.com,https://taobao.com,可以把后面的地址换成*,会变成所有的网站都可以

跨域资源共享,它的原理就是在请求服务器的时候,服务器给一个响应头,告诉客户端,这些数据可以访问

通过向客户端输出一个响应头
header("Axxess-Control-Allow-Origin:*"); // 跨域资源共享

这种方式是服务器直接给一个响应头Access-Control-Allow-Origin,告诉客户端浏览器,这些数据可以获取,这个Access-Control-Allow-Origin也是http协议规定的

15.3 jsonp与cors的区别

jsonp是最早的这种跨域解决方案,因为是使用script标签发送请求,所以兼容性比较好,但是只支持get方式

cors是后期的一种解决方案,它只需要改服务器的配置,设置一个响应;客户端不需要做任何处理.

其他方法: 通过后台服务器转发,通过设置代理服务器

16 前后端分离

如果前后端分离,服务端对外提供的都是json格式数据,都是提供的借口哦,提供的接口占用端口对外提供服务,就会存在接口安全问题,谁都可调用接口

解决接口安全问题: 对接口进行认证

  • session认证
  • token认证(令牌)
相关标签: PHP php 后端