php是什么
php中文名:超文本预处理器
变量
变量是一个可以改变的值
$x = 1;
$y = 2;
$z = $x +$y ;
echo $z
php严格区分大小写
php不可以以特殊字符数字为变量名,数字可以在中间或尾部
判断一个变量是否存在
isset($x);
销毁变量
unset($x);
字符串定义语法
单引号双引号的区别
```php
$name = '张三';
$age = 18;
$sex = '男';
```
- 单引号不能解析变量,双引号可以解析变量
- 双引号执行转译字符,单引号不转译\n \r \t \
- 它执行转译\\和’(输出一个\)
- 能使用单引号就不适用双引号,为什么?因为单引号效率要比双引号快
- 如果是字符串和变量一起的时候用.来链接
- 双引号里面插入单引号,单引号里面插入变量,变量会解析"'KaTeX parse error: Expected '}', got 'EOF' at end of input: …量加一组括号使PHP可以识别{a}
- 如果双引号里面插入变量的时候请在后面加上空格或者,号,不然计算机会认为你是一体的或者用大括号包起来
注意,当变量和字符串想在一起的时候用"点"来拼接 - 引号方式:比较适合定义那些比较短(不超过一行)或者没有结构要求的字符串
如果有结构要求,或者内容超过一行,可以使用以下两种结构定义
-
nowdoc字符串:没有单引号的单引号字符串
$str = <<< '边界符' 字符串内容 边界符; 代码示例: $str3 = <<<'EOD' hello EOD;
-
heredoc字符串:没有双引号的双引号字符串
$str = <<<边界符
字符串内容
边界符;
代码示例:
$str = <<< EOD
hello
EOD;
结构化定义字符串变量的规则:
- 结构化定义字符串对应的边界符有条件
- 上边界符后面不能跟任何内容
- 下边界符必须顶格,最左边
- 下边界符同样后面只能跟分号;不能跟任何内容
- 结构化定义字符串的内部(边界符之间)的所有内容都是字符串本身
数据类型
- 标量
2. 整型
1. 1,2,3
3. 浮点型
1. 1.2,2.2,3.3
3. 布尔类型
1. true
2. false
4. 字符串
1. 用单双引号引起来的都是字符串 - 混合类型
- 数组
- array
- 对象
- object
- 数组
- 特殊类型
- 空
- null
- 资源
2. resource
- 空
伪类型
伪类型:假类型,实际上在PHP中不存在的类型。但是通过伪类型可以帮助程序员去更好的查看操作手册从而更方便学习.
伪类型主要有两种:在三大类八小类之外
- Mixed:混合的,可以是多种PHP中的数据类型
- Number:数值的,可以是任意数值类型(整形和浮点型)
常量
define('ABC','abc')
echo ABC;
defined(ABC)#判断常量是否被定义
注意事项
- 不能重复定义
- 常量的名字一般使用大写字幕
- 常量的值只能是标量
- 常量的作用域是全局的
- 输出的时候没有$符号
- 常量不能写到字符串中
系统常量
__FILE__ #当前文档名以及所在路径
__LINE__ #代码所在行
__DIR__ #当前文件所在路径
PHP_OS #获取系统信息
PHP_VERSION #获取版本信息
__FUNCTION__ #获取当前函数名
M_PI #圆周率g'm
__MHTHOD__ #获取当前成员方法名
运算符
-
算术运算法
- (+ - * / %(求模又称取余数))
-
自增自减运算符
- ++ –
-
比较运算符
-
< >= <= == === != !==
== 只判断值而不比较数据的类型 === 比较值和类型
-
-
逻辑运算符
- && 逻辑与 并且有一个为假就是假多个为假的还是假只有同时为真的时候才是真
- || 逻辑或 或者只要有一个为真就是真多个同时为假才是假的
- ! 取反 就是假变成真的真的变成假的
为false几种情况
- 整型的0在进行判断的时候为假,整型的1在判断的时候为真
- 如果浮点的0.0000000都是假的只要后面有一个是非零的数字即为真
- 空字符串为假’'如果中间有一个字符都是真那怕是一个空格
- 空字符串的0即为假其他皆为真
- 空数组为假
- null作为判断条件的时候是假的
函数
function 定义函数的关键字
- 类别
- 类库函数
- is_array() //判断变量的数据类型是否为数组
- is_bool()
- is_float()
- is_int()
- is_null()
- is_numeric //判断变量的数据类型是否为整数或者字符串整数
- is_object()
- is_resource()
- is_string() //注: 如果直接数据结果,成功为1,失败什么都不显示
- 自定义函数
基本语法如下: function([参数]){ //[参数]可有可无 //函数体 //返回值: return结果; } ```·
- 类库函数
- 函数命名规范
- 函数名不区分大小写
- 函数名使用英文,遵循规范
- 下划线不属于特殊符号
- 数字可以加在中间或者后面
- 不用特殊符号
- 命名的时候要有意义
- 遵循驼峰或者下划线
- 不能使用系统函数以及关键字作为函数名
可变函数
可变函数:当前有一个变量所保存到值,刚好是一个函数的名字,那么就可以使用变量+()来充当函数名使用
$变量='display';
function display(){
}
//可变函数
$变量()
代码示例:
//定义函数
function display(){
echo __FUNCTION__;
}
//定义变量
$func = 'display';
//可变函数
$func();
可变函数在系统使用的过程中还是比较多的,尤其是使用很多系统函数的时候:需要用户在外部定义一个自定义函数,但是是需要传入到系统函数内部使用.
代码示例:
将一个用户定义的函数传入给另外一个函数(函数名)去使用的过程,称之为回调过程,而被传入的函数称之为回调函数
//定义系统函数(假设)
function sys_function($arg1,$arg2){
//给指定的函数(第一个参数),求对应的第二个参数值的4次方
//对实际用户输入的数值进行处理
$age2 = $age2 + 10;
return $arg1($arg2); //相当于user_function(20)
}
//定义一个用户函数:求一个数的四次方
function user_function($num){
return $num * $num * $num * $num;
}
//求10的4次方
sys_function('user_function',10);
匿名函数
基本概念
没有名字的函数
基本语法:
变量名 = function(){
//函数体
};
代码示例:
$func = function(){
echo 'hello world';
};
//调用匿名函数
$func();
变量保存匿名函数,本质得到的是一个对象(closure)
闭包
闭包:closure,一词来源于以下两者的结合:要执行的代码块(由于自由变量被包含在代码块中,这些自由变量以及它们引用的对象没有被释放)和为自由变量提供绑定的计算环境(作用域)
简单理解:函数内部有一些局部变量(要执行的代码块)在函数执行之后没有被释放,是因为在函数内部还有对应的函数在引用(函数的内部函数:匿名函数)
//闭包函数
function display(){
//定义变量:局部变量
$name = __FUNCTION__;
//定义匿名函数
$innerfunction = function() use($name){ //use 就是将外部变量(局部)保留给内部使用(闭包)
//函数内部的函数
echo $name;
};
//调用函数
$innerfunction();
}
display();
证明:函数的局部变量在函数使用完只会没有被释放?
- 使用内部匿名函数
- 匿名函数使用局变量:use;
- 匿名函数被返回给外部使用;
function display1(){
//定义变量:局部变量
$name = __FUNCTION__;
//定义匿名函数
$innerfunction = function() use($name){ //use 就是将外部变量(局部)保留给内部使用(闭包)
//函数内部的函数
echo $name;
};
//返回内部匿名函数
return $innerfunction;
}
$closure = display1();
//此行位置: display1函数运行结束:理论上局部变量$name应该已经被释放
$closure();//当前局部变量$name在$closure = display1();这一行display1函数运行结束后并没有被释放,从而在外部调用(也就是此行)内部匿名函数的时候可以被使用
相关函数
字符串相关函数
1. 转换函数: implode(),explode(),st_split()
lmplode(连接方式,数组):将数组中的元素按照某个规则连接成一个字符串,
explode(分割字符,目标字符串):将字符串按照某个格式进行分割,变成数组
str_split(字符串,字符长度):按照指定长度拆分字符串得到数组
2. 截取函数: trim(),ltrim(), rtrim()
trim(字符串,[指定字符]):本身默认是用来去除两边的空格(中间不行),但是也可以指定要去除的内容,是按照指定的内容循环去除两边有的内容:直到碰到一个不是目标字符为止.
ltrim():去除左边的空格
rtrim():去除右边的空格
3. 截取函数: substr(),strstr()
substr(字符串,起始位置从0开始[长度]):指定位置开始截取字符串,可以截取指定长度(不指定到最后)
strstr(字符串,匹配字符):从指定位置开始,截取到最后(可以用来取文件后缀名)
4. 大小转换函数: strtolower(),strtoupper(),ucfirst()
strtolower: 全部小写
strtoupper: 全部大写
ucfirst: 首字母大写
5. 查找函数: strpos(),strrpos()
strpos():判断字符在目标字符串中出现的位置(首次)
strrpos():判断字符在目标字符串中最后出现的位置
6. 替换函数: str_replace()
str_replace(匹配目标,替换的内容,字符串本身):将目标字符串中部分字符串进行替换,
$str = '123a234a3b2a';
str_replace('a','b',$str);
7. 格式化函数: printf(),sprintf()
printf/sprintf(输出字符串有占位符,顺序占位内容):格式化输出数据
$age = 50;
$name = 'TOM';
//格式化输出
echo sprintf("你好,今年我%d岁,我叫%s",$age,$name);
8. 其他: str_repeat(),str_shuffle()
str_repeat():重复某个字符串N次
str_shuffle():随机打乱字符串
作用域
定义: 就是一个变量的作用范围,或者叫做生命周期
- 内部变量
- 就是函数体内声明的变量,内部变量的作用域只在函数体内生效,程序执行完事以后自动销毁(垃圾回收机制)
- 外局变量
- 外部变量就是在函数体外声明的变量,不能在函数体内使用,函数体外的变量名字可以与函数体内的变量名字一样
- 超全局变量
- 外部变量和内部变量是同一个变量
- _GET
- _POST
- _FILE
- $_COOKIE
- $_SESSION
- $GLOBALS
- 外部变量和内部变量是同一个变量
- 静态变量
- static 静态变量关键字
- 在函数内部定义的变量,用来实现跨函数共享数据的变量
- 这个变量只会初始化一次在运行的时候他会记录上一次的值 static变量不会销毁
function 函数名(){ //定义变量 static $变量名 = 值; //通常会在定义的时候就直接赋值 }
global关键字定义的变量可以使内部和外部互相访问
基本语法:
global 变量名; //不能赋值
变量名 = 值; //修改
数组
数组的基本概念
数组:array,数据的组合,指将一组数据(多个)存储到一个指定的容器中,用变量指向该容器,然后可以通过变量一次性得到该容器中的所有数据.
数组定义语法
在PHP中系统提供多种定义数组的方式:
1. 使用array关键字:最常用的
$变量= (array元素1,元素2,元素3..);
2. 可以使用中括号来包裹数据:
$变量 = [元素1,元素2...];
3. 隐形定义数组:给变量增加一个中括号,系统自动变成数组
$变量[]=值1; //如果不提供下标也可以,系统自动生成(数字:从0开始)
$变量[下标]=值; //中括号里面的内容称之为下标key,该下标可以是字母(单词)或者数字,与变量命名的规则相似
PHP数组特点
- 可以整数下标或者字符串下标
- 不同下标可以混合存在
- 数组元素的顺序以放入顺序为准,跟下标无关
- 数字下标的自增长性
- 从0开始自动增长,如果中间手动下标出现较大的,那么后面的自增长元素从最大的值+1开始
- 特殊值下标的自动转换
- 布尔值
- true
- false
- 空
- null
- 布尔值
$arr1[false]=false;
$arr1[true]=true;
$arr1[null]=null;
var_dump($arr1);
结果:
array(3) {
[0]=>
bool(false)
[1]=>
bool(true)
[""]=>
NULL
}
- PHP中数组元素没有类型限制
- PHP中数组元素没有长度限制
- 补充:PHP中的数组是很大的数据,所以存储位置是堆区,为当前数组分配一块连续的内存.
多维数组
多维数组:数组里面的元素又是数组
二维数组
二维数组:数组中所有元素都是一维数组
$arr = array(
array('name'=>'Jim','age'=>30),
array('name'=>'Tom','age'=>28),
array('name'=>'Lily','age'=>20)
);
print_r($arr);
结果:
Array
(
[0] => Array
(
[name] => Jim
[age] => 30
)
[1] => Array
(
[name] => Tom
[age] => 28
)
[2] => Array
(
[name] => Lily
[age] => 20
)
)
### 多维数组
在第二维度的数组元素中可以继续是数组,在PHP中没有维度限制(PHP本质并没有二维数组)
但是不建议使用超过三维以上的数组,会增加访问的复杂度,降低访问效率.
### 异形数组(不规则数组)
异形数组:数组中的元素不规则,有基本变量也有数组在实际开发中并不常用,尽量让数组元素规则化(便于进行访问)
数组遍历
遍历的基本含义
数组遍历:普通数组数据的访问都是通过数组元素的下标来实现访问,如果说数组中所有的数据都需要依次输出出来,就需要我们使用到一些简化的规则来实现自动获取下标以及输出数组元素.
$arr = array(0=>array('name'=>'Tom'),1=>array('name'=>'Jim')); //二维数组
// 访问一维元素:$arr[一维下标]
$arr[0]; //结果:array('name'=>'Tom');
//访问二维元素:$arr[一维下标][二维下标]
$arr[1]['name'];//结果:Jim
foreach遍历原理
foreach遍历的原理:本质是数组的内部有一颗指针,默认是指向数组元素的第一个元素,foreach就是利用指针去获取数据,同时移动指针.
foreach($arr, as $k => $v){
//循环体
}
1.foreach会重置指针:让指针指向第一个元素;
2.进入foreach循环:通过指针取得当前第一个元素,然后将下标取出放到对应的下标变量$k中(如果存在),将值取出来放到对应的值变量$v中;(指针下移)
3.进入到循环内部(循环体),开始执行;
4.重复2和3,直到在2的时候遇到指针取不到内容(指针指向数组最后)
Foreach遍历语法
基本语法:
foreach(数组变量 as [$下标=>] $值){
}
通常:如果是关联数组(字母下标),就需要下标,如果是数字下标就直接访问值
在进行数据存储定义的时候,通常二维数组不会两个维度的key下标都为数字,一般是一维为数字(无意义),二维为字符串(数据库表字段),所以在进行遍历的时候,通常是只需要针对一维进行遍历,取得二维数组元素,然后二维数组元素通过下标去访问。
$arr = ['a'=>'a',='aaa','b'=>'bbb','c'='ccc'];
foreach($arr as $key=>$value){
echo $arr[$key].'<br/>';
}
foreach( $arr as $val){
echo $arr[$val].'<br/>';
}
#list只对索引数组有效
list($a,$b,$c) = $arr;
#each(不过多叙述)
for循环遍历数组
for循环:基于已知边界条件(起始和结束)然后有条件的变化(规律)
因此:for循环遍历数组有对应条件
- 获取数组长度:count(数组)得到数组元素的长度
- 要求数组元素的下标是规律的数字
$arr = array(1,2,3,4,5,6,7,10);
for($i=0,$len=count($arr);$i<$len;$i++){
echo 'key is :',$i,' and value is :',$arr[$i],'</br>';
}
结果:
key is :0 and value is :1
key is :1 and value is :2
key is :2 and value is :3
key is :3 and value is :4
key is :4 and value is :5
key is :5 and value is :6
key is :6 and value is :7
key is :7 and value is :10
运行结束,执行耗时:178毫秒
while配合each和list遍历数组
each函数:each能够从一个数组中获取当前数组指针所指向的元素的下标和值,拿到之后将数组指针下移,同时将掌到的元素下标和值以一个四个元素的数组返回:
0下标->取得元素的下标值
1下标->取得元素的值
Key下标->取得元素的下标值
value下标->取得元素的值
如果each取不到结果(数组指针移到最后),返回false
list函数:list是一种结构,不是一种函数(没有返回值),是list提供一堆变量取从一个数组中取得元素值,然后依次存放到对应的变量当中(批量为变量赋值:值来源于数组):
list必须从索引数组中去获取数据,而且必须从0开始
正确操作:
//list结构
$arr = array(1,2=>1);
list($first) = $arr;
var_dump($first);
结果:
int(1)
错误操作:变量多于数组元素,没有指定从0到指定变量的下标数组元素
//list结构
$arr = array(1,2=>1);
list($first,$second) = $arr; //错误: second变量对应的下标为元素下标1的,但是数组没有
var_dump($first,$second);
结果:
Notice: Undefined offset :1 in *****.php on line 19
int(1)
NULL
因此list与each配合特别好:each一定有两个元素就是0和1下标元素
list(变量1,变量2)=each(数组); //看上去是一种赋值运算,但是可以得到false结果(each取不到正确的结果),整个表达式为false
//while循环
$arr = array(1,'name'=> 'Tom',3,'age'=>30);
// list搭配each
while(list($key,$value)=each($arr)){
echo 'key is :' . $key . 'value is :'.$value.'</br>';
}
结果:
key is :0value is :1
key is :namevalue is :Tom
key is :1value is :3
key is :agevalue is :30
运行结束,执行耗时:1毫秒
数组排序函数
1. 排序函数:对数组元素进行排序,都是安装ASCII码进行比较,可以进行英文比较
sort():顺序排序(下标重排)
asort():升序排序(对键排序)
rsort():逆序排序
asor():顺序排序(下标保留)
arsort():逆序排序
ksort():顺序排序:按照键名(下标)
krsort():逆序排序
shuffle():随机打乱数组元素,数组下标会重排
2. 指针函数
reset():重置指针,将数组指针回到首位
end():重置指针,将数组指针指到最后一个元素
next():指针下移,取得下一个元素的值
prev():指针上移,取得上一个元素的值
current():获取当前指针对应的元素值
key():获取当前指针对应的下标值
注意事项:next和prev会移动指针,有可能导致指针移到最前或者最后(离开数组),导致数组不能使用,不能通过next和prev不能回到正确的位置.只能通过end或者reset进行指针重置
3. 其他函数
count():统计数组中元素的数量
array_push():往数组中加入一个元素(数组后面)
array_pop():从数组中取出一个元素(数组后面)
array_shift():从数组中取出一个元素(数组前面)
array_unshift():从数组中加入一个元素(数组前面)
PHP模拟数据结构:
栈:压栈,先进去后出来(FILO)
//数据结构:栈和队列
$arr = array();
//栈:先压栈后出栈:都是从一端出来
//前面:array_shift/array_unshift
//后面:array_push/array_pop
//压栈
array_push($arr,3);
array_push($arr,2);
array_push($arr,1);
print_r($arr);
//出栈
echo array_pop($arr),array_pop($arr),array_pop($arr);
结果:
Array
(
[0] => 3
[1] => 2
[2] => 1
)
123
队列:排队,先进去的先出去(FIFO)
//队列:先排队,先出来,一端进,另外一端出
//后进前出:array_push/array_shift
//前进后出:array_unshift/array_pop
$arr = array();
//入队
array_unshift($arr,3);
array_unshift($arr,2);
array_unshift($arr,1);
print_r($arr);
//出队
echo array_pop($arr),array_pop($arr),array_pop($arr);
arcray_reverse():数组元素反过来
in_array():判断一个元素在数组中是否存在
array_keys():获取一个数组的所有下标,返回一个索引数组
array_values():获取一个数组的所有值,返回一个索引数组
流程控制
控制分类
- 顺序结构
- 代码从上往下,顺序执行
- 分支结构
- 给定一个条件,同时有多种可执行代码块,然后根据条件执行某一段代码
- 循环结构
- 在某个条件控制范围内,指定的代码块可以重复执行
分支结构
if 分支
if(条件表达式){
//满足条件后执行的代码段;
}else{
//不满足条件执行的代码段;
}
复杂if结构
if(条件表达式1){
//满足条件表达式1的代码段
}elseif(条件表达式2){
//不满足表达式1条件,但是满足条件表达式2的代码段
} else{
//全部不满足条件的代码段
}//可以使用多个elseif
switch分支
switch(条件表达式){
case 值1:
要执行的代码段;
break;
case 值2:
要执行的代码段;
break;
case 值3:
要执行的代码段;
break;
default:
要执行的代码段;
break;
//break表示中断switch(结束)
}
循环结构
- for循环
for(条件表达式1;条件表达式2;条件表达式3){
//条件表达式1:定义初始化条件,可以有多种赋值语句存在,使用逗号分隔即可
//条件表达式2:边界判定,限定循环执行的次数
//条件表达式3:用来执行条件变化
//循环体
}
- while循环
条件初始化;
while(条件表达式){
//条件表达式就是判断边界条件
循环体;//循环条件的变化
}
$i = 1;
while($i <=10){
echo $i;
$i++;
}
- do-while循环
do-while:看着很像while,while首先进行条件判定然后执行循环体,有可能出现第
一次就条件不满足,那么就会直接失败(循环体一次都不执行).
do-while就是先干了再说(先执行循环体).后判断条件(至少会执行一次循环体)
do{
循环体;
}while(条件表达式);
$i = 1;
do{
echo $i;
$i++;
}while($i <=10);
- foreach循环(针对数组)
循环控制
- 循环控制
- 在循环内部对循环本身进行控制
- 中断控制
- 重新开始循环,循环体中还有其他内容,也在执行
- Continue层级; //默认是1(循环可以多层嵌套)
$i = 1; while($i <= 100){ //判断:是否是5的倍数 if($i % 5 !=0 ){ //说明当前$i不是5的倍数 //重新循环 $i++; //重新循环 continue; //系统重新跳到循环开始处 } //输出数值 echo $i++, '<br/> '; }
- 终止控制
- 循环直接结束
- break层级; //默认是1
$i = 1; while($i <= 100){ //判断:是否是5的倍数 if($i % 5 !=0 ){ //说明当前$i不是5的倍数 //重新循环 $i++; //终止循环 break; } //输出数值 echo $i++, '<br/>'; } echo $i;//只循环2次 /* Continue 2;//当前自己循环后面内部不再执行,同时外部循环如果还有循环体也不再执行,重新来过; Break 2;//当前自己循环结束,同时外部也结束(如果还有外部(第三层)不受影响,继续执行) */
流程控制替代语法
流程控制替代语法:分支和循环结构的替代语法
PHP本身是嵌入到HTML中的脚本语言,需要在HTML中书写一些关于判断或者循环的结构语法,必须符合PHP标签规范,需要 HTML与 PHP进行混搭,如果使用原始的PHP代码那么会非常不美观。
<table border=1>
<?php for($i = 1;$i < 10;$i++){?>
<tr>
<?php for($j = 1;$j < $i;$j++){?>
<td>
<?php echo $j .'*' .$i . '= ' .$i*$j;?>
</td>
<?php }?>
</tr>
<?php } ?>
</table>
//在PHP书写到HTML中的这些大括号}非常不美观,所以PHP提供了一种替代机制,让其可以不用书写大括号:
for(;;){ => for(;;):
} =>endfor;
如下:
<table border=1>
<?php for($i = 1;$i < 10;$i++):?>
<tr>
<?php for($j = 1;$j < $i;$j++):?>
<td>
<?php echo $j .'*' .$i . '= ' .$i*$j;?>
</td>
<?php endfor;?>
</tr>
<?php endfor; ?>
</table>
PHP中有哪些替代语法呢?
PHP应该在HTML中只做数据输出,输出通常伴有条件判断和循环操作,因此 PHP提供了对应分支结构和循环结构的替代语法:全部都是对应的一个模式:
左大括号{使用冒号替代:
右大括号}使用end+对应的其实标记替代
- if if(): endif;
- switch 同上
- for 同上
- while 同上
- foreach 同上
文件包含
文件包含:在一个 PHP脚本中,去将另外一个文件(PHP)包含进来,去合作完成一件事情.
文件包含的作用
文件包含的意义:
- 要么使用被包含文件中的内容,实现代码的共享(重用):向上包含(索要)
1.向上包含:在当前脚本要用某个代码之前包含别的文件 - 要么自己有东西可以给别的文件使用,实现代码的共享(重用):向下包含(给予)
- 向下包含:在自己有某个东西的时候,需要别的脚本来显示(自己代码写完之后包含其他文件)
最大的作用:分工协作,每个脚本做的事情不一样,因此可以使用协作方式,让多个脚本共同完成一件事情
- 向下包含:在自己有某个东西的时候,需要别的脚本来显示(自己代码写完之后包含其他文件)
文件包含四种形式
- include:包含文件
- include_once:系统会自动判断文件包含过程中,是否已经包含过(一个文件最多被包含一次)
- require:与include相同
- require_once:与include_once相同
包含基本语法
include '文件名字';
include('文件名字'); //文件名字,注意路径
向上包含:先包含文件,后使用文件的内容
include 'include1.php';
echo $a;
echo $b;
$a = 10;
const PI = 3.14;
向下包含://包含文件为了显示以上数据
include_once 'include4.php'
文件加载原理
- 在文件加载(include或者require)的时候,系统会自动将被包含文件中的代码相当于嵌入到当前文件中
- 加载位置:在哪加载,对应的文件中的代码嵌入的位置就是对应的include位置
- 在PHP中被包含的文件是单独进行编译的
include和require区别
include和include_once的区别:
include系统会碰到一次,执行一次;如果对同一个文件进行多次加载,那么系统就会执行多次
include_once:系统碰到多次也只会执行一次
require和include的区别:本质都是包含文件,唯一的区别在于包含不到文件的时候,报错的形式不一样
include报错是warning,不会阻止代码执行
require要求较高:如果包含出错,代码不再执行(require后面的代码)
算法
编程思想
编程思想:如何利用数学模式,来解决对应的需求问题:然后利用代码实现对应的数据模型(逻辑).
算法:使用代码实现对应的数学模型,从而解决对应的业务问题。
逆推算法
递推算法是一种简单的算法,即通过已知条件,利用特定关系得出中间推论,直至得到结果的算法.递推算法分为顺推和逆推两种.
- 顺推:通过最简单的条件(已知),然后逐步推演结果
- 逆推:通过结果找到规律,然后推到已知条件
斐波那契数列: 1 1 2 3 5 8 13 …
通常需求:请求得指定位置N所对应的值是多少
找规律:
- 第一个数是1
- 第二个数也是1
- 从第三位开始:属于前两个数的和
代码解决思路:
- 如果数字位置为1和2,结果都是1
- 从第三个开始,想办法得到前两个的结果,就可以得到
终极解决办法:想办法把要求的位置之前的所有的值都出来,那么要求的数就可以通过前两个之和计算出来:使用数组存储所有结果即可。
//递推思想(算法)
//需求:规律1 1 2 3 5 ...
//求出指定位数对应的值
//已知条件:第一个和第二个数都为1,第三个开始为前两个之和
function my_recursive($des){
//判断:如果为第一个或第二个直接返回结果
if($des==1||$des==2) return 1;
//开始计算:
$f[1] =1;
$f[2]=1; //如果想要第一个或者第二个结果,那么可以直接给出
for($i=3;$i<=$des;$i++){
$f[$i]=$f[$i-1]+$f[$i-2];
}
//返回结果
return $f[$des];
}
//调用函数并查看结果
echo my_recursive(10);
结果:55
递归算法
递归算法是把问题转化为规模缩小了的同类问题的子问题.然后递归调用函数(或过程〉来表示问题的解.
- 简化问题:找到最优子问题(不能再小)
- 函数调用自己
斐波那契序列:1 1 2 3 5 8 13…
需求:求指定位置的数列的值
规律:第一个和第二个为1,从第三个开始为前两个之和
假设:
F(N) = F(N-1)+F(N-2);
F(N-1) = F(N-1)+F(N-3);
···
F(2)=F(1)=1
递归思想中:有两个非常重要的点
递归点:发现当前问题可以有解决当期问题的函数,去解决规模比当前小一点的问题来解决
F(N) = F(N-1)+F(N-2);
递归出口:当问题解决的时候,已经到达(必须有)最优子问题,不能再次调用函数
如果一个函数递归调用自己而没有递归出口:就是死循环
递归的本质是函数调用函数:一个函数需要开辟一块内存空间,递归会出现同时调用N多个函数(自己):递归的本质是利用空间换时间
//递归思想
//递归一定有函数
function recursion($n){
//递归出口
if($n == 1 || $n == 2 ) return 1;
//递归点:求N的值,与求N-1的值一模一样,只是N-1的规模比N小
return recursion($n-1)+recursion($n-2);
}
echo recursion(3);
数组排序算法
冒泡排序
冒泡排序(Bubble Sort),是一种计算机科学领域的较简单的排序算法.
它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成.
冒泡排序的算法思路:
- 比较相邻的元素.如果第一个比第二个大,就交换他们两个.
- 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对.在这一点,最后的元素应该会是最大的数.
- 针对所有的元素重复以上的步骤,除了最后一个.
- 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较.
//数组排序算法:冒泡排序
$arr = array(1,4,2,9,7,5,8);
//2.想办法让下面可以每次最大值的代码重复执行
for($i=0,$len = count($arr);$i<$len;$i++){
//1. 想办法将最大的值放大最右边
for($j = 0; $j < $len - 1-$i;$j++){
//判断:两两相比
if($arr[$j]>$arr[$j+1]){
//左边比右边大:交换
$temp = $arr[$j];
$arr[$j] = $arr[$j+1];
$arr[$j+1] = $temp;
}
}
}
echo '<pre>';
print_r($arr);
结果:
Array
(
[0] => 1
[1] => 2
[2] => 4
[3] => 5
[4] => 7
[5] => 8
[6] => 9
)
选择排序
选择排序(Selection sort)是一种简单直观的排序算法.它的工作原理是每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完。选择排序是不稳定的排序方法(比如序列[5,5,3]第一次就将第一个[5]与[3]交换,导致第一个5挪动到第二个5后面).
选择排序的算法思路:
- 假设第一个元素为最小元素,记下下标.
- 寻找右侧剩余的元素,如果有更小的,重新记下最新的下标.
- 如果有新的最小的,交换两个元素.
- 往右重复以上步骤,直到元素本身是最后一个.
//数组排序算法:选择排序
$arr = array(1,5,2,9,6,3,4);
//1.确定要交换多少次:一次只能找一个最小的,需要找数组长度对应的次数
for($i=0,$len=count($arr);$i<$len;$i++){
//2.假设当前第一个已经排好序
$min = $i; //当前第一个数是最小的
//3.拿当前最小的去比较剩余的其他数
for($j=$i+1;$j<$len;$j++){
//4.比较:比较当前元素与选定的最小的元素
if($arr[$j]<$arr[$min]){
//说明当前的$min不合适
$min = $j;
}
}
//5.交换当前选定的值与实际最小的元素值
if($min != $i){
$temp = $arr[$i];
$arr[$i]=$arr[$min];
$arr[$min]=$temp;
}
}
echo '<pre>';
print_r($arr);
结果:
Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
[4] => 5
[5] => 6
[6] => 9
)
插入排序
插入排序(Insert sort),插入排序的基本操作就是将一个数据插入到已经排好序的有序数据中,从而得到一个新的、个数加一的有序数据,算法适用于少量数据的排序,是稳定的排序方法.插入算法把要排序的数组分成两部分:第一部分包含了这个数组的所有元素,但将最后一个元素除外(让数组多一个空间才有插入的位置),而第二部分就只包含这一个元素(即待插入元素).在第一部分排序完成后,再将这个最后元素插入到已排好序的第一部分中.
插入排序的基本思想是:每步将一个待排序的纪录,按其关键码值的大小插入前面已经排序的文件中适当位置上,直到全部插入完为止.
插入排序的算法思路:
-
设置监视哨r[0],将待插入纪录的值赋值给r[0];
-
设置开始查找的位置j;
-
在数组中进行搜索,搜索中将第j个纪录后移,直至r[0].kex>=r[j].key为止;
-
将r[0]插入r[j+1]的位置上.
-
认定第一个元素已经排好序;
-
取出第二个元素,作为待插入数据;
-
与已经排好序的数组的最右侧元素开始进行比较
-
如果后面的小于前面的:说明前面已经排好序的那个数组元素不在对的位置(向后移一个),然后让新的元素填充进去(继续向前比:高级)
-
重复前面的步骤:直到当前元素插入到对位置;
-
重复以上步骤,直到所有的数组元素都插入到对的位置.
//数组排序算法:插入排序
$arr = array(4,2,6,8,9,5);
//1、确定要插入多少回(假设一个数组一次性插入到对的位置,同时第一个位置是假设对的)
for($i = 1,$len = count($arr);$i< $len;$i++){
//2、取出当前要插入的元素的值
$temp = $arr[$i];
//3、让该数据与前面已经排好序的数组元素重复比较(挨个比较),直到的位置(交换)
for($j =$i - 1;$j >= 0;$j--){
// 4、比较
if($arr[$j] >$temp){
//说明当前要插入的元素,比前面的已经排好序的元素的值要小:交换位置
$arr[$j+1] = $arr[$j];
$arr[$j] = $temp;
}else{
//说明当前待插入元素,比前面的元素要大:说明位置正确
break;
}
}
}
echo '<pre>';
print_r($arr);
结果:
Array
(
[0] => 2
[1] => 4
[2] => 5
[3] => 6
[4] => 8
[5] => 9
)
快速排序
快速排序(Quicksort)是对冒泡排序的一种改进.通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列.(递归)
设要排序的数组是 A[0]……A[N-1],首先任意选取一个数据(通常选用数组的第一个数)作为关键数据,然后将所有比它小的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一趟快速排序.值得注意的是,快速排序不是一种稳定的排序算法,也就是说,多个相同的值的相对位置也许会在算法结束时产生变动
快速排序的算法是:
- 从数组中选出一个元素(通常第一个),作为参照对象.
- 定义两个数组,将目标数组中剩余的元素与参照元素挨个比较:小的放到一个数组,大的放到另外一个数组.
- 第二步执行完之后,前后的数组顺序不确定,但是确定了自己的位置.
- 将得到的小数组按照第1到第3部重复操作(子问题).
- 回溯最小数组(一个元素).
//PHP数组排序:快速排序
$arr = array(5,6,3,4,9,2,7,8);
//快速排序
function quick_sort($arr){
//递归出口
$len = count($arr);
if($len <= 1) return $arr;
//取出某个元素,然后将剩余的数组元素,分散到两个不同的数组中
$left = $right =array();
for($i=1;$i<$len;$i++){
//第一个元素作为比较元素
//比较:小的放left中,大的放right中
if($arr[$i]<$arr[0]){
$left[]=$arr[$i];
}else{
$right[]=$arr[$i];
}
}
//$left和$right数组没有排序好:递归点
$left = quick_sort($left);
$right = quick_sort($right);
//合并三个"数"组
return array_merge($left,(array)$arr[0],$right);
}
print_r(quick_sort($arr));
结果:
Array
(
[0] => 2
[1] => 3
[2] => 4
[3] => 5
[4] => 6
[5] => 7
[6] => 8
[7] => 9
)
归并排序
归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用.将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序.若将两个有序表合并成一个有序表,称为二路归并
二路归并实现:
$arr1 = array(1,3,5);
$arr2 = array(2,4,6);
//取出一个空数组用于归并空间
$arr3 = array();
while(count($arr1)&&count($arr2)){
//只要$arr1和$arr2里面还有元素,就进行循环
//取出每个元组的第一个元素:进行比较
$arr3[] = $arr1[0]<$arr2[0]?array_shift($arr1):array_shift($arr2);
}
//合并结果
print_r(array_merge($arr3,$arr1,$arr2));
结果:
Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
[4] => 5
[5] => 6
)
归并排序的算法是:
- 将数组拆分成两个数组
- 重复步骤1将数组拆分成最小单元
- 申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
- 设定两个指针,最初位置分别为两个已经排序序列的起始位置
- 比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
- 重复步骤3直到某一指针超出序列尾
- 将另一序列剩下的所有元素直接复制到合并序列尾
$arr=array(4,7,2,1,5,9,3);
//归并排序函数
function merge_sort($arr){
//递归出口
$len = count($arr);
if($len<=1) return $arr;
//拆分
$middle = floor($len/2);
$left = array_slice($arr,0,$middle);
$right = array_slice($arr,$middle);
//递归点:$left和$right都没有排好序:而且可能是多个元素的数组
$left = merge_sort($left);
$right = merge_sort($right);
//假设:左边和右边都已经排好序了
$m = array();
while(count($left)&&count($right)){
//只要$arr1和$arr2里面还有元素,就进行循环
//取出每个元组的第一个元素:进行比较
$m[] = $left[0]<$right[0]?array_shift($left):array_shift($right);
}
//返回结果
return array_merge($m,$left,$right);
}
print_r(merge_sort($arr));
结果:
Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
[4] => 5
[5] => 7
[6] => 9
)
查找算法
查找算法含义
查找是在大量的信息中寻找一个特定的信息元素,在计算机应用中,查找是常用的基本运算.查找算法是指实现查找过程对应的代码结.就是在大型数组中去快速定位想要的元素.
顺序查找算法
顺序查找也称为线形查找,从数据结构线形表的一端开始,顺序扫描,依次将扫描到的结点关键字与给定值k相比较,若相等则表示查找成功;若扫描结束仍没有找到关键字等于k的结点,表示查找失败.
//顺序查找
$arr = array(1,3,6,8,23,68,100);
//顺序查找:v哦那个数组第一个元素快速,挨个匹配
function check_order($arr,$num){
//全部匹配
for($i=0,$len=count($arr);$i<$len;$i++){
//判断
if($arr[$i] == $num){
return $i+1;
}
}
return false;
}
var_dump(check_order($arr,1));
结果:
int(1)
二分查找算法
二分查找要求线形表中的结点按关键字值升序或降序排列,用给定值k先与中间结点的关键字比较,中间结点把线形表分成两个子表,若相等则查找成功;若不相等,再根据k与该中间结点关键字的比较结果确定下一步查找那个子表,这样递归进行,直到查找到或查找结束发现表中没有这样的结点.
折半算法思路:
- 计算数组长度;
- 确定左右两边的指针位置;
- 找到中间位置;
- 匹配;
- 然后根据大小重定边界;
//二分查找算法
$arr = array(1,3,6,8,23,68,100);
function check_break($arr,$res){
//1.得到数组的边界(长度)
$right = count($arr);
$left = 0;
//2. 循环匹配
while($left<=$right){
//3.得到中间位置
$middle = floor(($right+$left)/2);
//4.匹配数据
if($arr[$middle]==$res){
return $middle+1;
}
//5.没有找到
if($arr[$middle]<$res){
//值在右边
$left=$middle+1;
}else{
//值在左边
$right = $middle-1;
}
}
return false;
}
var_dump(check_break($arr,3));
结果:
float(2)
文件操作
1、创建文件夹: mkdir("文件夹路径");
2、删除文件夹: rmdir("文件夹路径");
3、判断文件夹是否存在: is_dir("文件夹路径");
4、打开文件: fopen("文件路径",参数); 参数:r只读 w写入 x创建写入
5、关闭文件: fclose("文件路径");
6、读取文件: fread("文件路径",length);
7、写入文件: fwrite("文件路径",内容);
数据库
- 修改配置文件: php.ini文件中: ;extension=mysqli”,将分号去掉
- php无法直接连接数据,需要扩展: mysqli、PDO
- mysqli用法:
1、建立连接:
(1)、快速写法:
$mysqli = new mysqli ( $server, $username, $password, $dbname );
(2)、兼容写法:
$mysqli = new mysqli ( $server, $username, $password );
mysqli_select_db ( $mysqli, $dbname );
(3)、对象写法:
$mysqli = new mysqli ();
$mysqli->connect ( $server, $username, $password );
$mysqli->select_db ( $mysqli, $dbname );
2、建立连接所需参数:
$server = "127.0.0.1";
$dbname = "数据库名字";
$port = "3306";//可以不写,默认端口就是3306
3、执行sql语句 :
$result = mysqli_query(连接对象,sql语句);//$result:执行sql语句后得到的结果集
4、解析结果集:
(1)、fetch_assoc(): 以关联数组方式返回一行数据 ["key"=>"value"]
while($row = $result->fetch_assoc()) {//$row 每一行数据
echo "从数组$row中取出利用key取出value:".$row["key"];
}
(2)、fetch_row(): 以索引数组方式返回一行数据 [value1,value2...]
取值方法: $row = $result->fetch_row(); $row[index];
(3)、fetch_array(): 以数组方式返回一行数据
取值方法: 同assoc一样
(4)、fetch_object(): 以对象方式返回一行数据 {属性:值}
取值方法: $row = $result->fetch_object(); $row->属性名;
5、结果集属性:
(1)、num_rows:查询出来结果集的行数 $result->num_rows;
(2)、field_count:结果集总列数 $result->field_count;
(3)、affected_rows:指增,删,改的时候受影响的行数 $result->affected_rows;
(4)、insert_id:插入数据时最后1条数据的id值 $result->insert_id
6、关闭连接: mysqli_close($mysqli);
四、PDO使用
1、链接数据库: $pdo = new PDO("mysql:host=localhost;dbname=库名",用户名,密码);
2、执行sql语句
(1)、$result = $pdo->query(sql); query方法通常用来执行查询
(2)、$row = $pdo->exec(sql); exec方法用来执行增删改,返回受影响行数
(3)、预处理语句: 为了减轻服务器压力,先发送带有占位符的sql语句给服务器,再将参数给服务器
$sql = "select * from userinfo where username = ? and password = ?";
$stmt = $pdo->prepare($sql); //将sql语句发送给服务器,服务器返回预处理结果
$username = "wjk"; $password = "123";
$stmt->bindParam(1,$username); //bindParam方法第二个参数,必须传递变量
$stmt->bindParam(2,$password);
$stmt->bindValue(1,"wjk"); //bindValue方法第二个参数,可以直接写值
$stmt->bindValue(1,"123");
$result = $stmt->execute();//执行sql语句,返回true或false
(4)、pdo解析结果集
$result->fetch(PDO::FETCH_ASSOC); //以关联式数组返回数据
$result->fetch(PDO::FETCH_NUM); //以索引数组返回数据
$result->fetch(PDO::FETCH_OBJ); //以对象返回数据
fetchAll: 用法同上,返回所有行数
fetchColumn(第几列) :返回第几列数据