php学习(一):从基础PHP到高级PHP知识,一站式学习

1.composer常用命令

    composer list --help          list命令的帮助
    composer list                 显示包信息
    composer init ,               以交互方式填写composerjson_文件信息
    composer update               获取依赖的最新版本,升级composer.1ock文件
    composer require xxx          添加新的依赖包到composer.json_文件中并执行更新
    composer require xxx=5.1.*    安装指定版本的包(xxx:"5.1.*" 也可以)
    composer global require "xxxx"  全局安装插件包
    composer remove xxx           从composer.json中移除包
    composer search xxx           在当前项目中搜索依赖包
    composer show  xxx            列举所有可用的资源包
    composer validate             检测 composer.json_文件是否有效
    composer self-update          将composer工具更新到最新版本
    composer create-project       基于composer创建一个新的项目
    composer instan  从当前目录读取composer.json文件,处理依赖关系,并安装到 vendor目录下

2.package配置镜像
    (1.全局配置
        会配置到全局的config.json中
        命令: composer config -g repo.packagist composer https://packagist.phpcomposer.com


    (2.局部配置
        在项目下输入
        命令: composer config repo.packagist composer https://packagist.phpcomposer.com

        然后在composer.json中会出现
        "repositories":{
            "packagist":{
                "type":"composer",
                "url":"https://packagist.phpcomposer.com"
            }
        }


3.php与html区别

    HTML是超文本标记语言;PHP即“超文本预处理器”,是一种通用开源脚本语言。PHP 独特的语法混合了 C、Java、Perl 以及 PHP 自创新的语法。

    HTML主要用在客户端的显示,比如我们浏览的网页,特别是静态网页,都是用html语言写的,在网页上点击右键,查看源文件,就可以看到html代码了。

    PHP是服务器的语言,主要用来对处理客户通过网页提交的信息,它是运行在服务器端的,用来响应客户的请求。它可以比 CGI或者Perl更快速的执行动态网页。用PHP做出的动态页面与其他的编程语言相比;

    PHP是将程序嵌入到HTML文档中去执行,执行效率比完全生成HTML标记的CGI要高许多;PHP还可以执行编译后代码,编译可以达到加密和优化代码运行,使代码运行更快。PHP具有非常强大的功能,所有的CGI的功能PHP都能实现,而且支持几乎所有流行的数据库以及操作系统。

    简言之,php的最终目的还是为了生成html, 再表现给浏览者。 
    
 

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UEdBOtTI-1660870686892)(C:/Users/Icy-yun/AppData/Roaming/Typora/typora-user-images/image-20220723101138058.png)]

1.基本语法

1.文件开头
    <?php  
        .....
    ?>
    注意:php文件可以作为html页面的载体文件,浏览器对php的兼容性非常好。
         对于只包含PHP代码的文件,结束标志("?>")是不允许存在的,PHP自身不需要("?>")这样做,可以防止它的末尾被意外地注入空白并显示输出。

