PHP学习笔记 PHP基础1、PHP介绍PHP是一种运行在服务器端的HTML脚本/编程语言主要作用是编写动态网页。PHP的底层语言是C语言与Python类似PHP的很多功能是由加载拓展实现的。2、PHP环境搭建1、下载PHPPHP的目录结构主要有PHP解释器、PHP拓展包、PHP配置文件development 开发板 production 生产板、和php.exe。其中php.exe的作用为解析php代码转变为HTMLd代码从而让浏览器可以解析操作方式为打开命令行终端移动到PHP所在路径输入 php.exe -f 所需要解析的PHP文件路径2、web服务器加载PHP模块1、加载PHP模块在Apache的主文件中加载PHP提供的模块在Apache的httpd.conf文件中LoadModule中配置LoadModule php版本号_module PHP所提供的模块链接所在路径2、Apache分配工作给PHP模块通过文件后缀来分配,在httpd.conf中添加AddType appliaction/x-httpd-php .php3、将php配置文件加载到Apache配置文件中在httpd.conf中加载PHP配置文件:PHPIniDir PHP安装路径php.ini文件默认不存在是以development和production格式存在需要格式化在PHP文件中找到php.ini-development复制一份文件并将其后缀修改为.ini因为上面的步骤已经将PHP已经被Apache加载意味着php.ini修改需要Apache重启才能生效3、PHP连接数据库PHP本身不具备MySQL等数据库能力需要借助PHP操作MySQL拓展PHP加载MySQL拓展在php.ini文件中找到extension去除mysql拓展前的封号增加指定拓展所在路径在php.ini文件中找到extension_dir增加拓展路径即PHP中的ext文件拓展是否配置成功使用phpinfo()函数确认4、设定PHP系统时区在php.ini中找到date.timezone新增date.timezone PRC(代表中国时区)5、设置虚拟主机如果只在一台服务器上只配置一个网站那非常浪费因此需要虚拟主机的技术使得一台主机可以配置多个网站。虚拟主机Virtual machine可以提供真实主机功能但不是真的主机在Apache中配置虚拟主机可以分为基于IP的虚拟主机一台主机有多个IP每个IP对应一个网站。实现在一台主机上安装多张网卡一张网卡绑定一个IP基于域名的虚拟主机一台主机只有一个IP但一个IP下有多个网站每个网站有不同的名字虚拟主机名用户需要在URL里表明名字让Apache进行匹配3、PHP语法基础1、PHP代码格式PHP标记PHP代码可以嵌入到HTML中但为了让浏览器区分PHP脚本需要将PHP脚本进行标记标记的方式有ASP标记% php代码 %短标记? php代码 ?以上两种基本弃用脚本标记script languagephp php代码 /script标准标记最常用?php php代码 ?PHP注释和分隔符PHP的代码注释方式与C相同行注释使用#或//,区块注释使用/*注释的内容*/PHP语句使用;作为分隔符让系统判断语句结束位置2、变量PHP中定义不需要关键字或赋值如$aPHP中变量可以删除用来释放内存语法为unset($变量)PHP中的变量名必须以$开头可以是$字母、数字、下划线的组合但不能以数字开头PHP中还有一些预定义变量即系统定义好的变量用来存储用到的数据预定义变量数值类型都为数组自定义的变量名不能与这些预定义的变量重名常用的预定义变量有$_GET:获取所有表单以get方式提交的数据$_POST:GET提交的数据$_REQUEST:GET和POST提交的信息$_GLOBALS:PHP中所有的全局变量$_SERVER:服务器信息$_SESSION:session会话数据$_COOKIE:cookie会话数据#_ENV:环境信息$_FILES:用户上传的文件信息如果赋给一个变量的值刚好为另外一个变量的名则这个变量为可变变量可以在上一个变量前加一个$去调用另外一个变量$ab; $b可变变量; echo ($$a);3、常量PHP定义常量的方式两种define(常量名常量值)const 常量名 常量值常量命名不要在前加$不然系统就认为这个是变量常量的命名规则与变量基本相同一般为全大写字母为主但也可以使用特殊符号但名字有特殊符号的常量只能用define命名。常量的命名一般不区分大小写可以通过define区分但不推荐常量一般可以直接访问但名字为特殊符号的常量需要用constant来访问系统帮助用户定义了一些常量叫做系统常量用户可以直接使用例如PHP_VERSIONPHP版本PHP_INT_SIZEint类型所占字节PHP_INT_MAXint类型能表示的最大值PHP中还有些常量称为魔术常量其值会随着环境改变而改变但用户无法改变魔术常量命名一般以双下划线常量名双下划线4、数据类型PHP中的数据类型与C一致有简单数据类型整形int/integer,4字节整形如100这种数字表示十进制前面加0b,如0b100表示是二进制前加0如0100表示是八进制前加0x如0x100表示是十六进制PHP默认输出都自动转换为十进制浮点型:float/double8字节也可存储整形存不下的整数字符串型string布尔型:bool/boolean复合数据类型对象类型:object数组类型array特殊数据类型资源类型:resource空类型NULL不可运算PHP中的类型转换方式有两种自动转换系统根据自己需求转换例如布尔值false值为0true值为1字符串以在字母开头值为0以数字开头值为在第一个字母前的数字大小强制转换语法为(数据类型)变量若要将变量转换为NULL类型则需要unset()PHP可以用语句判断数据类型方式为is_数据类型变量名如果一致则返回ture否则返回falsegettype(变量名)返回与变量一致的数据类型的字符串settype(变量名)设置变量数据类型与强制转换不同强制转换只是单纯对原数据值进行处理不改变原来变量指向的值而settype直接改变变量指向的值5、运算符PHP的运算符包含赋值、算数、逻辑运算符等还包括连接运算符将字符串进行拼接的符号. :将两个字符串拼接.:将两个字符串拼接并重新赋值给左边错误抑制符添加到一段代码前若产生错误则不进行报告在代码前加6、分支结构PHP中的分支语句包括if和switch语句if语句语法为if(条件表达式1){执行的代码}elseif(表达式2){执行的代码}……else{执行的代码}switch语句的语法为switch(条件表达式){case 值1需要执行的代码break;case 值2需要执行的代码;break;……default需要执行的代码;break;}7、循环结构PHP循环结构语句有:for语句、While语句、do-while语句for循环的语法为For(初始化语句结束循环判定语句条件变化语句){循环执行的代码}while循环的语法为While(条件表达式){循环执行的代码}do-while循环语法为Do{循环结构}while(条件执行语句)循环可以通过continue和break来进行循环控制由于PHP是内嵌到HTML里的代码如果直接在HTML里写原来的流程控制语句会不美观因此PHP提供了一种代替机制可以不使用大括号左大括号{:用冒号替代右大括号}用end对应的控制语句替代!--不使用代替语句输出九九乘法表-- p九九乘法表/p table border1 ?php $x1; ? ?php for($i1;$i10;$i){ ? ?php $j0; ? /tr ?php for($j$x;$j 10;$j){ ? td?php echo $i.X.$j..$i*$j;?/td ?php }? /tr ?php $x; ? ?php } ? /table !--使用代替语句输出九九乘法表-- p九九乘法表/p table border1 ?php $x1; ? ?php for($i1;$i10;$i): ? ?php $j0; ? /tr ?php for($j$x;$j 10;$j): ? td?php echo $i.X.$j..$i*$j;?/td ?php endfor;? /tr ?php $x; ? ?php endfor; ? /table8、文件包含文件包含指在一个PHP脚本中将另外一个文件PHP包含进来实现代码的重用。让多个脚本协作完成一项工程。在PHP中被包含的文件是单独编译的PHP中文件包含有四种形式分别为include:包含文件,系统碰到一次执行一次include_once系统判断包含的文件之前是否被包含过限定一个文件只能被执行一次require:与include一致require_once:与include_once一致require与include使用基本一致区别在于如果包含文件的代码如果错误require报错形式与include不一样include包含文件代码出错则会不执行包含文件但继续往下执行代码但require包含文件代码错误则不再执行require以后的代码9、函数PHP中函数语法格式如下function 函数名参数{函数体}静态变量PHP中可以使用static修饰变量用于实现跨函数数据共享函数在调用时会自动跳过static这一行。静态变量可用于统计函数被调用的次数统筹函数在第几次调用时的结果递归函数里常用可变函数一个变量所保存的值与一个函数名相同则这个函数称为可变函数可以使用变量名去调用该函数回调函数将一个函数作为参数传给另外一个函数则这个函数称为回调函数闭包若一个父函数内部有子函数子函数为匿名函数若使用use(变量名)将子函数之外父函数的变量给子函数使用这个过程称为闭包伪类型实际上不存在与PHP的类型见于操作手册用于辅助理解的伪类型包括Mixed混合类型代表PHP中的所有类型Number:数值类型可以是整形或浮点型系统常用函数系统常用函数有print():输出函数与echo类似本质是一种结构不是函数返回1括号可不加print_r():与var_dump类似只会输出值不会输出数据类型date()按照指定格式对应的时间戳从1970年1月1日0时0分0秒起到目前或指定时间事件的秒数time:获取当前时间的时间戳microtime()获取微秒级别的时间strtotime():将指定格式表示时间的字符串转换为时间戳max()指定参数中最大的值min()指定参数的最小值rand()得到一个指定区间的随机整数mt_rand()与rand()一样但效率更高建议使用这个ceil()向上取整floor()向下取整pow(a,b)取a的b次幂abs():绝对值sqrt():求平方根function_exists()判断指定函数名字是否在内存中存在增加代码安全性func_get_arg()在自定义函数中获取指定数值对应的参数func_get_args()获取自定义函数的所有参数func_num_args()获取自定义函数的参数数量10、错误处理在开发中需要完全反馈错误信息以调试代码而在实际生产环境中根据最小化反馈信息的原则一般需要不抛出或只抛出一点点错误信息而又要保存错误日志让后台的程序员去修改那需要配置PHP文件或者在代码中使用ini_set设置。配置设置方法为在php.ini中找到log_errors将其赋值为on找到error_log指定错误日志保存路径也可以自定错误处理PHP系统提供了一种用户处理错误的机制用户自定义错误处理函数将该函数增加到系统错误句柄中系统读到错误时会使用用户的函数将用户自定义的函数放到系统中set_error_handle的步骤为自定义错误函数其中包括五个参数变量名建议与操作手册的命名一样errno错误代号;errstr错误提示;(前两个自定义函数中必须存在)errfile错误文件路径;errline 发生错误的代码位置;errcontext注册自定义函数修改错误机制set_error_handle(自定义函数)?php //自定义错误函数 function my_error_handler( $errno, $errstr, $errfile, $errline) { if(!(error_reporting()$errno)){ return false; }//首先将系统本不会处理的报错排除在外 switch($errno){ case E_ERROR: echo系统错误; break; case E_WARNING: echo 系统警告; break; case E_USER_ERROR: echo 用户错误; break; case E_USER_WARNING: echo 用户警告; break; default: echo 其他错误; }//然后对于报错分别处理 } $a; echo $a; set_error_handler(my_error_handler);//将自定义错误放入系统 echo $a; ?11、字符串字符串可以用单引号或双引号定义这种定义方式适合不超过一行或者没有结构的字符串若是定义长字符串或者有结构的字符串可以用一下两种结构化方式定义heredoc结构相当于双引号结构变量边界符字符串边界符nowdoc结构相当于单引号结构变量‘边界符’字符串边界符结构化定义字符串规则上边界符不能跟任何内容下边界符必须顶格且后边不可跟任何内容转义字符PHP中也有转义字符一般为\后加转义符号单引号字符串无法转义\而双引号字符串无法转义\双引号定义的字符串可以识别$从而可以解析变量但单引号不行字符串常用函数strlen()得到字符串的字节数中文占用3字节加载mbstring拓展可以得到很多关于字符串的函数mb_string:获得不同字符集下多字节字符串的长度需要指定字符串格式mb_string(字符串格式)implode()将数组中的元素按照指定规则连接成字符串implode(连接方式数组)explode()将字符串按照指定格式分割成数组explode(分割字符字符串)str_split():将字符串按照指定长度分割成数组str_split(长度字符串)trim()去除字符串两边的空格也可以指定去除两边指定的内容直到碰到第一个非目标字符substr()截取指定位置和指定长度的字符串strtoupper()将字符全转换为大写strtolower()将字符串全转换为小写uc_first()将字符串首字母转换为大写strpos()查找指定字符在字符串中首次出现的位置若没找到则返回falsestrrpos()查找指定字符在字符串中最后一次出现的位置若没找到则返回falsestr_replace()将字符串指定字符替换为指定的其他字符str_repalce(指定字符替换字符)printf()/sprintf()格式化输出字符串sprintf(输出的包含占位符的字符串占位符对应的变量)str_repeat()重复字符串N次str_shuffle()随机打乱字符串12、数组PHP中提供了多种定义数组的方法$变量array元素1元素2……);或者array(key1value1,……)$变量[元素1元素2……]隐形数组$变量[]值1$变量[下标]值//下标可以是字母、数字若不提供下标则系统自动从0开始标PHP的数组有自己的一些特点PHP数组可以是整数下标或者字符串下标也可以同时有字母和数字纯数字下标的数组称索引数组、纯字母下标的数组称关联数组、字母数字下标的数组称混合数组数组的元素顺序与放入数组的顺序为准与下标无关PHP数组拥有自增长特性默认从0开始1增长但若中间手动添加一个较大下标则按最大的数开始自动增长PHP数组的下标相当于JS或python里字典的键名下标对应的元素相当于键值特殊字符不可用作下标若用成下标则会自动转换如false转换为0true转换为1NULL转换为空字符串PHP数组没有类型和长度限制多维数组二维数组的定义方法可以是array(array(),array(),……)多维数组指第二维的元素还是数组PHP数组没有维度限制因为PHP的数组不是真正意义上的数组但不推荐超过三维异性数组数组元素不规则有是数组也有不是数组的可以但不常见数组遍历因为PHP数组下标不规则所以需要一些简化规则自动获取下标并访问元素使用foreach遍历,语法为foreach($数组变量 as [$下标] $值){}索引数组一般无需获取下标而关联数组一般要获取下标foreach的原理是利用数组内部的指针该指针默认指向第一个元素在利用指针获取数据的同时移动指针如果之前操作过指针foreach会将指针重置到指向第一个元素使用for循环遍历数组for循环遍历要求数组元素下标必须是规律的数字语法为for($i0;$icount(数组)i){}使用whileeach或list遍历each函数PHP7.2之后弃用:可以从一个数组中获取当前指针指向的数组下标和值并以一个四个元素的数组返回如果数组指针指向数组最后则返回false分别为0下标-取得元素的下标值1下标-取得元素的值key下标-取得元素的下标值value下标-取得元素的值list函数是一个结构因此没有返回值list提供一堆变量依次取得数组的元素并赋值给这些变量list只能从索引数组获取数据且数组第一元素的索引必须是0语法为:list($变量1$变量2,……)list中变量个数必须小于等于数组$arr array(1,nametom,age18); foreach ($arr as $k $v) { echo. $k .. $v .; } echobr; $nums [0,1,2,3,4,5,6,7,8]; for($i 0; $i count($nums); $i) { echo $i; } echo br;数组函数常见的数组函数有排序函数也可以排序字符串按字符串首字母的Ascall码值进行排序sort()将数组元素顺序排序会改变原元素的下标rsort()将数组元素逆序排序asort()将数组函数顺序排序不改变原元素下标ksort()按照数组键名下标顺序排序krsort()按照数组键名下标逆序排序shuffle()随机打乱数组元素指针函数reset()将数组指针回到指向第一个元素end()将数组指针拨到指向最后一个元素next()将数组的内部指针下移一位返回下一个指向元素的值prev()指针上移取得上一个元素值;next和prev可能导致指针移除数组且语法移回此时需要end或reset重置指针current()取得当前指针指向的元素值key()获取当前指针指向的元素下标其他函数count()统计数组中元素的数量array_push()往数组末尾加入一个元素array_pop()取出数组末尾的元素array_shift()取出数组头部的元素array_unshift()往数组头部加入一个元素array_reverse()将数组转置in_array()判断一个元素是否在数组中array_keys()获取一个数组所有下标返回一个索引数组array_values()获取一个数组所有值返回一个索引数组13、算法基础递推算法递推算法是指通过已知条件利用特定关系得出中间结论直至得到结果递推算法有顺推和逆推两种顺推通过已知条件推演结果逆推通过已知结果得到条件递归算法递归算法就是讲一个问题转换为多个同类问题的子问题然后调用函数表示问题的解递归函数指函数的返回值是函数本身递归算法分为以下几步简化问题找到最优子问题即不可再缩小范围的问题调用函数让函数自己调用自己当一个问题可以用递归函数解决时那么这个问题一定有两个点递归点发现当前问题有一个小一点的子问题可以用函数解决递归出口当问题解决时已经到达最优子问题可以设立递归结束条件结束递归在写代码时先写递归出口递归的优缺点因为会同时调用N多个函数因此会占用内存但执行更快是一种空间换时间的方法例如斐波那契数列、爬楼梯等问题都用到递归?php //爬楼梯问题设有一个台阶可以一次爬一级也可以一次爬两级当一个台阶阶数为n时请问总共有几种爬法 //找规律当台阶的阶数和方法数关系对应为 /* 1 1 2 2 3 3 4 5 …… */ //发现到第N阶楼梯的方法数F(N)等于前N-1级台阶方法数F(N-1)和前N-2级台阶方法数F(N-2)的和直到拆分到N2和N1为止 //例如一个9级台阶的方法数等于8级台阶和7级台阶的和8级台阶等于7级台阶和6级台阶的和…… //这样可以写函数 function stair($n){ if($n1){ return 1; } elseif($n2){ return 2; }//先写递归中止条件即递归出口 return stair($n-1)stair($n-2);//在写递归点即将这个大问题分割为小问题的方法 } echo stair(3); ?排序算法排序算法有冒泡排序、选择排序、插入排序、快速排序和并归排序冒泡排序冒泡排序属于简单的排序算法重复走过需要排序的数列一次比较两个元素如果顺序错误则交换两个元素的位置每一次能确定一个最大/最小的泡放置在数组末尾之后对剩余元素重复以上步骤直到没有任何一对数字顺序错误//冒泡排序 function bubble_rsort($array){ for($i 0;$icount($array);$i){ for($j0;$jcount($array)-1;$j){ if($array[$j]$array[$j1]){ $x$array[$j];//交换两个元素的值创建一个中间变量方便交换 $array[$j]$array[$j1]; $array[$j1]$x; } } } return $array; }//将一个数组从大到小排列 $arr[1,4,6,9,1,2,5,7,9,1]; print_r(bubble_rsort($arr));选择排序比冒泡排序效率更高的一种排序方法用到选择函数初始假设数组中数组最前端的元素A为数组中最大/最小的一个元素然后继续寻找右侧剩余数组元素比较如果出现比A小的元素B则认为新的最小的元素为B之后再和右侧剩余元素比较。选择排序也是最不稳定的一种排序方法即相同值的元素下标会不停变动。//选择排序 function select_sort($array){ for($i0,$lencount($array);$i$len;$i){ $max$i;//初始假设最大的数为array[$i] for($j$i1;$jcount($array);$j){ if($array[$j]$array[$max]){ $max$j; }//循环找出一个数组中下标i之后的最大的数的下标 } //如果$i的值不等于$max的值则交换当前值 if($i!$max){ $mid$array[$i]; $array[$i]$array[$max]; $array[$max]$mid; } } return $array; } $arr1[1,4,6,9,1,2,5,7,9,1]; print_r(select_sort($arr1));插入排序插入排序是一种比选择排序更加稳定的排序方法其思路为i从0开始将第i1个元素插入到前0-i个元素中//插入排序 function insert_sort($array){ for($i 1;$icount($array);$i){//假设第一个元素已经排好 $temp $array[$i];//从第i1个元素开始插入到对应的位置 for($j$i-1;$j0;$j--){ if($temp$array[$j]){//如果要插入的元素小于arr[$j]则将arr[$j]后移一位中间插入该元素 $array[$j1]$array[$j]; $array[$j]$temp; } } } return $array; } $arr2[1,4,6,9,1,2,5,7,9,1]; print_r(insert_sort($arr2));快速排序快速排序是冒泡排序的改进用到的是递归的方法也是一个不稳定的排序算法算法思路为先取出数组中的一个元素然后定义两个数组比该元素小的数组放在一个数组比该元素大的放在另外一个数组这样虽然前后数组顺序不确定但确定了第一个元素所在的位置之后将两个数组递归重复上面的步骤直到数组中只有一个元素回溯最小数组//快速排序 function quick_sort($array){ if(count($array)1){ return $array; }//设置递归出口 $left$rightarray();//创建两个数组一个大一个小 for($i 1;$icount($array);$i){ if($array[0]$array[$i]){ $left[]$array[$i]; } else{$right[]$array[$i];} } //将比第一个元素大的数放在left中将比第一个元素小的元素放在right中 //继续对两个数组进行以上操作 $leftquick_sort($left); $rightquick_sort($right); return array_merge($left,(array)$array[0],$right); } $arr3[1,4,6,9,1,2,5,7,9,1]; print_r(quick_sort($arr3));归并排序并归算法是一种与快速排序效率差不多的算法其思路为将一个数组不断进行二分拆解直到数组里只有1-2个元素此时数组是有序的然后使用二分并归法将数组合并。//归并排序 function merge_sort($array){ if(count($array)1){return $array;}//设置递归出口 $lencount($array); $middlefloor($len/2);//将数组进行二分化 $leftarray_slice($array,0, $middle); $rightarray_slice($array, $middle); $resarray();//创建一个新数组 $leftmerge_sort($left); $rightmerge_sort($right);//设置递归点 while(count($left) count($right)){ $res[]$left[0]$right[0]? array_shift($left):array_shift($right); }//对数组进行二分并归 return array_merge($res,$left,$right); } $arr4[1,4,6,9,1,2,5,7,9,1]; print_r(merge_sort($arr3));查找算法查找算法用于寻找数组中有无匹配项其算法有顺序查找和二分查找顺序查找遍历所有数组中的元素直到有与查找元素匹配的元素或遍历到数组末尾有则返回数组下标没有则返回false二分查找用于在有序数组里查找元素其算法思路为定边界一开始为最左边和最右边比较两个边界中间的元素与查找元素的关系如果大则下次的左边界为中间1的位置如果小则下次的右边界为中间1重复上述过程直到找到元素或者左边界值大于等于右边界值