2.文件运行 
   方法一: 开启服务器
       localhost/+ 文件名(含扩展名)             
       注释://     /* */         #
       输出: echo ""   或 print "" 
       (1.1.有时不能够重新加载(有缓存),刷新的位置有 “清空缓存xx”,打开控制台,右键点击刷新)
       (1.2. 正常的js文件与ajax文件应该分开 (js注意分配)
       (1.3 结果返回异常(类似于css样式),可以在network查看响应的php文件
       
   方法二:原生php
        如果php文件经过php的编译,是可以进行输出。   
        dd($arr)                 // 输出原始数据,并阻塞程序的运行 
        print($str)              // 常用于直接 输出字符串
        print_r($arr)            // 可以输出一个对象,而print echo不可以输出任何数组格式数据, 
                                 // 对象需要经过json_encode($arr) 进行转换才可以被直接输出   
        var_dump($arr)           // 主要是输出数组,功能和print_r相同
        json_encode($response)   //  将关联数据转换成json数据格式 
        echo "{'msg':'当前访问的Ts文件不存在','code':404}";      // 也是输出json格式
        echo array('code'=>200,'msg':'登录成功!')             // 输入的格式 (直接array)
        
3.基本语法 
    (1.$相当于声明一个变量,  “.” 用于连接字符串
    
    (2.变量不能以数字开头,可以下划线开头

    方法一: "" 和 {$xxx}
     例如:   $a = "abc{$xxx}def"

    方法二: <<< 和 $xxx
     例如:   $a = <<<std
                     abc$xxxdef
                  std
                  
   (3. 引用赋值         
       $str2 =&$str1                                
       // $str2改变,$str1也会改变
       
       function ab($str){....}     ab(&$string1)
       // 传递给函数的实参是引用变量,函数内的形参变化,实参也会变化。
       

2.str字符串


(1.正则和结构赋值
	preg_match("/userName/",$new)                      // 匹配正则表达式
	 
    list($key,$value) = $arr;                           // list解构赋值


(2. 字符串常用方法:
    $len = strlen($str)                               //获取字符串的长度   ,  汉字占2个字符

    $arrLen = count($a)                               // 获取a数组里的长度 

    $newStr = strtolower($str)                        // 将字符转换为小写

    $newStr = strtoupper($str)                        //将字符转换为大写

    $newStr = str_starts_with($str, $index);             // 前缀匹配

    $newStr = str_ends_with($str, $index);               // 后缀匹配

    $newArr = explode(",",$str,(limit)) 
    //分割字符串, limit可以设置分割后数组的元素个数,可以不选参数,也可以选负数

    $newStr = implode("*",$arr)         
    // 使用*连接数组中的元素,并转换为字符串, 类似 "-".join(arr)

    $newStr = trim($str,"*")           
    //去除左右两侧的结尾处的字符串符号   ,ltrim($str,"*"), 去除左侧的开头处的字符串符号  ,rtrim($str,"*")  去除右侧的结尾处的字符串符号   

    $newStr = str_replace("abc", "小明", $str,(count)  
    // 替换字符串的数据,区分大小写,count表示替换的个数,默认替换全部. str_ireplace() 不区分大小写


(3. 位置索引:
    $pos = strpos($str,"is")       
    // 索引"is"在$str字符串中首次出现的位置,区分大小写,stripos($str,"is") ,不区分大小写  strrpos($str,"is") , 最后一次出现的位置,区分大小写 (""   i   r  都可以添加这些数据), 结果返回-1,判断无效果。默认返回0

    $newStr = substr($str, $start, $len)             
    // 截取指定长度的子串, $start可以为负值,表示倒数位置,同python列表

    $newStr = strstr($str,".")        
    //去除索引处开头部分,获取从索引位置至末尾的子串,区分大小写, 否则返回false,  stristr($str,"a"),不区分大小写, strrshr()  获取最后一次出现的位置至结尾的子串

    $newStr = substr_replace($str, $replaceStr, $start, $len)    
    // 替换指定字段的子字符串,$start可以为负值,从$start开始至$len长度的字串替换为$replaceStr

    $len = substr_count($str,$find)                             
    // 统计特定字符在子串中出现的次数


(4.其他字符串函数 
    $newStr = htmlentities($str, ENT_QUOTES, " utf-8")  ;    
    //设置转换的字符集为"utf-8"  可选参数,选择如何处理字符串中的引号,有三个可选值
        (1 ENT_COMPAT,    转换双引号,忽略单引号,它是默认值;
        (2 ENT_NOQUOTES,  忽略双引号和单引号:
        (3 ENT_QUOTES,     转换双引号和单引号quote (“引用”)


    $a = addslashes ($str);           //对字符串中的特殊字符进行转义  即把' " 等加上\
    $b = stripslashes($a);            //对转义后的字符进行还原         

    $a = addcslashes ($str,"t");      //对字符串中的“指定的字符”进行转义  即把' " 等加上\
    $b = stripcslashes($a);           //对addcslashes转义后的字符进行还原


(5.常用方法 
    $b = empty($abc)                                       //检测内容是否为空

    $b =  isset($_POST[sub])                               // 检测按钮变量是否存在

    $char = chr(32)                                        //将ascii码转换为字符

    $num = rand(1,100)                                     // 获取1 ~ 100的随机数

    $time = microtime()                                    //获取时间戳秒数

    $time = time()                                         // 获取当前时间

    $da = date("Y/m/d H:i:s")                              //获取当前时间

    $name = $_FILES['file_1']              
    // 将图片信息保存在变量中($name["name"]表示文件名称)

    $moveRes = move_uploaded_file($name["tmp_name"],$path)   
    // 将图片移动到指定位置,返回true 或false信息,也可以用于保存文件

    $b = is_uploaded_file($_FILES[ 'up-picture'] [ 'tmpname' ]))          
    //判断文件是否是HTPP POST上传

    $b = is_dir("./hello/")                  //检测文件是否存在

    mkdir("./hello/")                         //创建文件夹

    number_format($num)                       // 将字符串转换成数字

    number_format($num, 2);                   // 将字符串转换成数字,并保留2位小数

    (int)$ab                                   // c语言的转换方式

    (float)$bc                                 // 转换成符点型


(6. 服务器中常用:
    $username = $_POST["username"];            服务器接受post请求
    
    $username = $_GET["content"];               服务器接受get请求

(7.文件中常用
    file_put_contents( "communication.txt", $str, FILE_APPEND);
    //向文件中写入数据(追加,默认覆盖)

    file_get_contents("communication.txt");            
    //向文件中读取数据,也可以获取远程网页数据 

    move_uploaded_file( $temp,$file_path.$file_name) ;  
    // 将上传的文件保存 


(8.客户端常用 
    dirname(__FILE__)               
    //当前运行php文件的文件路径 C:\wamp64\www\php_demo\php_study

    dirname(__DIR__)                
    //当前工作空间的文件路径  C:\wamp64\www\php_demo

3.define常量


常量区分大小写,在定义时可以指定是否大小写敏感。其命名的规则和变量的规则一样。
常量只能以字母和下画线开头,后面可以接任意个数的字母字符。 
在定义常量时,应该尽量使用大写字符,便于阅读和识别。
常量的名称不能以字符$开头,它们的值只能是特定类型的:整数、浮点数、字符

常量   ABX = 123  _AAA = 111

TRUE、 true、True 、1                     表示正确
FALSE 、false、 False 、 "" 、 0          表示错误
NULL、 null                              表示空值


(1.define("ABC",123)             // 定义常量,没有返回值                      
		// 最后一个参数表示是否大小写敏感,True 表示不敏感(服务器中使用true参数,会出错)
(2.defined("ABC")                 // 判断一个常量是否已经被定义              
        // 成功为true,(服务器中返回的是1 或 “”) 
(3.constant("ABC")                // 可以动态获取指定的常量                 
	    // 失败会提示错误信息, (服务器如果出现未定义的变量,会出错)
	    
实例:
    define ("_MESSAGE", "How are you\n",false);
    echo _MESSAGE."<BR>";

    echo "当前文件路径:".__FILE__;            // PHP程序文件名
    echo "<br>当前行数:".__LINE__;           // PHP程序行数
    echo "<br>当前PHP版本信息:".PHP_VERSION;  // PHP程序的版本
    echo "<br>当前操作系统:".PHP_OS ;         //执行PHP解析器的操作系统名称

4.global变量


      
局部变量 ,全局变量,静态变量
1.全局变量用 global修饰,  静态变量用static修饰
    $example="在函数外赋值";
    function example(){                             
        $example="在函数内赋值";
        print "输出的内容是:$example.<br>";    
        // print是直接在页面输出结果,可以不添加{}识别变量
    }
    example();
    echo "在函数外输出的内容是:{$example}"."<br>";      // 也可以不添加{}识别变量

2.静态变量  static number = 0

3.全局变量  global $a.
  // 主要是解决函数内部不能直接访问全局下的变量,这一点和python一样
	$zy="你好.";
    $zyy= "PHP语言";
    function lxt (){
        //$zy不能被调用,没有输出, (服务器会报错)
        global $zyy ;                
        //利用关键字global在函数内部定义全局变量
        echo "<font face='楷体_gb2312' color='blue' size='+2'>".$zyy."</font><br>";
    }
    lxt();
 4.可变变量$$xxx  
   // $xxx的 变化,只改变了$$xxx的值,而原来$$xxx ==$xxx
    $$my_name = “myname”
    $my_name="myname" ;
    $my_name= "yourname" ;
    echo $my_name."<br>";  //输出myname
    echo $$my_name ;       // 输出yourname

5.type数据类型

(1.boolean型       true  false

(2.string字符串型   字符串型变量是所有类型变量中最好区分的,只要变量的值经单引号或者双引号包括的都可以视为是字符串型变量,当然 PHP 是一种弱类型语言,有时像123这种变量的值, 在特定的情况下,也会被默认为是字符串变量  例echo  '<h1>$i</h1>'     

(3.Integer整型     存在整数溢出的现象,同样,如果表达式的最后运算结果超出了int 的范围,也返回float型。

(4.float浮点型     float double

type类型有boolean、float、integer、array、null、object、string类型


1.强制类型转换
    (boolean/integer/float/array/string)$num    
    (1.转换成boolean型             null, 0,未赋值的变量或数组,会被转换为False, 其它的为True

    (2.转换成整型                  布尔型的False转为0,True转为1。 浮点型的小数部分被舍去。 
    注意:字符串型。如果以数字开头,就截取到非数字位,否则输出0。  $newChar = (float/int)x

2.gettype获取类型
    settype($num,"boolean")               把数据转换成指定的类型(无效)
    
    $res = gettype($a).PHP_EOL            查看变量的类型,返回一个字符。


3.is_判断数据类型 
    is_bool                    检查变量是否为布尔类型
    is_string                  检查变量是否为字符串类型
    is_float/is_double         检查变量是否为浮点类型
    is_integer/is_int          检查变量是否为整数
    is_null                    检查变量是否为null
    is_array                   检查变量是否为数组类型
    is_object                  检查变量是否为一个对象类型
    Is_numeric                 检查变量是否为数字或由数字组成的字符串
 

6.±运算符和<<<定界符


(1.算术运算符   + - * / %
	注意:+在php中只当作算术运算符使用,类似javascript的“+”运算
	
(2.赋值运算符  = += -= *= /=    ./  %=
	特别的 ./可以把连接的字符串赋值给第一个变量   $a.=$b;   $a%=$b;
	
(3.自增运算符、自减运算符  ++ --
	自增 $a++ ==$a    自减 $b-- --$b
	$c = $a++;          $d = $b--;
	
(4.逻辑运算符 &&    ||    !   xor(异或)      and   or
    注意:xor表示  一真一假时才为真
    $i=false;         //定义布尔型变量     
    $j= true;         // $i or $j and $z    ==>   $i or ( $j and $z )
    $z= false;
    if($i and !$j)    //这是用or做判断    and 优先级高于or  (and相邻左右先比较)
    	echo "true";
    else
    	echo "false";
    echo "<br>";
    if($i || $j && $z) //这是用||做判断         || 优先级高于and  (||相邻左右先比较)
        echo "true" ;
    else
        echo "false" ; 
    // 优先级从大到小(只是用于编程)   &&   ||   !    and   or  (实际的表优先级相反,即从小到大)
    
(5.比较运算符  ><==   >=  <=  !=   !==  ===
      恒等于===与javascript一样 存在数据与类型的问题
      
(6.三目运算符  ?:
	a> b ? a : b
	
(7.错误屏蔽运算符  @
	$err = @(5 / 0)       对错误的信息隐藏,但实际上依然存在,只是不显示而已(结果是INF)

1.定界符<<< (模板字符串),并且需要配合 “$常量” 使用
 
注意:不允许出现 $row["ab"], $row->ab ,里面的符号不需要“\”斜杠转义。
while($row = mysqli_fetch_array($result)){
    $title = $row['title'];
    $content = $row['content'];
    $username = $row['username'];
    $create_time = $row['create_time'];
    echo <<<std
        <li >
            <img src="../img/avatar.png" alt="">
            <div class="content-div">
                <div class="top">$title</div>
                <div class="middle">$content</div>
                <div class="bottom">
                    <span>$username</span>  &nbsp;
                    <span>发布时间:$create_time</span>
                </div>
            </div>
        </li>
                    std;
}
                 

7.function函数

(1. function func(args){ ... }
    // 函数与javascript类似,同样可以 有返回值 ,也有for循环
    // 注意:函数内的变量是局部变量,函数外的是全局变量,这与python类似,但可以引用赋值,将$m的地址传给形参func(& $m)
    for($i=0;$i<=$x;$i++){ .. }
    // 函数 也有带默认值的形参
    function fun($price,$tax=0){  ..  }
    
(2.return()返回数据,list()  函数可以获取多个返回值 (从一个数组中获取多个数据)
    $array=array ("PHP","MYSOL","APACHE");
    list($PHP,$MySQL,$apache) =$array;
    echo "$PHP+$MySQL+$apache<br>";       //通过list()函数返回数组中的多个值

    function example(){
        $arr = array();
        $arr[0]="PHP";
        $arr[1]="MYSQL";
        $arr[2]="APACHE";
        return $arr;
    }
    $new_obj = example();              // 这个对象无法输出
    list($PHP,$MySQL,$apache) = $new_obj;
    echo "$PHP*$MySQL*$apache" ;

8.for循环控制语句

条件控制语句  if.. else...、if ... elseif... else、switch
循环控制语句  while 、do..while、for、foreach
跳转控制语句  break、continue、return
 
1. for ..each...是javascript的功能      
  (foreach是php独特的功能,使用前先用is_array()函数判断是否为为数组)
  (if .. elseif 是连接着的,其它的都与javascript相同,switch中的case都可以使用字符串,这是弱类型的特点) 
  
2. foreach 循环体中, 不能使用-> 获取属性, 应该使用 []获取。
    $i  或 $i["type_name"] 才有效
    
3.枚举数据,有序号(序号标识)
    foreach ($b as $key => $value) { 
       echo $key.','.$value." ; 
    }
4.for循环遍历
    for($a=0;$a<100;$a++){
        echo $a;
    }

9.require文件引入


(1.include("./module.php");                 
  // php文件导入外部文件,不建议使用,可能会出现变量或者函数多次定义的情况,
  // 可以重复多次,这却也是一个优点,当同一个文件需要多次导入时,就很有实用性
  
(2.include_once("./modele.php")           
  // php文件导入外部文件,不会多次导入相同的文件,即使多次调用也不会重复多次

(3.require("./module.php")                    
  // html文件导入php文件,但也可以php中调用外部文件
  
(4.require_once("./module.php")            
  // 内容同上,都是不会重复调用相同的文件

注意点:
  (1.require()会提前找到该文件,如果不存在,则会终止脚本。
  (2.include()只会在执行到该条语句才会执行,如果不存在,只会输出警告,程序会继续执行
1.namespace+require
--创建Home/Index.php文件
<?php
    //namespace HomeIndex;   // 声明当前文件的命名空间 
    use Illuminate\Support\Facades\Route;   // 使用项目路径下的路由方法 
    function HomeRoutes(){  // 准备暴露的函数 
        // 1测试使用
        Route::get('/',function(){
            return '登录成功1';
        });
        // 2测试使用
        Route::get('test',function(){
            return '登录成功test';
        });
        // 3测试使用
        Route::get('user/test',function(){
            return '登录成功user/test';
        });

        // 测试接口
        Route::any('getQuestion', 'QuestionController@getQuestion');

    }



--- 同级创建web.php文件
<?php 
use Illuminate\Support\Facades\Route;  
require ('Home/Index.php');    // 引入自定义的模块

//HomeIndex\HomeRoutes();    // 如果有命名空间,则使用模块内,指定命名空间的函数
HomeRoutes();    // 如果没有命名空间,则直接使用模块内的函数

2.namespace+use
------laravle项目下的app/Http/Controllers/Controller.php文件 
<?php 
namespace App\Http\Controllers;   // 声明命名空间
...........
class Controller extends BaseController
{
    use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
}



------laravle项目下的app/Http/Controllers/Admin/LoginController.php文件
<?php 
namespace App\Http\Controllers\Admin; 
use App\Http\Controllers\Controller;       // 使用命名空间
....... 
class LoginController extends Controller
{
    // 后台登录页
    public function login(){
        return view("admin.login");
    }
    // 后台首页
    public function index(){
        return view("admin.index");
    }
    // 后台欢迎页
    public function welcome(){
        return view("admin.welcome");
    }
}

10.pcre正则表达式

1.正则语法
1.正则表达式版本
    (1.pcre      perl兼容正则表达式           preg  (效率高)
    (2.posix     便携式操作系统接口            ereg


2.基本语法
    (1、行定位符(^ 和$): 段首^tm ,段尾tm$
        如果出现在任意位置,可以直接写相关字符  tm
        
    (2、单词定界符   (\b和\B)
        \btm\b        匹配所有以tm为单词的一部分的单词
        \Btm\B        匹配所有不以tm为单词身份出现的数据
        
    (3、字符类([])
        []            只能匹配一个字符,不允许不同的字符出现在同一个[]内,大小写除外
        [Tt][Mm]      表示不区分大小写
        
    (4、选择字符(|)
        (T | t)(M | m)
        
    (5、连接字符(-)表示范围,一般会与[]一起使用:取和
        [a-zA-Z0-9]
        
    (6、排除字符 ([^])表示排除的意思
        [^a-zA-Z]     不以字母开头的数据
        
    (7、限定符(?*+{n , m})
        go{2,20}gle        匹配的goole中的o不少于2但不多于20
        
    (8、点号字符(.)表示可以匹配除换行符外的所有字符
        ^s.t$              匹配类似set的字符串
        ^r.s.*t$           匹配类似reset的字符串
        
    (9、转义字符(\)
        [0-9](1,3}(\ .[0-9]{1,3} ){3}   匹配127.0.0.1

    注意: ()表示一个元字符,可以包含多个字符


3.符号含义
    ---------------------------------------------------------------------
                             限定符的说明和举例
    限定符             说明                                  举例
    ?        匹配前面的字符零次或一次        colou?r,该表达式可以匹配colour 和 color-
    +        匹配前面的字符一次或多次        go+gle,该表达式可以匹配的范围从gogle到goo-gle
    *        匹配前面的字符零次或多次        go*gle,该表达式可以匹配的范围从ggle到goo-gle
    {n}      匹配前面的字符n次              go{2}gle,该表达式只匹配google
    {n,}     匹配前面的字符最少n次           go{2,}gle,该表达式可以匹配的范围从google到 goo…gle
    {n,m}    匹配前面的字符最少n次,最多m次    employe{0,2},该表达式可以匹配employ , employe和 mployee三种情况
    
    
    ----------------------------------------------------------------------
                    POSIX风格的预定义字符类
    预定义字符类                         说明
    [:digit:]                   十进制数字集合。等同于[0-9]
    [[:alpha:]l                 字母集合。等同于[a-zA-Z]
    [[:alnum:]]                 字母和数字的集合。等同于[a-zA-Z0-9]
    [[:blank:]]                 空格和制表符
    [[:space:]]                 空白字符(空格、换行符、换页符、回车符、水平制表符)
    [[:upper:]]                 所有大写字母,[A-Z]
    [[:lower:]]                 所有小写字母,[a-z]
    
    [[:xdigit:]]                十六进制数字
    [[:punct:]]                 特殊字符集合。包括接光盘上的所有特殊字符,如!@#$?等
    [[:print:]]                 所有可打印的字符(包括空白字符)
    [[:graph:]]                 所有可打印的字符(不包括空白字符)
    [[:cntrl:]]                 控制字符
    
    而PCRE的预定义字符类则使用反斜线来表示,请参考7.2.10节。
    -----------------------------------------------------------------------
                  反斜线输出不可打印字符
    字符                                说明
    \b                    退格,即 ASCII中的<BS>字符(Ox08)。注意,在PHP中只有在中括号([])里使用才表示退格
    \e                    Escape,即 ASCHI中的<ESC>字符(Ox1B)
    \n                    换行符,即ASCII中的<L凡>字符(Ox0A)
    \r                    回车符,即ASCII中的<CR>字符(OxOD)
    \t                    水平制表符,即ASCII中的<HT>字符(Ox09)
    \a                    警报,即 ASCII中的<BEL>字符(Ox07)
    \f                    换页符,即 ASCII中的<F昨>字符(Ox0C)
    \xhh                  十六进制代码
    \ddd                  八进制代码
    \cx                   即control-x 的缩写,匹配由x指明的控制字符,其中x是任意字符
    --------------------------------------------------------------------------
                  反斜线指定的预定义字符集
    预定义字符集                 说明
    \d                    任意一个十进制数字,相当于[0-9]
    \D                    任意一个非十进制数字
    \s                    任意一个空白字符(空格、换行符、换页符、回车符、水平制表符),相当于[ \fnr]
    \S                    任意一个非空白字符
    \w                    任意一个单词字符,相当于[a-zA-Z0-9_]
    \W                    任意一个非单词字符
    ----------------------------------------------------------------------------
                   反斜线定义断言的限定符
    限定符                       说明
    \b                    单词分界符,用来匹配字符串中的某些位置,lb是以统一的分界符来匹配
    \B                    非单词分界符序列
    \A                    总是能够匹配待搜索文本的起始位置
    \Z                    表示在未指定任何模式下匹配的字符,通常是字符串的末尾位置,或者是在字符串末尾的换行符之前的位置
    \z                    只匹配字符串的末尾,而不考虑任何换行符
    \G                    当前匹配的起始位置
    --------------------------------------------------------------------------------
2.正则常用方法

(1.$count = preg_match("/..../",$str)           
    //根据正则表达式的模式除对指定的字符串进行搜索和匹配,(只会匹配一个结果),返回值为1 或者0

(2.$counts = preg_match_all("/..../",$str,$arr) 
    //根据正则表达式的模式除对指定的字符串进行搜索和匹配(匹配所有结果)返回值为 1. 2 。。。或0 ,$arr保存着查找的结果

(3.preg_grep("/.../",$arr)                       
    // 对数组中的元素进行匹配

(4.$newStr = preg_replace("/.../","",$str,(limit))  
    //对字符串进行搜索和替换操作,limit表示替换的次数(-1表示全部替换)

(5.$newStr = preg_replace_all("/.../","c_back",$str,(limit))         
    //对字符串进行搜索和替换操作,limit表示替换的次数(-1表示全部替换),通过回调函数实现替换
  
(6.$newStr = preg_split("/.../",$str,(limit,falgs)) 
    // 对指定字符串进行分割操作,flags有下面3种标记
    
    PREG_SPLIT_NO_EMPTY:如果设定本标记,则preg_split()只返回非空的成分;

    PREG_SPLIT_DELIM_CAPTURE:如果设定本标记,定界符模式中的括号表达式也会被捕获并返回。本标记添加于PHP 4.0.5;

    PREG_SPLIT_OFFSET_CAPTURE:如果设定本标记,对每个出现的匹配结果也同时返回其附属的字符串偏移量。注意这改变了返回的数组的值,

    使其中的每个单元也是一个数组,其中第一项为匹配字符串,第二项为其在 subject中的偏移量。本标记自 PHP4.3.0起可用。
3.正则常用实例

(1.匹配: 中文:/^[\x{4e00}-\x{9fa5}]+$/u
      说明:  对中文字符串进行匹配。

(2.匹配邮箱地址: lw+([-+.']lw+)*@lw+([-.]lw+)*L.lw+(I-.Jlw+)*
     说明:匹配标准的E-mail邮箱地址,在表单验证中使用最多。 (不包括qq邮箱)

(3.匹配网址URL: [a-zA-z]+://[^\s]*
     说明:匹配网站地址的格式是否正确。
 
(4.匹配空白行: \n\s*\r
     说明:可以用来删除空白行。

(5.匹配双字节字符(包括汉字在内):[^\x00-\xff]
     说明:可以用于计算字符串的长度(一个双字节字符长度为2,ASCII字符为1)

(6.匹配账号或者注册用户名:^[a-zA-Z][a-zA-Z0-9_]{4,15}$
     说明:匹配以字母开头,允许5~16字节,允许使用字母、数字和下画线

(7.和javascript对比使用
    (1.Javascript请求服务器
         function checktruename(truename){
            var str=truename;
              //在Javascript中,正则表达式只能使用/"开头和结尾,不能使用双绰号
            var Expression=/[^\u4E00-\u9FA5]/;
            var objExp=new RegExp (Expression);
            if(objExp.test(str)==true){   
                 return true;   
            }else{
              return false;
            }
          }

    (2.php响应文件
         <?php
              header ( "Content-type: text/html;charset=utf-8");            
              //设置文件编码格式
              if($_POST['truename']==true){
                  //判断提交是否为空
                  if (preg match("/^ [\x{4e003-1x(9fa5)]+$/u”,$_POST[ 'truename']){
                   //验证提交的真实姓名是否是中文
                     echo “用户名:“-$POST['username']."<br>";
                     echo “密码:“.$-POST['password' ]."<br>";
                     echo"真实姓名:".S_POST['truename] ."br>" ;
                     echo"地址:".$_POST[ 'address'];
             }else {
                echo "<script>alert('真实姓名格式不合理,必须是中文');
                window. 1ocation.href='index.php';</script>";
            }

11.array数组

1.数组函数
1.普通方法
(1  count($arr)                           // 获取数组的个数,   如果是空数组或NULL,会返回0, 
     sort($arr)                            // 对数组进行排序 
     join("-",$arr);                       // 用 '-'将数组连接 起来
                                           // 如果是判断是否初始化,应使用isset()函数
(2  array_push($arr,"hello")              // 向数组末尾添加元素(数字索引数组,可连续添加多个), 
     $arr["A"] = "hello"                   // 关联数据可以直接赋值(键会自动转换成字符串)
      
(3  $newStr = array_pop($arr)             // 删除数组最后一个元素,并返回该元素

(4  $result = array_shift($user);         // 删除数组的第一个元素

(5  $user = array_splice($user,1);        //删除数组第一个元素,注意此时返回的是被删除后的新的数组

     unset($input["_token"])               // 删除数组中指定的元素 

(6   $newArr = array_slice($arr, 0,5)      // 切割指定长度的数组

(7   $turns_arr = array_merge($turns_arr,$item );      // 合并两个数组(不允许是模型对象)

       // 类似于javascript的contact 连接方法, python 的extend方法
       
2.高级方法 
(1  $newArr = array_unique($arr)               // 删除重复的元素(保存第一个出现的元素)
 
(2  $newArr = array_keys($arr,"1",(strict))    // 查找元素的所有键名,并返回一个数字索引数组 

(3  $isExist = array_key_exists($key, $array)  //  查询是否存在键名, 建议使用

(4  $key = array_search("1",$arr,true)         // 查找元素的键名,(strict表示是否检查类型),                                  // 如果不存在,则返回null或FALSE(以前版本), 不建议使用
     $isExist = isset($array[$key])             // 存在则返回true, 不存在则返回null
       
(5  is_array($arr)                              // 判断是否是数组类型

(6  list($msec, $sec) = explode(" ", microtime());            // list从变量中解构中数据

(7  $result = urldecode(http_build_query(  ['data'=>'666'])) ; // 序列化queryString
2.数字索引数组,

数字索引数组, 关联数组(类似python的字典)


(1.普通创建
	$arr_int = array ("PHP学习手册","C#学习手册,"VB学习手册");        //声明数字索引数组


(2..和list使用
    // 一般和list()函数配合使用,单独使用无效
    $arr[] = "111" $arr[] = "222" $arr[] = "333"    

    $new_obj = example(); 
    list($PHP,$MySQL,$apache) = $new_obj;
3.字符串索引数组

$arr_string =array ("PHP"=>"PHP学习手册","JAVA"=> "JAVA学习手册"); //声明关联数组             
      
1.特殊字符需要使用转义字符\ 进行转义  ‘  \n   \r   \\   \$   \'  \" ‘  
2.计算方式2e3 == 2000
3.被赋值的数据可以通过unset()函数释放内存 ,一般内存会自动释放    
4.没有赋任何值 
5.被赋值为null  
6.被unset()函数处理过的变量,但必须非空值才可以使用,因为内存不能多次释放
(服务器上不允许出现空值,会出现错误)


4.生成二维数组
(1.创建二维数组
    $arr =array (
        "编程图书"=>array( PHP学习手册","C#学习手册","VB学习手册"),
        "历史文献"=>array ( "1"=>"春秋","2"=>"战国","3"=>"左传"),
        "文学小说"=>array("明朝哪些事儿",3=>"狼图腾”,"鬼吹灯")
    );                                 
    print_r($arr);                //输出数组元素

(2.遍历数组
    foreach($arr as $key1=>$value1) {         //循环读取二维数组,返回值仍是数组
        foreach ($value1 as $key => $value) { 
            // echo $str[$key1][$key];
            echo $value."&nbsp;";
        }
    }  
    for($i=0;$i<count($array);$i++) { 
    	echo $arr[$i];
    }


12.高级的对象

1.time时间对象
------------------------------------------------------------------------
            1.1  将日期、时间转换成UNIX时间戳的函数
函数                                        说明
time                            返回当前的UNIX时间戳
microtime                       返回当前UNIX时间戳和微秒数
mktime                          获取一个日期的UNIX时间截
strtotime                       将任何英文文本的日期时间描述解析为UNIX时间截
gmmktime                        获取GMT (Greenwich Mean Time)日期的UNIX时间戳

(1.$time = mktime(h,m,s,M,D,Y,[is_dst])
// 获取当前时间的时间戳(没有任何参数的情况下)       is_dst 默认为-1 ,

(2.$time = time()
// 获取当前时间的时间戳

(3.strtotime ( "now"),strtotime ("20 October 2010")
// 获取当前、指定日期的时间戳

$input["registerTime"] =  date('Y-m-d h:i:s', time());
// 可以转换为当前时间(也是日期类型)




--------------------------------------------------------------------------------------
            1.2  日期和时间处理函数
函数                                      说明
date                            格式化一个本地时间/日期
getdate                         获取日期/时间信息
checkdate                       验证日期的有效性
gettimeofday                    获取当前时间
gmdate                          格式化一个GMT(格林尼治标准时间)/UTC日期/时间
gmstrftime                      根据区域设置格式化 GMT/UTC时间/日期
localtime                       获取本地时间
strftime                        根据区域设置格式化本地时间/日期

(1.date("Y-m-d H:i:s",(timestamp))
// 输出系统当前时间     timestamp默认为time()时间戳

(2.$arr = getdate( (timestamp))
// 获取当前时间信息,返回一个数组,timestamp默认为time()时间戳  $arr[mon];

(3.$b = checkdate(2020,2,28)
//验证当前时间的准确性




-------------------------------------------------------------------------
        getdate()函数返回的关联数组中元素的说明
键名                        说明                         返回值
seconds                     秒                       返回值为0~59
minutes                    分钟                      返回值为0~59
hours                      小时                      返回值为0~23
mday                       月份中第几天               返回值为1~31
mon                        月份数字                  返回值为1到12
year                       4位数字表示的完整年份       返回的值如:2010或2011
yday                       一年中的第几天             返回值为0~365
wday                       星期中第几天               返回值为0(表示星期日)~一6(表示星期六)
weekday                    星期几的完整文本表示        返回值为Sunday到Saturday
month                      月份的完整文本表示          返回值为January到 December
---------------------------------------------------------------------------

2.使用实例


(1.比较两个时间的大小,必需转换成时间戳,时间戳越小,时间就越靠前
     $time = "2010年10月10日10时10分10秒";               //设置固定时间
     $times = "2011-11-11 11:11:11";                   //设置固定时间
     if(strtotime($time)- strtotime($times)< 0){       //对两个时间进行运算
        echo“时间:".$time."<p>早于".$times ;            //time -times<O说明time的时间在前
     }else{
        echo"时间:".stimes."<p>早于".$time;             //否则,说明times 的时间在前
     }
    
(2.倒计时的设置
    $time1 = strtotime (date( "Y-m-d"));               //当前的系统时间
    $time2 =strtotime ( " 2011-1-1“);                  //2011年元旦
    $sub2 = ceil(($time2 - $time1)/86400);             //(60秒*60分*24小时)秒/天
    echo"距离2011年元旦还有<font color=red>$sub2 </font>天!!!";

    $time1 = strtotime(date( "Y-m-d"));               //当前的系统时间,获取月和天的时间
    $time2=strtotime(date("Y")."-09-18");             // getdate()["year"]   //设置时间3月15日的时间戳
    echo $time2;
    if($time1==$time2){                               //判断两个时间戳是否相同
        echo "<script>alert('勿忘国耻!');
        window.location.href='index.php';</script>";//给出提示信息
    }else {
        echo "今天不是一个特殊的日子!";
    }

(3.计时器
    function run_time(){
       list($msec, $sec) = explode(" ", microtime());//使用explode函数返回两个变量
       return ((int) $msec + (float)$sec);
    }
    $start_time = run_time();       //第一次运行run-time ()函数
    sleep(4);                  // 睡眠
    $end_time = run_time();            //再次运行run_time()函数
    $all_time = $end_time - $start_time;
    echo $all_time;

              
2.date日期对象

date_default_timezone_set('PRC'); //默认时区

date('Y-m-d H:i:s', time())       //当前时间

(1.普通使用
    echo "今天:",date('Y-m-d H:i:s', time()),"\n";

    echo "今天:",date("Y-m-d",strtotime("18 june 2008")),"\n";

    echo "昨天:",date("Y-m-d",strtotime("-1 day")),"\n";

    echo "明天:",date("Y-m-d",strtotime("+1 day")),"\n";

    echo "一周后:",date("Y-m-d",strtotime("+1 week")),"\n";

    echo "一周零两天四小时两秒后:",date("Y-m-d G:H:s",strtotime("+1 week 2 days 4 hours 2 seconds")), "\n";

    echo "下个星期四:",date("Y-m-d",strtotime("next Thursday")),"\n";

    echo "上个周一:".date("Y-m-d",strtotime("last Monday"))."\n";

    echo "一个月前:".date("Y-m-d",strtotime("last month"))."\n";

    echo "一个月后:".date("Y-m-d",strtotime("+1 month"))."\n";

    echo "十年后:".date("Y-m-d",strtotime("+10 year"))."\n";


(2.PHP计鼻两个时间差的万法
    $startdate="2010-12-11 11:40:OO";
    $enddate="2012-12-12 11:45:O9";

    $date=floor((strtotime($enddate)-strtotime($startdate))/86400);
    // 相差多少天

    $hour=floor((strtotime($enddate)-strtotime($startdate))/86400/3600);
    // 相差多少小时

    $minute=floor((strtotime($enddate)-strtotime($startdate))/86400/60);
    // 相差多少分钟 

    $second=floor((strtotime($enddate)-strtotime($startdate))/86400/60);
    // 相差多少秒

3.class类的使用
get_class_methods( ) 获取类的方法(公共方法)

public $table = 'scene-msg';     // 1.用户模型关联表

get_class_vars( ) 获取类的属性(公共属性,静态属性)

get_object_vars( ) 获取类的属性(公共方法)

$table =  get_class_vars(new User())['table']

1.在模型中使用   
    public $table = 'scene-msg';     // 1.用户模型关联表

  
2.在控制器中使用方法 
    // 获取SceneMsg()的表名(防止表名被修改)
    public function SceneMsgTable (){
        return get_object_vars(new SceneMsg())['table'];
    }
    
    // 为了加快访问速度,也可以直接定义属性
    public $sceneMsgTable = 'scene-msg';

13.php无框架网页

1.php与html文件
在开启phpStudy(或者wampserver)的前提下,经过服务器的处理,打开对应的php页面,就会响应页面的内容。

如果直接打开php页面,则无法解析文件。会直接输出文本内容。

注意:php页面可以直接写html页面内容。比如html标签,表面上只是文件后缀名称不同而已。
 
2.php获取网页提交数据
<form action="main.php" method="post"></form>           表单提交  
 
$_GET[] , $_POST[]                                      获取提交的内容


$username=@$_GET['username'];                          // @防止被解析
$password=@$_GET['password'];

3.$_SESSION身份认证
session_start();                               // 使用session的标志
$username=@$_SESSION['username'];               // 获取session的值(@是为了以止被解析)
$password=@$_SESSION['password'];


@$_SESSION['username']=$username;               // 设置session的值
@$_SESSION['password']=$password;

unset(@$_SESSION['jugelizi'])                   // 删除指定的session()
session_destroy()                              // 清除所有的session值 


注意:一定要写在php文件的的。 使用session_start()。否则会出现声明冲突,session值无法获取的情况。
<?php
    session_start();
?>
4.mysqli_连接数据库
$con = mysqli_connect('localhost','root','123456','user','3307');  // 连接数据库

$result = mysqli_query($con,$sql);                                 // sql语句查询

5.php嵌入htm网页(模板)
  1. 建立index.php文件, 可以在里面写html标签,js语句,css样式。

  2. 同时还可以嵌入 php语句。 使用 <?php xxxx ?> 标记包裹着

  3. php语句中也可以直接输出 HTML网页标签。 echo “

    hello

<?php
   php A
?>

     HTML A,     
     // form表单标签属性action="", 并且添加type="submit",name="submit"的提交按钮,
     // 就可以在当前页面中处理请求
       
<?php
if(isset($_POST['submit']))    // 如果页面提交,就执行php内部的语句
{
    $q1=@$_POST['q1'];
    $q2=@$_POST['q2'];

    ......
    $_SESSION['QA_points']=$i*20;
    echo HTMLB;
} 
?>

index.php页面

<?php
    session_start();
?>
<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style type="text/css">
        body{
            width: 100vw;
            height: 100vh;
            display: flex;
            flex-direction: column;
            justify-content: center;
            align-items: center;
            background: url("/img/bg-login.png") no-repeat;
            background-size: cover;
        }
        h2{
            letter-spacing: 1px;
            font-family: "Microsoft Himalaya";
        }
        form{
            width: 240px;
            height: 240px;
            display: flex;
            justify-content: space-around;
            flex-direction: column;
            align-items: center;
            font-size: 1.2rem;
            border:1px solid #fef9ff;
            box-shadow:0 0 2px #1f1f1f;
            padding:40px 60px;
        }
        form .item label{
            width: 60px;
        }
        form .item .input-item{
            width: 160px;
            height: 20px;
            outline: none;
            padding:5px;
        }
        .item{
            width: 100%;
            display: flex;
            justify-content: space-between;
        }
        .item-btn input{
            width: 100px;
            height: 35px;
            font-size: 1.2rem;
        }
        .dump-div{
            margin-top:5px;
            text-align: center;
        }

        .dump-div a{
            cursor: pointer;
            text-decoration: none;
            color:#1f1f1f;
        }
        .dump-div a:hover{
            color:red;
        }
    </style>
</head>
<body>
<h2>留言板登录</h2>
<div class="form-div">
    <form action="" method="post">
        <div class="item">
            <label for="">用户名</label>
            <input name="username" class="input-item" type="text">
        </div>
        <div class="item">
            <label for="">密码</label>
            <input name="password" class="input-item" type="password">
        </div>
        <div class="item">
            <div class="radio-div">
                <input name="type" type="radio" value="0" id="r1" checked>
                <label for="r1">普通用户</label>
            </div>
            <div class="radio-div">
                <input name="type"  value="1" type="radio" id="r2">
                <label for="r2">管理员</label>
            </div>
        </div>
        <div class="item-btn">
            <input type="submit" name="submit" value="登录">
            <input type="reset" name="submit2" value="重置">
        </div>
    </form>
    <div class="dump-div">
        <a href="/register.php">没有帐号?立即注册</a>
    </div>
</body>
</html>



<?php 
unset($_SESSION['username']);
unset($_SESSION['user_id']);
unset($_SESSION['type']);

// 引入封装的自定义函数
require("page/connectDB.php");

// 监听submit的点击提交
if(isset($_POST['submit'])) {
    $username = @$_POST['username'];
    $password = @$_POST['password'];
    $type = @$_POST['type'];

    // 开启数据库连接
    $con = open();

    // 调用自定义函数whereIn,进行数组的序列化;
    $data = array(
        'username'=>$username,
        'password'=>$password,
        'is_super'=>$type
    );
    $new_str = whereIn($data);
    $sql = "select * from table_user ".$new_str;

    // 执行sql语句
    $result = mysqli_query($con, $sql);
    // 获取影响的行数
    $row = mysqli_fetch_array($result);
    if ($row != 0) {
        // 把表单数据存入session中,并跳转主页
        @$_SESSION['username'] = $username;
        @$_SESSION['user_id'] = $row['id'];
        @$_SESSION['type'] = $type;
        echo "<script>window.location.href='/page/leaveMessage.php'</script>";
    } else {
        echo "用户不存在";
    }

    // 关闭连接
    close($con);
}
?>

page/connectDB页面

<?php

// 连接数据
function open(){
    $con = mysqli_connect('localhost','php-msgboard','123456','php-msgboard','3307');        // 连接数据库
    mysqli_set_charset($con,"utf8");                                   // 设置字符集
    return $con;
}

// 断开连接
function close($con){
    mysqli_close($con);
}


// 封装where方法
function whereIn($data){
    // where abc='xxx'
    $new_str = ' where ';
    $len = count($data);
    $turns = 0;
    foreach ($data as $key=>$item){
        if(strpos($key,'time') != 0) {
            // 日期格式
            $new_str = $new_str . $key . '=' . $item ;
        }else{
            $new_str = $new_str . $key . '=' . "'" . $item . "'";
        }

        if($turns != $len - 1){
            $new_str = $new_str.' and ';
        }
        $turns ++;
    }
    return $new_str;
}


// 封装values方法
function valuesIn($data){
    //(id,xxx,xxx) values(NULL,xxx,xxx )
    $new_pre = '(id,';
    $new_str = ') values(NULL ';
    $len = count($data);
    $turns = 0;
    foreach ($data as $key=>$item){
        if($turns != $len - 1){
            $new_pre = $new_pre.$key.',';
            $new_str = $new_str.','."'".$item."'";
        }else{
            $new_pre = $new_pre.$key;
            $new_str = $new_str.','."'".$item."'".')';
        }
        $turns ++;
    }
    $new_str = $new_pre.$new_str;
    return $new_str;
}

14.mysql_连接数据库

1.mysqli_数据库命令
$con = mysqli_connect('localhost','root','123456','students',3307);        
// 连接数据库
 
mysqli_set_charset($con,"utf8");                                   
// 设置字符集
    
mysqli_error($con));                                               
// 返回错误信息 

mysql_select_db()                                                  
// 选择数据库 (330页)

$res = mysqli_num_rows($rs)                                        
//判断数据表中是否存在字段,如果不存在就返回0

$result = mysqli_query($con,$sql);                                
// sql语句查询,  sql语句查询(select为sql语句时,不能直接输出,其它返回的都是影响的行数,默认1, update无法判断是否正常 )
 
$row = mysqli_fetch_array($result)                                 
// 获取查询结果, sql对象转换成数组(可以用while多次获取,返回的是一行数据(数组或json对象))
 
mysqli_close($con);                                               
// 断开连接
 

html连接数据库(php写响应文件)

 <?php
        $q = $_GET['q'];                   // 获取请求的字段
            
        $con = mysqli_connect('localhost','root','123456','user');    // 连接数据库
        mysqli_set_charset($con,"utf8");                              // 设置字符集
        if (!$con) {
            echo('Could not connect: ' . mysqli_error($con));         // 错误信息
        }else{ 
            $sql="SELECT * FROM usermessage WHERE id = ".$q;
            $result = mysqli_query($con,$sql);                       // sql语句查询
            echo "<table>";
            while($row = mysqli_fetch_array($result)) {                      
                // 查找结果的数组
                echo "<tr><th>CustomerID</th><td>" . $row['id'] . "</td></tr>";     
                // 查找的数据 json数据
                echo "<tr><th>CustomerName</th><td>" . $row['name'] . "</td></tr>";
                echo "<tr><th>CustomerSexx</th><td>" . $row['sexx'] . "</td></tr>";
                echo "<tr><th>CustomerAddress</th><td>" . $row['address'] . "</td></tr>";
            }
            //echo "</table>";
            mysqli_close($con);       // 断开连接
        }
2.crud基本查询

// $sql='insert into usermessage values(20,"oooo","女","11212121")';

// $sql="select * from usermessage where id=20";

// $sql="update usermessage set name='小7' where id=20";

// $sql="delete from usermessage where id=20";
<?php

$con = mysqli_connect('localhost','root','123456','user');
mysqli_set_charset($con,"utf8");

if (!$con) {
	echo('Could not connect: ' . mysqli_error($con));
}
else{
    // $sql='insert into usermessage values(20,"oooo","女","11212121")';
    // $sql="select * from usermessage where id=20";
    // $sql="update usermessage set name='小7' where id=20";
    // $sql="delete from usermessage where id=20";
}

// (1. 执行添加,删除,修改的sql语句
$result = mysqli_query($con,$sql);
echo $result;



​ // (2.执行查询操作
​ // 其它返回的结果都是影响的行数,而查询结果却是sql对象(不可以直接输出),通过mysqli_fetch_array获取一行数据对象
​ //(列表或json数据),可以使用while多次获取,可以使用$row[0] $row[‘id’]获取数据;
r o w = m y s q l i f e t c h a r r a y ( row = mysqli_fetch_array( row=mysqlifetcharray(result);
​ echo r o w [ " i d " ] . " , " . row["id"].",". row["id"].",".row[“name”];
​ echo r o w [ 0 ] . " , " . row[0].",". row[0].",".row[1];
​ while( r o w = m y s q l i f e t c h a r r a y ( row = mysqli_fetch_array( row=mysqlifetcharray(result)) {
​ echo “CustomerID” . $row[‘id’] . “”;
​ echo “CustomerName” . $row[‘name’] . “”;
​ echo “CustomerSexx” . $row[‘sexx’] . “”;
​ echo “CustomerAddress” . KaTeX parse error: Expected 'EOF', got '}' at position 37: …d></tr>"; ​ }̲ ​ mysqli_cl…con);

15.php实战应用

1.exec命令行操作
⾸先,打开php.ini,关掉安全模式safe_mode = off,
然后在看看禁⽤函数列表 disable_functions = proc_open, popen, exec, system,shell_exec ,把exec去掉。

exec( 执行命令,执行回调 ,执行结果)       //  return_var –是返回值0或1,如果返回0则执⾏成功,返回1则执⾏失败。
exec("mkdir d:\\test",$out);   
print_r($out);



/**
 * @param $dir   要查找的文件路径
 * @param $dir_array    存储文件名的数组
 */
function find_files($dir, &$dir_array)
{
    // 读取当前目录下的所有文件和目录(不包含子目录下文件)
    $files = scandir($dir);
 
    if (is_array($files)) {
        foreach ($files as $val) {
            // 跳过. 和 ..
            if ($val == '.' || $val == '..')
                continue;
 
            // 判断是否是目录
            if (is_dir($dir . '/' . $val)) {
                // 将当前目录添加进数组
                $dir_array[$dir][] = $val;
                // 递归继续往下寻找
                find_files($dir . '/' . $val, $dir_array);
            } else {
                // 不是目录也需要将当前文件添加进数组
                $dir_array[$dir][] = $val;
            }
        }
    }
}
 
// 调用
$folder_list = array();
find_files('/demo/', $folder_list);
var_dump($folder_list); 
 
2.$_FILES服务端文件存储
1.文件上传

   <?php
            if( !empty ($_FILES[ 'up-picture'][ ' name'])) {     //判断上传内容是否为空
                if ($_FILES['up-picture']['error'] > 0) {   //判断文件是否可以上传到服务器
                    echo "上传错误:";
                    switch ($_FILES['up_picture'] ['error']) {        
                      //根据$_FILES[]全局数组返回的错误代码,输出不同的错误信息
                        case 1:
                            echo "上传文件大小超出配置文件规定值";
                            break;
                        case 2:
                            echo "上传文件大小超出表单中约定值";
                            break;
                        case 3:
                            echo "上传文件不全";
                            break;
                        case 4 :
                            echo "没有上传文件";
                            break;
                    }
                } else {
                    if (!is_dir("./upfi1e/")) {      //判断指定目录是否存在
                        mkdir("./upfile/ ");        //创建目录
                    }
                    $path = ' . /upfile/' . time() . strstr($_FILES['up_picture'] ['name'], '.');  
                    //定义上传文件名称和存储位置
                    if (is_uploaded_file($_FILES['up-picture']['tmp-name'])) {              
                    //判断文件是否是HTPP POsT上传
                        if (!move_uploaded_file($_FILES['up_picture']['tmp_name '], $path)) {  
                           //执行上传操作
                            echo "上传失败";
                        } else {
                            echo "文件" . $_FILES ['up picture'] ['name'] . "上传成功,大小为:" . $_FILES['up- picture']['size'];
                        }
                    } else {
                        echo "上传文件" . S_FILES['up-pictute'] ['name'] . "不合法!";
                    }
                }
            }
3.$_SERVER[]服务器数据

header ( "Content-type: text/html;charset=utf-8");             //设置文件编码格式


$_SERVER[ ]全局数组包含Web服务器创建的信息,应用该数组可以获取服务器和客户配置及当前请求的有关信息。
下面对$_SERVER[ ]全局数组进行介绍,如表8.1所示。
---------------------------------------------------------------------------
$_SERVER[]全局数组
数组元素                                                                    说明
$_GET[] , $_POST[]                         接收GET方法和POST方法传递到当前页面的数据
(一般会与isset()函数一起使用)               if( isset($_GET["sub"])  ){ .... }
 
$_REQUEST[]                              可以用$_REQUEST[ ]全局数组获取GET方法、POST方法和 http Cookie传递到脚本的信息。如果在编写程序时,
不能确定是通过什么方法提交数据的,那么就可以通过$_REQUEST[ ]全局数组获取提交到当前页面的数据。

$_FILES[]                                与其他全局数组不同,$_FILES[ ]全局数组为一个多维数组,该数组用于获取通过POST方法上传文件时的相关信息。
如果为单文件上传,则该数组为二个维数组,如果为多文件上传,则该数组为三维数组。下面对该数组的具体参数取值进行描述。
$_FILES["file"]["name"]:                 从客户端上传的文件名称。
$_FILES["file"]["type"]:                 从客户端上传的文件类型。
$_FILES["userfile"]["size"]:             己上传文件的大小。
$_FILES[ "file"][ "tmp_name"]:           文件上传到服务器后,在服务器中的临时文件名。
$_FILES["file"]["error"]:                返回在上传过程中发生错误的错误代号。
 
$_SESSION[]                              获取会话变量的相关信息
$_COOKIE[]                               存储了通过http Cookie传递到脚本的信息。PHP可以通过setcookie()设置Cookie的值。  数组的下标为Cookie的名称
 
$_SERVER['SERVER_ADDR"]                  当前运行脚本所在的服务器的P地址
$_SERVER['SERVER_NAME']                  当前运行脚本所在服务器主机的名称。如果该脚本运行在一个虚拟主机上,该名称由那个虚拟主机所设置的值决定
$_SERVER['REQUEST_METHOD']               访问页面时的请求方法。例如:“GET”、“HEAD”、“POST”、“PUT”。如果请求的方式是HEAD,PHP脚本将在送出头信息后中止(这意味着在产生任何输出后,不再有输出缓冲)
$_SERVER['REMOTE_ADDR"]                  正在浏览当前页面用户的IP地址
$_SERVER['REMOTE_HOST]                   正在浏览当前页面用户的主机名。反向域名解析基于该用户的REMOTE_ADDR
$_SERVER['REMOTE_PORT]                   用户连接到服务器时所使用的端口
$_SERVER[SCRIPT_FILENAME"]               当前执行脚本的绝对路径名。注意:如果脚本在CLI中被执行,作为相对路径,
如file.php或者../file.php,$_SERVER['SCRIPT_FILENAME']将包含用户指定的相对路径
$_SERVER['SERVER_PORT]                   服务器所使用的端口,默认为“80”。如果使用SSL安全连接,则这个值为用户设置的 HTTP端口
$_SERVER['SERVER_SIGNATURE*"]            包含服务器版本和虚拟主机名的字符串
$_SERVER['DOCUMENT_ROOT]                 当前运行脚本所在的文档根目录,在服务器配置文件中定义 

$_ENV["HOSTNAME"]                        获取服务器有关的信息
$_ENV["SHELL"]                           获取系统shell
4.file_get_contents请求资源

(1.封装的函数


    // 请求远程网页数据
    // url , method,  header,  data, timeout
    public function requestRemote($options){
        try{
            // 设置默认值
            $options['url'] = isset($options['url']) ? $options['url'] : '';
            $options['method'] = isset($options['method']) ? $options['method'] : 'get';
            $options['header'] = isset($options['header']) ? $options['header'] : array();
            $options['data'] = isset($options['data']) ? $options['data'] : array();
            $options['timeout'] = isset($options['timeout']) ? $options['timeout'] : 10;

            if(strtolower($options['method']) == 'get'){
                $query = urldecode(http_build_query(  $options['data'])) ;
                $url = $options['url'].'?'.$query;
                $result = file_get_contents($url);
            }else{
                $context  = stream_context_create([
                    'http' => array(
                        'header'  => $options['header'],
                        // 或者, 'header' => 'Content-type: application/x-www-form-urlencodedrn'
                        'timeout'=>$options['timeout'],
                        'method'  => $options['url'],
                        'content' => $options['data'],
                    )
                ]);
                $result = file_get_contents($options['url'],false,$context);
            }
            return $result;
        }catch (Exception $e){
            return $e;
        }
    }
    
   // 直接调用 
  $result = requestRemote([  'url'=>'https://tianqi.2345.com/pc/pcIndex/zhengzhou/57083']);

   

(2.使用的方法

1.get请求 
        $result = file_get_contents($url)
 
2.post请求 
        $context  = stream_context_create([
            'http' => array(
                'method'  => 'get',
                'header'  => array(
                    'Host'=>'tianqi.2345.com'
                ),
                // 或者, 'header' => 'Content-type: application/x-www-form-urlencodedrn'
                // 'content' => array(),
                'timeout'=>10,
            )
        ]);
        $result = file_get_contents($url,false,$context);



3:用fsockopen函数打开url,以get方式获取完整的数据,包括header和body,fsockopen需要 PHP.ini 中 allow_url_fopen 选项开启(???)
    
    function get_url($url, $cookie = false) {
        $url = parse_url($url);
        $query = $url[path] . " ? " . $url[query];
        echo $query;
        $fp = fsockopen($url[host], $url[port] ? $url[port] : 80, $errno, $errstr, 30);
        if (!$fp) {
            return false;
        } else {
            $request = "GET $query HTTP/1.1\r\n";
            $request.= "Host: $url[host]\r\n";
            $request.= "Connection: Close\r\n";
            if ($cookie) $request.= "Cookie: $cookien";
            $request.= "\r\n";
            fwrite($fp, $request);
            while (!@feof($fp)) {
                $result.= @fgets($fp, 1024);
            }
            fclose($fp);
            return $result;
        }
    }
    //获取url的html部分,去掉header
    function GetUrlHTML($url, $cookie = false) {
        $rowdata = get_url($url, $cookie);
        if ($rowdata) {
            $body = stristr($rowdata, ”rnrn”);
            $body = substr($body, 4, strlen($body));
            return $body;
        }
        return false;
    }


(3.网络api接口实例

        
          <?php
            function send_mail() {
              $url = 'https://api.sendcloud.net/apiv2/mail/send';
              $API_USER = '您账户中的API_USER';
              $API_KEY = 'API_USER所对应的API_KEY';
        
              //您需要登录SendCloud创建API_USER,使用API_USER和API_KEY才可以进行邮件的发送。
              $param = array(
                  'apiUser' => $API_USER,
                  'apiKey' => 'API_USER所对应的API_KEY',
                  'from' => 'service@sendcloud.im',
                  'fromName' => 'SendCloud测试邮件',
                  'to' => '收件人地址',
                  'subject' => '来自SendCloud的第一封邮件!',
                  'html' => '你太棒了!你已成功的从SendCloud发送了一封测试邮件,接下来快登录前台去完善账户信息吧!',
                  'respEmailId' => 'true');
        
            $data = http_build_query($param);
        
            $options = array(
                  'http' => array(
                      'method'  => 'POST',
                      'header'  => 'Content-Type: application/x-www-form-urlencoded',
                      'content' => $data
                  )
            );
        
            $context  = stream_context_create($options);
            $result = file_get_contents($url, false, $context);
        
            return $result;
          }
        echo send_mail();
        ?>
5.simple_html_dom解析网页

(1.安装模块


composer require voku/simple_html_dom 

**(2.使用方法 **

simple_html_dom/README_API.md at master · voku/simple_html_dom

use voku\helper\HtmlDomParser;


    public function test(){
 
 		// (1.获取网页文件
 		
        $html = HtmlDomParser::str_get_html('<html><body>Hello!</body></html>');
        
        $dom = HtmlDomParser::str_get_html($str);  // 从字符串中读取
        
        $dom = HtmlDomParser::file_get_html($file); // 从文件中读取 $file也可以是url, 或者本地文件

		// (2.过滤数据
       
        $element = $dom->findOne('#css-selector'); //  查找一个元素

        $elements = $dom->findMulti('.css-selector'); // 获取多个元素

        $elementOrFalse = $dom->findOneOrFalse('#css-selector'); //  查找可能存在的元素  

        $elementsOrFalse = $dom->findMultiOrFalse('.css-selector'); //  查找多个可能存在的元素 
        
        $ret = $html->find('a');           // 查找a标签 

        $ret = $html->find('a', 0);        // 查找第0个标签

        $ret = $html->find('a', -1);       // 查找最后一个标签 

        $ret = $html->find('div[id=foo]');    // 查找最后一个标签
  
        $ret = $html->find("#div1", 0)->children(1)->children(1)->children(2)->id;  // 类似于jquery的语法

        $ret = $html->getElementById("div1")->childNodes(1)->childNodes(1)->childNodes(2)->getAttribute('id');
        
        $ret = $ret->->innerHtml()           // 获取文本信息

        return $html;
    }

(3.封装的函数


// 解析2345网站网页
function parseWeather(){
    $url = 'https://tianqi.2345.com/pc/pcIndex/zhengzhou/57083';
    // 1.请求数据
    $result = requestRemote([  'url'=>$url]);
    // 2.解析文档
    $dom = HtmlDomParser::str_get_html($result);
    // 3.获取数据
    // (1.天气情况: 多云, 晴,阴 ,小雨 (具体定位)
    $weather = $dom->findOne('span.banner-whether-desc2')->innerHtml(); //  查找一个元素
    // (2.温度 :31.  (大于,小于,等于 )
    $temperature = $dom->findOne('span.banner-whether-desc1')->innerHtml(); //  查找一个元素
    // (3.湿度 :56%   (大于,小于,等于)
    $humidity = $dom->find('span.sp-bold',2)->innerHtml(); //  查找一个元素
    // (3.图片: 背景图(注意不要有多个类名)
    // $banner = $dom->findOne('div.icon-current-wea')->html(); //  查找一个元素

    $banner_arr = [
        '晴'=>'https://tianqi-stream.2345cdn.net/tqpcimg/tianqiimg/theme4/V2Images/wea_icon/80px/icon_qing@2x.png',
        '多云'=>'https://tianqi-stream.2345cdn.net/tqpcimg/tianqiimg/theme4/V2Images/wea_icon/36px/icon_duoyun@2x.png',
        '阴'=>'https://tianqi-stream.2345cdn.net/tqpcimg/tianqiimg/theme4/V2Images/wea_icon/36px/icon_yin@2x.png',
        '小雨'=>'https://tianqi-stream.2345cdn.net/tqpcimg/tianqiimg/theme4/V2Images/wea_icon/36px/icon_xiaoyu@2x.png',
    ];
    $banner = isset($banner_arr[$weather]) ? $banner_arr['weather'] : '暂无图片';

    return array('url'=>$url,'weather'=>$weather,'temperature'=>$temperature,'humidity'=>$humidity,'banner'=>$banner);
}
6.parseDom 解析(auto)

Gitee 极速下载/htmlparsermodel - 码云 - 开源中国

在第5个simple_html_dom解析错误时,即可使用当前方法。因为可能会因为电脑不同,所以该simple_html_dom模块有兼容性问题。

(1.安装方法

使用composer安装的模块有问题

在gitee下找到htmlparsermodel仓库下, src/ParserDom.php ,复制到 Laravel下的新模块 parsefunction.php,
形成一个自动加载的模块,记得使用 composer dump-auto --ignore-platform-reqs

然后在另一个自动加载模块,创建getParseDom函数
use HtmlParser/ParseDom;
function getParseDom($html){
     return ParseDom($html);
}


(2.在控制器中使用


$html = '<html>
      <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title>test</title>
      </head>
      <body>
        <p class="test_class test_class1">p1</p>
        <p class="test_class test_class2">p2</p>
        <p class="test_class test_class3">p3</p>
        <div id="test1">测试1</div>
      </body>
    </html>';
$html_dom = getParserDom($html);
$p_array = $html_dom->find('p.test_class')->innerHtml();

方法和simple_html_dom差不多,就是没有findOne过滤方法

16.文件处理

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-scWnxRTq-1660870686896)(C:/Users/Icy-yun/AppData/Roaming/Typora/typora-user-images/image-20220810144320037.png)]

配置php.ini

访问远程文件使用 fopen()函数, 需要在php.ini中设置 allow_url_fopen=NO
$fp = fopen("http://www.baidu.com/",'rb')


1.文件处理请求
表10.1 fopen()函数中参数mode的可选值
r     只读         读模式——读文件,文件指针位于文件头部
r+    只读         读写模式——读、写文件,文件指针位于文件头部。注意:如果在现有文件内容的末尾之前进行写入就会覆盖原有内容
w     只写         写模式——写入文件,文件指针指向文件头部。注意:如果文件存在,则文件内容被删除,重新写入:如果文件不存在,则函数自行创建文件
w+    只写         写模式—读、写文件,文件指针指向文件头部。注意:如果文件存在,则文件内容被删除,重新写入:如果文件不存在,则函数自行创建文件

a    追加          追加模式打开文件,文件指针指向文件尾部。注意:如果文件已有内容,则将从文件末尾开始追加i;如果文件不存在,则函数自行创建文件
a+   追加          追加模式打开文件,文件指针指向文件尾部。注意:如果文件已有内容,则从文件末尾开始追加或者读取:如果文件不存在,则函数自行创建文件
b    二进制        二进制模式─—用于与其他模式进行连接。注意:如果文件系统能够区分二进制文件和文本文件,可能会使用它。Windows 可以区分,UNIX则不区分。推荐使用这个选项,便于获得最大程度的可移植性。它是默认模式
t    文本         用于与其他模式的结合。这个模式只是Windows下的一个选项

1.读取文件


 1.需要打开文件的操作
    // fopen 打开文件
    // fclose 关闭文件
    // filesize 文件大小
     $fp = fopen("./hello.txt","r");
     $size = filesize('./hello.txt');
    
     // (1.fgetc 读取一个字符
    for($a=0;$a<$size;$a++){
        echo fgetc($fp);
    }
    
    // (2.fgets 读取一行数据(注意,上方会把指针移到文件尾部)
    echo fgets($fp);
    
    // (3.fread() 读取任意长度的字串
    echo fread($fp,$size);
    
    fclose($fp);


 2.不需要打开文件的操作
    // (1.readfile()函数读取一个文件并写入到输出缓冲,成功返回读取的字节数,失败返回FALSE,语法如下。
    // 包含了print输出语句。不需要打开文件
     readfile("./hello.txt");

    // (2.file()函数将整个文件的内容读入到一个数组中。成功的话返回数组,数组中的每个元素都是文件中对应的一行,包括换行符在内;失败返回FALSE,语法如下。
    // 返回的是数组
    $a = file("./hello.txt");
    print($a[0]);

    // (3.file_get_contents()函数将文件内容读入一个字符串。如果有offset和 maxlen参数,将在参数offset所指定的位置开始读取长度为maxlen的内容。如果失败,返回FALSE,语法如下。
    // 也适合读取二进制的数据
    $a = file_get_contents("./hello.txt");
    print($a);

2.写入文件

 1.需要打开文件的操作
    // (1.fwrite 写入数据, (别名puts)
    $fp = fopen("./hello.txt","a");
    fwrite($fp,' i am a engeneer',2);
    fclose($fp);
    
    // (2. flock 在向一个文本文件写入数据时,需要先锁定文件,以防其他用户同时也修改此文件内容。PHP中通过flock()函数实现文件锁定,语法如下。
    //LOCK_SH:取得共享锁定(读取程序);
    //LOCK_EX:取得独占锁定(写入程序);
    //LOCK_UN:释放锁定;
    //LOCK_NB:防止flock()在锁定时堵塞。
    flock($fp,LOCK_EX);


 2.不需要打开文件的操作
    // (1.file_put_contents()函数将一个字符串写入文件中。若成功返回写入的字节数,失败则返回FALSE。
    $res = file_put_contents('./hello.txt','abc');

2.目录操作技术
 1.基本操作
     mkdir('xxx')            创建文件夹
     rmdir('xxx')            移除文件夹
     unlink('xxx.txt')       删除文件
     is_dir                  判断是否是目录
     id_writable('xxx.txt')  判断文件是可写模式
     id_readable('xxx.txt')  判断文件是可读模式


 2.目录操作
    // (1.opendir 打开目录
    $dir = opendir('./test');
    // (2.closedir 关闭目录
    closedir($dir);
    // (3.scandir 浏览目录,返回目录数组
    // (4.readlpath 输出根目录的绝对路径
    print_r(realpath('./test'));
    if(is_dir('./test')){
        $path = scandir('./test');
        for($a = 0;$a<count($path);$a++){
            echo  "#".$path[$a].'<br>';
        }
    }
3.文件的上传技术

1.配置php.ini文件

PHP中通过 php.ini文件对上传文件进行控制,包括是否支持上传、上传文件的临时目录、上传文件的大小、指令执行的时间、指令分配的内存空间。在php.ini中,定位到File Uploads项,完成对上传相关选项的设置。上传相关选项的含义如下。

file_uploads:如果值是 On,说明服务器支持文件上传;如果为 Off,则不支持。 一般默认是支持的,这个不用修改。

upload_tmp_dir:上传文件临时目录。在文件被成功上传之前,文件首先存放到服务器端的临时目录中。多数使用系统默认目录,但是也可以自行设置。

upload_max_filesize:服务器允许上传文件的最大值,以MB为单位。系统默认为2MB,如果网站需要上传超过2MB的数据,那么就要修改这个值。上述是php.ini中File_Uploads项与上传相关选项参数设置说明,除了File_Uploads项中的内容外,在 php.ini中还有其他几个选项会影响到文件的上传。

max_execution_time: PHP中一个指令所能执行的最大时间,单位是秒。该选项在上传超大文件时必须要修改,否则即使上传文件在服务器允许的范围内,但是超过了指令所能执行的最大时间,仍然无法实现上传。

memory_limit:PHP中一个指令所分配的内存空间,单位是MB。它的大小同样会影响到超大文件的上传。

2.接受上传信息

$file = $_FILES('file');

// 输出上传文件的路径名称(主要资源文件)
$tmp_name = $file['tmp_name']

// 输出上传文件的名称
$name = $file['name']

// 输出上传文件的类型
$type = $file['type']

// 输出上传文件的类型
$size = $file['size']

3.上传指定目录(保存)

1.is_uploaded_file() 函数
   参数filename必须指定类似于$_FILES['filename']['tmp_name']的变量,不可以使用从客户端上传的文件名$_FILES['filename']['name'] ;通过is_uploaded_file()函数对上传文件进行判断,可以确保恶意的用户无法欺骗脚本去访问本不能访问的文件,如/etc/passwd。

2.move_uploaded_file() 函数
   move_uploaded_file()函数将文件上传到服务器中指定的位置。如果成功则返回TRUE,否则返回 FALSE,语法如下。参数filename 指定上传文件的临时文件名,即$_FILES[tmp_name];参数destination指文件上传后保存的新路径和名称。

3.单个文件上传实例
    $file=$FILES['text'];
    //将图片的相关信息保存在数组中
    if(is_uploadedfile($file[ 'tmp_name'])){
        // 判断文件是否是一个上传文件
        $rand-=rand(1,1000);
        // 随机取1~1000中的一个随机数
        $floatTime=microtime();
        // 获取此时刻的微妙数
        $str=substr($file[ 'name'],-4,4);
        // 截取上传文件名称后四位
        $path="images/".($and+$floatTime).$str;
        // 拼接图片路径
        if(move_uploaded file($file[ 'tmp name'] ,$path)){
            // 将文件移动到指定文件夹并输出信息
            echo "上传成功,文件名称为:".($and+$floatTime) .$str;
		}
	}
	
4.多文件上传实例
   for($a=l;$a<5; $a++)(
        //循环语句
        $name=$FILES[ 'file__'.$a] :
        //将变量的名称保存在变量中
        $rand=rand(1,100000):
        //获取随机数
        $name_type=substr($name['name'],-4,4);
        //获取文件名称的后四位即文件的格式
        $time=microtime():
        //获取随机数
        $path='upfiles/'.(($rand+$time).$name type); 
        //定义上传文件的路径
        $dir=' upfiles/';
        //定义目录
        $move = move_uploaded_file($name['tmp_name'],$path);
        //移动到服务器指定位置
        if($move==true){
        	echo "成功上传文件”.(Srand+$time).$name-type."<br>";
        	//输出提示
       	}
   }


 
4.文件下载技术
1.header()函数,
    属于HTTP函数。其作用是以HTTP协议将HTML文档的标头送到浏览器,并告诉浏览器具体怎么处理这个页面,其语法如下。 void header ( string string [, bool replace [, int http_response_code]] )
    参数string指定发送的标头;参数replace控制如果一次发送多个标头,对于相似的标头是替换还是添加。如果是FALSE,则强制发送多个同类型的标头。默认是TRUE,即替换。参数http_response_code强制将HTTP响应代码设置为指定值。

2.使用实例(主要是浏览器不能打开二进制的图片,而下载图片,一般与api混合使用)
    //设置图片类型
    header('Content-Type : image/jpg');
    //描述下载文件,指定文件名称
    header('Content-Disposition:attachment;filename="test.jpg"');
    //定义下载文件大小
    header( 'Content-Length: '.filesize('test.jpg')); 
    //读取文件,执行下载
    readfile('test.jpg');


17.会话控制

Cookie和会话是数据的临时档案馆。Cookie将数据存储在客户端,实现数据的持久存储。会话将数据存储在服务器端,保证数据在程序的单次访问中持续有效。有了Cookie和会话这个临时档案馆,就可以解决HTTP Web 协议的无状态问题,实现数据在不同页面之间的传递(例如:通过会话存储的数据来判断用户的访问权限,)和数据在客户端的持久存储(例如:通过Cookie存储论坛用户的登录信息,用户下次在本机登录时,就不需要输入用户名和密码,可以直接登录)

1.会话的操作

(1.基本概念

   在计算机专业术语中,SESSION是指一个终端用户与交互系统进行通信的时间间隔,通常是指从注册进入系统到注销退出系统之间所经过的时间。
   当登录网站时,启动SESSION会话,在服务器中随机生成一个唯一的SESSION_ ID,这个SESSION_ID在本次登录结束之前在页面中一直有效。当关闭页面或者执行注销操作后,这个 SESSION_ID会在服务器中自动注销,当重新登录此页面时,会再次生成一个随机且唯一的SESSION_ID。

    SESSION在Web技术中占有非常重要的地位。由于网页是一种无状态的连接程序,所以无法获取用户的浏览状态。因此必须通过SESSION记录用户的有关信息,以供用户再次以此身份对Web 服务器提要求时做确认。例如,在电子商务网站中,通过SESSION记录用户登录的信息,判断用户的访问权限,通过SESSION实现购物车功能,记录用户所购买商品。


(2.会话的基本使用


<?php
    // 配置session
    // 方法一:支持性不太好
    session_set_Cookie_params(1*60);
    // 方法二:推荐
    setCookie(session_name(),session_id(),1*60+time(),"/");
    
    // 创建会话, 这个必须放在文件的开头(使用到session的都需要加载)
    session_start();    
    // 注册会话
    $_SESSION['user'] = 'abcd';
    // 获取会话数据
    $user = $_SESSION['user'];
    
    // get方法传递session_id
    $s_id = session_id();
    <a href="index.php?s_id= <?php echo session_id(); ?> ">
    // 获取上一页胡session_id
    $s_id = $_GET['s_id'];
    
    // 删除会话
    unset($_SESSION['user']);
    // 清空所有会话
    session_destroy();
?>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hXVlL7jS-1660870686900)(C:/Users/Icy-yun/AppData/Roaming/Typora/typora-user-images/image-20220816153340612.png)]

(3.会话的高级应用

(3.1 文件存储session

​ 在服务器中,如果将所有用户的SESSION都保存到临时目录中,会降低服务器的安全性和服务器的效率,导致打开服务器所在的站点会非常慢。解决这个问题使用的就是12.1.2节中的第4种方法,将SESSION存储到数据库或者临时文件中。

​ 所谓SESSION 的缓存是将网页中的内容临时存储到客户端E的Temporary InternetFiles文件夹下,并且可以设置缓存的时间。当网页第一次被浏览后,页面的部分内容在规定的时间内被临时存储在客户端的临时文件夹中,这样在下次访问这个页面时,就可以直接读取缓存中的内容,从而提高网站的浏览效率。

  
<?php
    // 配置session
    // 设置保存路径
    session_save_path('./session_files');
    // session缓存
    // (1.设置缓存方式
    session_cache_limiter('private');
    // (2.设置缓存时间
    session_cache_expire(1);

    // 创建会话, 这个必须放在文件的开头(使用到session的都需要加载)
    session_start();   
?>

(3.2数据库存储session

将SESSION存储于临时文件夹中,虽然不至于将临时文件夹填满而造成站点瘫痪,但是如果一个大型网站一天登录1200人,一个月登录30000人,这个时候站点中存在30000个SESSION文件,要在这30000个文件中查询一个SESSION_ID,速度可想而知。如果此时将SESSION_ID存储于数据库中,那么查询的速度受到的影响就会小很多。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jBHvb6h5-1660870686902)(C:/Users/Icy-yun/AppData/Roaming/Typora/typora-user-images/image-20220816160124852.png)]

// 定义_open函数,实现与数据库的链接,函数语法如下。
function _open(){
   global $conn;
   $conn = mysql-connect ('localhost', 'root', '111') or die( '数据库连接失败');
   //连接MYsOL数据库
   mysql_select_db('db-database12', $conn) or die('数据库中没有此库名');
   //找到数据库
   mysql_query ( "set names utf8");
   //设置编码格式
   return (true);
}

// 定义_close()函数,关闭数据库链接,函数语法如下。
function _close(){
   //关闭数据库
   global $conn;
   mysq1_close($conn);
   return(true);
}

// 定义_read()函数,读取数据库中SESSION 数据的存储时间大于当前时间戳的数据。如果存在返回SESSION的名称,否则返回FALSE,函数语法如下。
function _read($key){
   globa1 $conn;
   //全局变量sconn连接数据库
   Stime = time();
   //设定当前时间
   $sql = "select sessiondata from tb.session where session_key = '$key' and session_time >$time" ;
    $result =mysql_query(ssql,$conn);
    $row = mysql_fetch_array ($result);
    if($row)(
        return($row['session_data']);
        //返回SESSION名称及内容
    }else{
    	return (false);
	}
}

//定义_write()函数,如果SESSION已经过期,那么执行insert添加语句重新向数据库中添加数据;如果 SESSION未过期,那么执行update更新语句,更新数据库中的数据,函数语法如下。
function _write($key ,$data){
//首先判断SESSION是否失效,如果失效则重新向数据库中添加数据
    global $conn;
    $time =60*60;
    //设置过期时间
    $overdue_time = time() + $time;
    //得到UNIX时间戳
    $sql = "select session data from tb_session where session_key = '$key' and session_time > $overdue_time" ;
    $result = mysql_query ($sql,$conn) ;
    if (mysql_num_rows ($result) ==0){
        //没有结果
        $sql = "insert into tb_session values('skey', 'sdata',$overdue_time)";
        //添加语句
        $result = mysql_query($sql,$conn);
    }else {
        //否则,更新 SESSION的数据
        $sql = "update tb_session set session_key = '$key' ,session_data ='$data',session_time = $overdue_time where session_key = '$key'";
        //定义更新语句
        $result = mysql_query($sql, $conn);
        //执行更新语句
        return ($result);
        //返回标识
    }
}

// 定义_destroy()函数,根据$key值删除数据库中的SESSION,函数语法如下。
function _destroy ($key)
{
    global $conn;
    $sql = "delete from tb_session where session_key = '$key'";
    //删除数据库sql语句
    $result = mysql_query($sql, $conn);
    return ($result);
}

// 定义_overdue()函数,根据给出的过期时间删除过期的SESSION,函数语法如下。
function _overdue($expiry_time) {
    global $conn;
    $overdue_time = time();
    //将参数$expiry_time赋值为当前时间截
    $sql = "delete from tb_session where $expiry_time < $overdue_time";
    //删除数据库sql语句
    $result = mysql_query($sql, $conn);
    return ($result);
}


<?php
    //省略定义6个自定义函数
    session_set_save_handler ('_open', '_close','_read' , '_write' ,'_destroy','_overdue');
    session_start();
    //初始化session变量
    $SESSION['user']= 'mr' ;
    //为session变量赋值
    $_SESSION[ ' pwd']='mrsoft';
?>

<?php
$result=mysql_query("select * from tb-session",$conn);
//执行查询语句
while($myrow=mysql_fetch_array ($result)){
//循环读取SESSION数据
?>
    
<tr>
<td width="217" align="center" bgcolor="#PFFFFF">
    <span class="STYLE6"><?php echo $myrow["session_key"];?></span>
</td>
<td width="286" align="center" bgcolor="#FFFFFF">
    <span class="STYLE6"><?php echo $myrow["session_data"] ;?></span>
</td>
<td width="199" height="25" align=" center" bgcolor="#FFFFFF">
    <span class="STYLE6"><?php echo date("Y-m-d H:i:s", $myrow["session_time"]);?></span>
</td>
</tr>
    
<?php} ?>

2.Cookie的操作

(1.基本概念

    Cookie是一种在远程客户端存储数据并以此来跟踪和识别用户的机制。简单地说,Cookie是Web服务器暂时存储在用户硬盘上的一个文本文件,并随后被Web浏览器读取。当用户再次访问Web网站时,网站通过读取 Cookie文件记录这位访客的特定信息(如上次访问的位置、花费的时间、用户名和密码等),从而迅速做出响应,如在页面中不需要输入用户的D和密码即可直接登录网站。
    这个文本文件以此种格式(用户名@网站地址[数字].txt)存储于客户端硬盘的指定文件夹下。例如,客户端机器为Windows 2000/XP/2003操作系统,系统盘为C盘,当通过IE浏览器访问Web 网站时,Web 服务器会自动以(用户名@网站地址[数字].txt)格式生成Cookie文本文件,并存储在用户硬盘的指定位置,如图12.15所示。

   说明:在 Cookies文件夹下,每个Cookie文件都是普通的文本文件,而不是程序.文本文件中的内容大多都经过了加密处理,因此,表面看来只是一些字母和数字的组合,而只有服务器的CGI处理程序才知道它们真正的含义。

根据Cookie的定义,归纳出Cookie常用于以下三个方面:
(1)记录访客的某些信息。例如:利用Cookie记录用户访问网页的次数,记录访客曾经输入过的信息,或者利用Cookie自动记录访客上次登录的用户名、密码,实现自动登录;

(2)在页面间传递变量。浏览器并不会保存当前页面上的任何变量信息,当页面被关闭后页面上的任何数据信息都将随之消失。此时就可以通过Cookie实现变量值在页面之间的传递。方法就是在当前页通过Cookie保存变量值,然后,在另一页面中再次获取Cookie的值;

( 3)将Web页面存储于Cookie临时文件夹中,提高网页下次访问的速度。

对于Cookie的使用,我们必须谨慎。
 第一,不是所有的浏览器都支持Cookie;
 
 第二,数据是以明文的形式存储于客户端计算机中的,不适合保存敏感的、未加密的数据;
 
 第三,Cookie存储的数据量有一定的限制。一个浏览器允许最多存储300个Cookie文件,而且每个Cookie文件支持最大容量为4KB;每个域名最多支持20个Cookie,如果达到限制,浏览器会自动删除Cookie。

(2.cookie的基本使用

​ 使用Cookie 时要注意,如果未设置Cookie的过期时间,那么在关闭浏览器时会自动删除Cookie数据。如果设置Cookie的过期时间,那么浏览器将会保存Cookie数据,即使用户重新启动计算机,只要没有过期,Cookie数据就一直有效。

​ 如果Cookie 不设定时间,就表示它的生命周期为浏览器会话的期间,只要关闭正E浏览器,Cookie就会自动消失。这种Cookie被称为会话Cookie,一般不保存在硬盘上,而是保存在内存中。

​ 如果设置了过期时间,那么浏览器会把Cookie保存到硬盘中,再次打开E浏览器时依然有效,直到它过期为止。
​ 虽然Cookie 可以长期保存在客户端浏览器中,但也不是一成不变的。因为浏览器允许最多存储300个 Cookie文件,而且每个Cookie文件支持最大容量为4KB;每个域名最多支持20个 Cookie,如果达到限制,浏览器会自动删除Cookie。

<?php
   // 设置cookie, 
   // 创建Cookie应用的是setCookie()函数。由于Cookie是HTTP头标的组成部分,作为头标必须在页面其他内容之前发送,也必须最先输出,所以在 setCookie()函数之前不能有任何内容输出,即使是一个HTML标记、一个echo语句甚至一个空行都会导致程序出错, 并且第 一次运行的时候,是获取不到cookie,刷新后就可以
   
   // 设置有效时间是60秒 ,有效目录为"/12.8/",有效域名为".baidu.com" 及其所有子域名
   // 在客户端的Cookies文件夹下会自动生成一个 Cookie文件,名为administrator@12[1].txt,Cookie的有效期为60秒,失效后Cookie文件自动删除。
   setCookie("mr","张小明",time()+60,'/12.8/',".baidu.com",1);

	// 获取cookie
	$cookie1 = $_COOKIE['user'];
	
	// 删除cookie
	setCookie("mr","",time()-1)
?>



18.面向对象

面向对象(OOP)的编程方式是PHP的突出特点之一,采用这种编程方式可以对大量零散代码进行有效组织,从而使PHP具备大型Web项目开发的能力。另外,采用面向对象编程方式还可以提高网站的易维护性和易读性。

1.类的实例化

(1.类的简介

<?php
	权限修饰符 class 类名{
	   类体;
	   
	   成员变量;
	   var $host;
	   
	   成员常量
	   const PT = 3.14159;
	   
	   常量可以使用作用域操作符::,  类名::常量名
	   
	   成员方法
	   function 方法名称(){
	       
	   } 
	}
?>

权限修饰符是可选项,可以使用public,protected,private或省略
也可以改为 static, abstract等

(2.类的实例

// 创建一个类的实例
$变量名 = new 类名称([参数]);

// 设置成员属性
$变量名->成员属性=值

// 获取成员属性;
$newData = $变量名->成员属性;

// 访问成员方法
$变量名->成员方法()


注意:
1. $this
   $this存在于类的每个成员方法中,它是一个特殊的对象引用方法。成员方法属于哪个对象,$this 引用就代表哪个对象,其作用就是专门完成对象内部成员之间的访问。
   
2."::" 操作符
  相比$this引用只能在类的内部使用,操作符“:.”才是真正的强大。操作符“:.”可以在没有声明任何实例的情况下访问类中的成员。例如:在子类的重载方法中调用父类中被覆盖的方法。操作符“”的语法格式如下。

 关键字::变量名/常量名/方法名  
 
 这里的关键字分为三种情况:
    parent关键字:可以调用父类中的成员变量、成员方法和常量;
    self关键字:可以调用当前类中的静态成员和常量;
    类名:可以调用本类中的变量、常量和方法。

(3.构造和析构方法


1.构造方法
   构造方法是对象创建完成后第一个被对象自动调用的方法。它存在于每个声明的类中,是一个特殊的成员方法,如果在类中没有直接声明构造方法,那么类中会默认生成一个没有任何参数且内容为空的构造方法。
   构造方法多数是执行一些初始化的任务
   public function __construct(){
       // 有些还要重载父类
       parent::__construct();
   }
   
2.析构方法
    析构方法的作用和构造方法正好相反,是对象被销毁之前最后一个被对象自动调用的方法。它是PHP 5中新添加的内容,实现在销毁一个对象之前执行一些特定的操作,如关闭文件、释放内存等。
  function -_ destruct((
      //方法体,通常是完成一些在对象销毁前的清理任务
  }
    在PHP中,有一种“垃圾回收”机制,可以自动清除不再使用的对象,释放内存。而析构方法就是在这个垃圾回收程序执行之前被调用的方法,在PHP中它属于类中的可选内容。

2.封装,继承,多态

面向对象编程的三个重要特点是:继承、封装和多态,它们迎合了编程中注重代码重用性、灵活性和可扩展性的需要,奠定了面向对象在编程中的地位。

(1)封装性:就是将一个类的使用和实现分开,只保留有限的接口(方法)与外部联系。对于使用该类的开发人员,只要知道这个类该如何使用即可,而不用去关心这个类是如何实现的。这样做可以让开发人员更好地把精力集中起来专注别的事情,同时也避免了程序之间的相互依赖而带来的不便。

(2)继承性:是派生类(子类)自动继承一个或多个基类(父类)中的属性与方法,并可以重写或添加新的属性或方法。继承这个特性简化了对象和类的创建,增加了代码的可重用性。

(3)多态性:是指同一个类的不同对象,使用同一个方法可以获得不同的结果。多态性增强了软件的灵活性和重用性。

(1.封装

视频速递:深入讲解面向对象的封装特性
面向对象编程的特点之一是封装性,将类中的成员属性和方法结合成一个独立的相同单位,并尽可能地隐藏对象的内容细节。
其目的就是确保类以外的部分不能随意存取类的内部数据(成员属性和成员方法)。从而有效地避免外部错误对类内数据的影响。
类的封装是通过关键字public、private、protected、static和 final来实现的。 默认也是public


class  Car{
     private $car = '奥迪系列';
     public function getName(){
         return $this->carName;
     }
}
    顾名思义,公共成员就是可以公开的、没有必要隐藏的数据信息。可以在程序的任何地点(类内、类外)被其他的类和对象调用。子类可以继承和使用父类中所有的公共成员。
    被private关键字修饰的变量和方法,只能在所属类的内部被调用和修改,不可以在类外被访问,即使是子类也不可以。
     private关键字可以将数据完全隐藏起来,除了在本类外,其他地方都不可以调用,子类也不可以。但对于有些变量希望子类能够调用,但对另外的类来说,还要做到封装。这时,就可以使用protected。



(2.继承性

   类的继承是类与类之间的一种关系的体现。子类不仅有自己的属性和方法,而且还拥有父类的所有属性和方法,所谓子承父业。
   注意: 当父类和子类中都定义了构造方法时,当子类的对象被创建后,将调用子类的构造方法,而不会调用父类的构造.

class 子类名称 extends 父类名称{
    // 子类成员变量列表
    function 成员方法(){
        //子类成员方法
        //方法体
        parent::父类成员方法();
    }
    // 重写父类成员方法
    function 与父类同名的方法(){
        
    }
}

(3.多态性

  面向对象编程的一个特点是多态性,是指一段程序能够处理多种类型对象的能力。在PHP中,多态有两种实现方法:通过继承实现多态和通过接口实现多态。

1.继承方式

abstract class 抽象类名称{
    //抽象类的成员变量列表
    abstract function 成员方法1(参数);
    //定义抽象方法
    abstract function 成员方法2(参数);
     //定义成员方法
}

class 抽象类的子类1 extends 抽象类名称{
    // 显示声明公有成员变量
    public function 成员方法1(参数){
        
    };
    // 显示声明公有成员变量
    public function 成员方法2(参数){
        
    };
}

class 抽象类的子类2 extends 抽象类名称{
    // 显示声明公有成员变量
    public function 成员方法1(参数){
        
    };
    // 显示声明公有成员变量
    public function 成员方法2(参数){
        
    };
}

$obj = new 抽象类的子类();
$obj->成员方法1();

在上述实例中对于抽象类Vehicle而言,Train类和Car类就是其多态性的体现。


2.接口方式
//声明接口
interface One{
    const CONSTANT= ' CONSTANT value';
    //声明常量成员属性
    function FunOne ():
    //声明抽象方法
}
 
class Member1 implements One{  
   // 可以实现多个接口  One,Two
    public function FunOne(){
       
    } 
}
class Member2 implements One{  
   // 可以实现多个接口  One,Two
    public function FunOne(){
       
    } 
}
 
3.抽象类和接口

​ 抽象类是一种不能被实例化的类,只能作为其他类的父类来使用。抽象类使用abstract关键字来声明,其语法格式如下。

abstract class 抽象类名称{
    //抽象类的成员变量列表
    abstract function 成员方法1(参数);
    //定义抽象方法
    abstract function 成员方法2(参数);
     //定义成员方法
}

class 抽象类的子类 extends 抽象类名称{
    // 显示声明公有成员变量
    public function 成员方法1(参数){
        
    };
    // 显示声明公有成员变量
    public function 成员方法2(参数){
        
    };
}

$obj = new 抽象类的子类();
$obj->成员方法1();

​ 继承特性简化了对象、类的创建,增加了代码的可重性。但PHP只支持单继承。如果想实现多重继承,就要使用接口。PHP可以实现多个接口。

​ 接口类通过interface关键字来声明,接口中声明的方法必须是抽象方法,接口中不能声明变量,只能使用const关键字声明为常量的成员属性,并且接口中所有成员都必须具备 public的访问权限。接口声明的语法格式如下。

​ 接口和抽象类相同都不能进行实例化的操作,也需要通过子类来实现。但是接口可以直接使用接口名称在接口外去获取常量成员的值。

//声明接口
interface One{
    const CONSTANT= ' CONSTANT value';
    //声明常量成员属性
    function FunOne ():
    //声明抽象方法
}

interface Two extends One{
    //声明接口,并实现接口之间的继承
    function FunTwo();
    //声明抽象方法
}

class Member implements Two{  
   // 可以实现多个接口  One,Two
    public function FunOne(){
       
    }
    public function FunTwo(){
       
    }
}

$man = new Member();
$man->FunOne()

抽象类和接口的差异

抽象类和接口有相同之处,也有类似的功能,但是它们之间还是存在很多区别的:
(1)抽象类的操作通过继承关键字extends来实现,而接口的使用是通过implements关键字来实现的;
(2)抽象类中有数据成员,可以实现数据的封装,但是接口没有数据成员;
(3)抽象类中可以有构造函数,但是接口没有构造函数;
(4)抽象类的方法可以通过private、protected 或 public关键字来修饰,而接口中的方法只能使用public来修饰;
(5)一个类只能继承于一个抽象类,而一个类可以同时实现多个接口;
(6)抽象类中可以有成员方法的实现代码,而接口中不可以有成员方法的实现代码。

4.类的魔术方法
1.__construct
2.__destruct
3._clone
4._set 和_get
set()和_get()方法对私有成员进行赋值或者获取值的操作。
    _set()方法:在程序运行过程中为私有的成员属性设置值,它不需要任何返回值。
_set()方法包含两个参数,分别表示变量名称和变量值。两个参数不可省略。这个方法不需要主动调用,可以在方法前加上 private关键字修饰,防止用户直接去调用。 
    _get()方法:在程序运行过程中,在对象的外部获取私有成员属性的值。它有一个必要参数,即私有成员属性名,它返回一个允许对象在外部使用的值。这个方法同样不需要主动调用,可以在方法前加上private关键字,防止用户直接调用。
5._isset()和_unset()
    isset()函数用于检测变量是否存在,如果存在则返回TRUE,否则返回FALSE。而在面向对象中,通过isset()函数可以对公有的成员属性进行检测,但是对于私有的成员属性,这个函数就不起作用了,而魔术方法_isset()的作用就是帮助 isset()函数检测私有成员属性。
     如果在对象中存在“_sset()”方法,当在类的外部使用isset()函数检测对象中的私有成员属性时,就会自动调用类中的“_isset()”方法完成对私有成员属性的检测操作。
其语法如下。
bool _isset(string name)  //传入对象中的成员属性名,返回值为测定结果

  unset()函数的作用是删除指定的变量,参数为要删除的变量名称。而在面向对象中,通过unset()函数可以对公有的成员属性进行删除操作,但是对于私有的成员属性,那么就必须有_unset(方法的帮助才能够完成。
_unset()方法帮助unset()函数在类的外部删除指定的私有成员属性。其语法格式如下。
  void _unset (string name) //传入对象中的成员属性名,执行将私有成员属性删除的操作

6._call()
 _call()方法的作用是:当程序试图调用不存在或不可见的成员方法时,PHP会先调用_call()方法来存储方法名及其参数。_call)方法包含两个参数,即方法名和方法参数。其中,方法参数是以数组形式存在的。
    public function _call ($method, Sparameter)(
        //_cal1()方法
        echo '如果方法不存在,则执行_cal1()方法。<br>' ;
        echo '方法名为:'.$method."<br>';
        //输出第一个参数,即方法名
        echo·参数有:';
        var_dump ($parameter);
        //输出第二个参数,是一个参数数组
   }

7._toString()
魔术方法_toString()的作用是:当使用echo或print输出对象时,将对象转化为字符串。
    public function -tostring(){
       return“我是tostring的方法体";
    }
    
8._autoload()
在 PHP5中应用_autoload()方法解决了这个问题。_autoload()方法可以自动实例化需要使用的类。当程序要用到一个类,但该类还没有被实例化时,PHP 5将使用_autoload()方法,在指定的路径下自动查找和该类名称相同的文件。如果找到则继续执行,否则报告错误。 
    function_autoload ($classname)
        //创建_autoload()万法
        $class_path = $class name." /inc.php' ;
        //类文件路径
        if(file_exists($class-path)){
            //判断类文件是否存在
            include_.once($class-path);
            //动态包含类文件
        }else{
        	echo '类路径错误。';
        }
   }

5.面向对象的关键字

(1.final关键字

final class class_name{
     
}
// 该类不可以被继承,也不能有子类

final function method_name(){
   
}
// 该方法在子类中不可以进行重写

(2.static关键字

1.静态属性
static $num = '0'
类名称::静态属性名称

2.静态方法
static function hello(){ }
类名称::静态方法()

   使用静态成员,除了可以不需要实例化对象,另一个作用就是在对象被销毁后,仍然保存被修改的静态数据,以便下次继续使用。

(3.clone关键字

   
   新克隆的对象 = clone 旧对象

   魔术方法“_clone()”可以为克隆后的副本对象重新初始化。它不需要任何参数,其中自动包含$this 和$that两个对象的引用,$this是副本对象的引用,$that则是原本对象的引用。

class Person{
    public function_clone(){
        //声明__clone()方法
        $this->object-type = 'computer' ;
        //将变量$objecttype的值修改为
        computer 
    }
}

$person2 = clone $person1;

(4.instanceof关键字

instanceof操作符可以检测当前对象是属于哪个类。

ObjectName instanceof ClassName


19.其它技术

1.PHP字符编码

1.基本概念

(1.ASCII 字符集

ASCII (American Standard Code for Information Interchange,美国信息交流标准代码)码是最早的字符集方案,基于罗马字母表的一套电脑编码系统。ASCII编码结构为7位(00~7F),第8位没有被使用,主要包括基本的大小写字母与常用符合。其中,ASCII码32~127表示大小写字符,32表示空格,32以下是控制字符(不可见字符)。

(2.ISO 8859字符集

这种7位的ASCII字符集已经基本支持计算机对字符的显示和保存功能,但对其他西欧国家的字符集却不支持,如英国和德国的货币符号、法国的重音符号等,因此人们将ASCII码扩展到0~255的范围,形成了ISO8859字符集。

ISO 8859是由ISO ( International Organization for Standardization,国际标准化组织)在ASCII编码基础上制定的编码标准。ISO 8859包括128个ASCII字符,并新增加了用于西欧国家的128个字符。

(3.Unicode 字符集

Unicode字符集是Universal Multiple-Octet Coded Character Set通用多八位编码字符集的简称,是由一个名为Unicode学术学会(Unicode Consortium)的机构制定的字符编码系统。

Unicode是一种在计算机上使用的字符编码。它为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求。

Unicode标准始终使用十六进制数字,而且在书写时在前面加上前缀“U+”,例如字母“A”的编码为004116和字符“”的编码为20AC16。所以“A”的编码书写为“U+0041”。

Unicode堪称一个伟大的成就,它把在这个世界上的每一个合理的文字系统整合成了一个单一的字符集。

​ **UTF-8编码**是Unicode 中的一种使用方式。UTF是 Unicode Translation Format,即把Unicode转成某种格式的意思。

​ UTF-8便于不同的计算机之间使用网络传输不同语言和编码的文字,使得双字节的Unicode能够在现存的处理单字节的系统上正确传输。

​ UTF-8使用可变长度字节来存储Unicode字符,如ASCII字母继续使用1字节存储,重音文字、希腊字母或西里尔字母等使用2字节来存储,而常用的汉字就要使用3字节辅助平面字符则使用4字节。
UTF-8有两大优点:
​ (1)128以下编码和单字节处理软件兼容;
​ (2)UTF-8的多字节编码没有部分字节混淆问题。如删除半汉字后整行乱码的问题在UTF-8里是不会出现的;任何一字节的损坏都只影响对应的那个字符,其他字符都可以完整地恢复。

​ 所以,在开发项目的过程中,笔者建议使用UTF-8编码,因为UTF-8在不同的计算机之间使用网络传输不同语言和编码的文字时,不会出现乱码的问题。

(4.GB2312 字符集

GB2312又称GB2312-80编码,全称为《信息交换用汉字编码字符集.基本集》,由原中国国家标准总局发布,1981年5月1日实施。GB2312编码是中华人民共和国国家标准汉字信息交换用编码。它所收录的汉字已经覆盖99.75%的使用频率,基本满足了汉字的计算机处理需要,在中国和新加坡得到广泛使用。

GB2312编码中对所收汉字进行了“分区”处理,每区含有94个汉字/符号。这种表示方式也称为区位码。
各区包含的字符如下:0109区为特殊符号;1655区为一级汉字,按拼音排序;56~87区为二级汉字,按部首/笔画排序;10~15区及88~94区则未有编码。

两字节中前面的字节为第一字节,后面的字节为第二字节。习惯上称第一字节为“高位字节”,而称第二字节为“低位字节”。“高位字节”使用了0xA1~OxF7(把0187区的区号加上OxA0),“低位字节”使用了OxA1~OxFE(把01-94加上OxAO)。

(5. GBK 字符集

GBK编码是对GB2312编码的扩充,它包含2万多个字符,除了保持和GB2312兼容外,还包含并且增加了部分Unicode中没有的字符。GBK只是一个规范而不是国家标准的编码,新的国家标准是GB18030-2000,它比 GBK包含更多的字符。

2.开发使用

// 转换编码格式
// 由于mb_convert_encoding()函数属于mbstring扩展库,所以要应用mb_convert.手提示
encoding()函数,必须加载mbsiring 扩展库。即在php.ini文件中定位到“;php_mbstring.dll”,将其前面的分号“,”去掉,保存并重新启动Apache服务器。
// IGNORE的作用是忽略转换时的错误,有时iconv()函数在转换字符“一”到GB2312编码时会出错,如果没有IGNORE参数,该字符后面的所有字符串都无法被保存。
$strs = iconv("gb2312","utf-8",$text); 
$strs = iconv("gb2312","utf-8//IGNORE",$text);
$strs = mb_convert_encoding($text,"UTF8","gb2312")


// 监测当前页面的编码格式
$code = mb_detect_encoding("监测");


// meta标签
<meta http-equiv="Content-Type" content="text/html;charset=gb2312">


// header 函数设置页面编码, header函数优先级高于页面的meta标签
header("content-type:text/html;charset=UTF-8")


// 从图18.8中可以看出,通过substr函数对包含中文的字符串进行截取时,一个中文汉字被看做两个字节,如果最后截取的字节不是一个完整的中文(即只截取到一个完整中文字节的一半),那么输出的将是
// 其原因在于使用substr()函数进行字符串的截取时是以一个字节为单位进行的,但是中文字符串是以两个字节为一个汉字书写的,所以在截取的过程中如果出现半个汉字的字节,就会出现乱码。
// mb_substr()函数,通过它来对中文字符串进行截取,就可以避免在截取中文字符串时出现乱码。
$str = mb_substr($str1,0,6,"UTF-8")


// 将本地的语言设置雨为指定人地区语言
setlocale(LC_ALL,'chs');
strftime('%A  %e %B %Y',time())

2.php程序调试

1.基本概念

定义错误;
定义错误是指使用了未加定义的变量或方法。简单地说,就是在页面中调用一个sayO方法,但是页面中并没有定义一个叫做say的方法。

逻辑错误:
所谓的逻辑错误就是大家俗称的bug。

运行错误:
运行错误是指代码在运行时出现异常而导致的非致命错误,此类异常不是编程的逻辑错误造成的,而是PHP代码以外的问题,如磁盘、数据库、文件或者网络等。

只读属性:
与只写属性放在一起比较好理解,只读就是可以读取但不可以写入,只写恰好相反。

环境错误:
是与脚本的运行环境和相关服务关联的问题,如操作系统、PHP版本、PHP配置等。

错误级别:
错误也是分级别的,有些错误一旦发生则程序无法运行,称为致命错误,有些错误发生时只是一些简单的提示但并不致命,程序可以继续执行。

2.异常捕获

// try..catch.. 异常捕获
try{
   
}catch(Exception $e){
    Exception类提供了一些内置的方法,用于输出各种错误信息。
    getMessage(:返回传递给构造函数的信息。
    getCode():返回传递给构造函数的代码。
    getFile(:返回产生异常的代码文件的完整路径。
    getLine():返回代码文件中产生异常的代码行号。
    getTrace():返回一个包含产生异常的代码回退路径的数组。
    getTraceAsString():返回一个包含产生异常的代码回退路径的数组,该信息将被格式化成一个字符串。
    __toString():输出一个Exception对象,并且给出以上所有方法可以提供的信息,支持重载。

}


// PHP提供一种隐藏错误的方法。即在要被调用的函数名前加上“@”符号来隐藏可能由于这个函数导致的错误信息。
$fp = @fopen(xxxxx,'r')


// 重定向页面
header("Location:error.html")

// 自定义错误日志
在php.ini文件中,设置 display_errors = Off
<?php
    function err_log($error ,$error-str){
        // 自定义一个错误处理函数
        $file="phperrors.1og" ;
        if(filesize($file)>1024){
            //如果日志文件大于1024KB
            rename ($file,$file. (string)time()); 
            //以时间为准绳对日志文件进行重命名
            clearstatcache ();
            //清除文件状态缓存
            error_1og($errorstr, 3,$file);
            //衔出错信息记录到指定的文件中
     }
    set_errorhandler('err-log');
    //执行自定义函数log roller()函数
    trigger_error(tine(). :程序报错.\n");
	//发出错误信息
	restore_error_handler();
    //重新编译这个预错处理的函数
?>

3.配置php.ini

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0nAX6Uq3-1660870686903)(C:/Users/Icy-yun/AppData/Roaming/Typora/typora-user-images/image-20220817104321379.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-K4fMijCd-1660870686907)(C:/Users/Icy-yun/AppData/Roaming/Typora/typora-user-images/image-20220817104343630.png)]

3.Smarty模板技术

(1.smarty介绍

Smarty模板引擎实现Web网站中用户界面和 PHP代码的分离。通过Smarty模板的加入,将尝试一种新的Web交互式网站的开发流程。

静态页:
-般是指HTML脚本语言,不存在一个交互的理念。

变量调节器:
变量调节器作用于变量、自定义函数和字符串。使用“I”符号和调节器名称调用调节器。

内建函数:
Smarty本身定义的函数。

Smarty 拥有丰富的函数库,从统计字数到字符串的截取、文字的环绕及正则表达式都可以直接使用,还具有很强的扩展能力。Smarty模板的优点总结如下。

速度:相对于其他模板而言,采用Smarty模板编写的程序可以获得最快的速度。

编译性调用:采用Smarty模板编写的程序在运行时会生成一个PHP和HTML混合的文件,在下一次访问模板时会直接访问这个混编的文件(前提是源文件没有改变),而不必重新编译,进而可以提高访问速度。

缓存技术:Smarty 提供一种可选择的缓存技术,可以将客户端的HTML文件缓存成一个静态页。当用户开启缓存后,在指定的时间内,Web请求会直接调用这个缓存文件,即直接调用静态的HTML文件。

插件技术:因为Smarty模板引擎是通过 PHP面向对象技术实现的,所以不仅可以修改Smarty模板的源文件,而且还可以通过自定义函数向Smarty中添加功能。

模板中可以使用iflelseif/elselendif。

(2.smarty的使用


smarty模板引擎很类似 tp的模板引擎语法

19.GD2图像函数库(略)

在php.ini文件中开启
;extension=php_gd2.dll  (php8,x没有)
;extension=gd

测试是否安装
phpinfo()


注意:以下技术都需要开启 wampserver。

1.常用的图像处理

<?php
 header('Content-type:text/html;charset=utf-8');
 header('Content-type:image/gif');
 $img = imagecreate(395,100);
 $white = imagecolorallocate($img,211,126,29);
 imagegif($img);
 imagedestroy($img);

20.PDO抽象层(略 )

(1.基本介绍

     PDO (PHP Data Object)是一个“数据库访问抽象层”,作用是统一各种数据库的访问接口,与mysql和mssql函数库相比,PDO让跨数据库的使用更具有亲和力;与ADODB和 MDB2相比,PDO更高效。
     PDO将通过一种轻型、清晰、方便的函数,统一各种不同RDBMS库的共有特性,在最大程度上实现PHP脚本的抽象性和兼容性。
     PDO吸取现有数据库扩展成功和失败的经验教训,利用PHP 5的最新特性,可以轻松地与各种数据库进行交互。
     PDO扩展是模块化的,使您能够在运行时为您的数据库后端加载驱动程序,而不必重新编译或重新安装整个PHP程序。例如,PDO_MySQL扩展会替代PDO扩展实现MySQL数据库API。还有一些用于Oracle、PostgreSQL、ODBC 和Firebird 的驱动程序,更多的驱动程序尚在开发中。
     
     PDO是PHP Date Object (PHP数据对象)的简称,它是与PHP 5.1版本一起发行的,目前支持的数据库包括Firebird、FreeTDS、Interbase、MySQL、MS SQL Server、ODBC、Oracle、Postgre sQL、SQLite和 Sybase。有了PDO,您不必再使用mysql_*函数、oci_函数或者 mssql_*函数,也不必再为它们封装数据库操作类,只需要使用PDO接口中的方法就可以对数据库进行操作。在选择不同的数据库时,只需修改PDO的 DSN(数据源名称)


(2.基本的使用

<?php
    $dbms= 'mysql';
    //数据库类型,对于开发者来说,使用不同的数据库,只要11改这个,不用记住那么多的函数
    $host= 'localhost';
    //数据库主机名
    $abName='db_database16';
    //使用的数据库
    $user='root';
    //数据库连接用户名
    $pass= "111';
    /对应的密码
    $dsn=" $dbms:host=$host;dbname=$dbName";
    try {
         // 连接数据库,初始化一个 PDO对象,就是创建了数据库连接对象$pdo
        $pdo = new PDO($dsn, $user, $pass);
        // 查询数据
        $result = $pdo->query($sql);
        // 断开数据库连接
        echo"连接成功<br/>";
        $pdo = nul1;
    }catch (PDOException $e){
    	die ( "Error!: ". $e->getMessage(). "<br/>");
    }
?>

  • 1
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值