PHP面试值知识点复习

=====================1.基础=====================

1.1 PHP的引用传递
值类型默认存放在栈中,但当值类型是在引用类型中声明的时候,则存放在其所在的引用类型的堆中。

引用类型存放在堆中。其在堆中的内存地址存放在栈中。
1.2 PHP定义字符串的几种方式

单引号、双引号、heredoc(<<<EOT)和newdoc(<<<’EOT’)

区别:双引号可以解析变量,转义字符而单引号不可以;单引号和双引号都可以使用.进行连接;单引号比双引号的执行效率更好;heredoc和newdoc主要用于比较长的字符串;

注意:双引号中的单引号不

$a   = 'newStr';
$str = "abcdef{&&$a&&}g";
var_dump($str);

echo PHP_EOL;

$str = <<<'EOL'
SELECTFROM `dvb_user` WHERE `userName` = 'panda' AND `sex` = '1' AND  `money` > 280 LEFT JOIN `dvb_hotel` ON
`dvb_user`.id = `dvb_hotel`.user_id;
EOL;
1.3 PHP的数据类型

PHP的数据类型有8种(整形、字符型、浮点型、数组、对象、null、资源、布尔型) 可以分为三类(标量 符合 特殊)
注意:浮点类型不能用于准确的相等判断中;布尔类型包括(0、’’、’0’,[],false,null,0.0)

var_dump($str);

$a = 0.1;
$b = 0.4;

if((float)$a + (double)$b === (float)0.5){
    echo 'true';
}else{
    echo 'false';
}
1.4 PHP中的超全局数组

$_GLOBALS,$_GET,$_POST,$_REQUEST,$_SERVER,$_SESSION,$_COOKIE,$_FILES,$_ENV

注意:$_GLOBALS包含其他所有的全局数组 主要记住 $_SERVER[‘SERVER_ADDR’] $_SERVER[‘REMOTE_ADDR’] $_SERVER[‘HTTP_USER_AGENT’]

var_dump($_SERVER);
1.5 NULL的三种情况

直接对变量赋值为NULL 、变量未定义、变量被销毁

var_dump($a);
$a = 'a';
unset($a);
var_dump($a);
1.6 比较常量 const和define (常量一经定义不能进行修改和删除)

PHP预定义常量 FILELINEDIRFUNCTIONCLASSTRAITMETHODNAMESPACE

class IndexClass{
    //定义常量,const可以定义在类内,而define不可以
    const A = 'a';
    const B = 'b';
}
define('AAA',5);
define('BBB',6);
//测试修改define常量
define('AAA',4);  //这种用法不会真正的修改到常量的值
var_dump(AAA);
var_dump(BBB);
$indexClass = new IndexClass();
var_dump($indexClass::A);
var_dump(__FILE__); //当前文件的路径和文件名
var_dump(__LINE__); //返回当前的行号
var_dump(__DIR__); //返回当前文件所在的目录路径
class TestClass{
//    //初始化
    public function __construct()
    {
//          var_dump(__CLASS__); //返回当前的类名
            var_dump(__FUNCTION__); //返回当前的方法名
    }

    public function test()
    {
        var_dump(__FUNCTION__);   //__METHOD__和__FUNCTION__位于类外,没有区别;位于类内,__METHOD__会多一个类名 string(15) "TestClass::test"
        var_dump(__METHOD__);
    }
}

$obj = new TestClass(); $obj->test();

trait TraitTest{
    //
    public function test()
    {
        echo 1;
    }
}

class Index{
    use TraitTest;

    public function __construct()
    {
        $this->test();
    }

    public function testTrait()
    {
//        var_dump(__TRAIT__);
    }
}

$a = new Index(); $a->testTrait();
var_dump(__NAMESPACE__); //返回当前文件的命名空间

=====================2.变量与作用域=====================

2.1 变量的作用域和静态变量

变量的作用域:变量生效的范围,这个范围的跨度包括require和include引入的文件
函数外面的变量(全局变量)一般情况不可以直接在函数内部进行使用,如果要在函数内部使用外部的定义的变量可以使用global或者其他超全局数组关键字;

静态变量 static 静态变量只会存在于函数内部,函数外部的变量不受其影响,但当程序离开此程序作用域,其值不会随着函数的执行完毕而消失

静态变量的特点:
  • ①仅初始化一次;
  • ②初始化的时候需要赋值;
  • ③每次执行完函数该值保留
  • ④static修饰的变量是局部的,仅在函数内部有效
  • ⑤可以用来记录函数调用的次数
2.2 函数的参数

默认情况下,函数的参数传递是通过值传递的,如果想在函数的内部修改参数的值,需要进行引用传递,即在参数的前面加上&

$a = 1; //1
function test_function_params(&$a){
    $a++;
    echo $a;
    echo PHP_EOL;
}
$a++; //2
echo test_function_params($a);  //3
echo $a; //3
2.3 函数的返回值

使用return进行返回,函数中一旦执行到return则马上进行返回
可以返回数组,对象等php基本数据类型
原则上不允许返回多个值,可以通过数组来保存多个值
引用返回:需要在函数声明和值返回的时候加上引用符号

function &my_func(){
    static $a = 3;
    return $a;
}
echo my_func(); //10
$a = &my_func();//将外部的$a和内部的$a的变量指向相同的内存空间
$a = 100; //修改内存空间的值
echo my_func(); //100
2.4 外部引用

外部引用文件需要指明引用文件的具体路径,如果没有指定则会去系统的include_path文件下查找,如果include_path也没有,则会从当前目录进行查找

如果在以上三个地方都没有找到,那么加载文件就会报错,include会产生警告,require会产生致命的错误 include_once和require_once

include 'index1.php';
require 'index1.php';
2.5 常用的PHP内置函数

时间日期函数 Ip处理函数 打印处理函数 序列化函数 字符串处理函数 数组处理函数 https://php.net/

var_dump(date('Y-m-d H:i:s',1494221221));  //将时间戳格式化成日期时间类型
var_dump(time());  //time() 打印当前的时间戳
var_dump(strtotime('2018-12-7 12:30'));  //将英文的日期时间转化为时间戳
var_dump(mktime(12,45,11,3,23,2019)); //输出一个指定日期时间的时间戳
var_dump(microtime()); //返回当前的Unix时间戳和微秒数
date_default_timezone_set('Asia/Shanghai'); //设定用于一个脚本中所有日期时间函数的默认时区

ip相关

var_dump(ip2long('192.168.1.1'));  //将 IPV4 的字符串互联网协议转换成长整型数字
var_dump(long2ip(3232235778)); //将 长整型数字 转化成 IPV4 的字符串互联网协议转
打印相关 print() echo() printf() sprintf() printf_r()只能针对数组和对象  var_dump() var_export()

字符串处理函数

implode(); //将多个数组,用指定的字符连接起来 join()===implode()
explode(); //将字符串分割成数组
$a = ['1','2','3'];  var_dump(implode('-',$a));
$str = '192.168.1.1';  var_dump(explode('.',$str));
$str = '192.168.1.1'; var_dump(strrev($str)); //翻转字符串
$str = ' 123 455\t '; var_dump($str); var_dump(trim($str)); //过滤字符串首部和尾部的空白字符(或者其他字符)
ltrim() rtrim() left right
$str = '192.168.1.1'; var_dump(strstr($str,'.')); //strstr();  //查找字符串的首次出现
echo number_format(125,'3');  //以千位分隔符方式格式化一个数字

=====================3.正则表达式=====================

3.1 正则表达式

正则表达式的作用:分割、查找、匹配、替换

  • 常用的分隔符:正斜线(/) hash符号(#)以及取反符号(~)
  • 通用原子: \d [0-9] \D ![0-9] \w [数字、字母、下划线] \W ![数字、字母、下划线] \s 空白符 \S !空白符
  • 元字符:.![换行符]匹配前面的内容0 1 多次 ? ^ $ + {n} {n,} {n,m} [] () [^] | [-]

模式修正符 i m e s U x A D u

涉及到的函数 preg_match() preg_match_all() preg_replace() preg_split()

3.2 正则表达式后向引用

需要匹配的用括号括起来

$str = '<b>abc</b>';  //将其中的b替换成其他
$pattern  = '/<b>(.*)<\/b>/';
//$result  = preg_match($pattern,$str); //匹配是都在<b></b>中
$result   = preg_replace($pattern,'\\1',$str); //去掉b标签
var_dump($result);
3.3 正则表达式的贪婪模式

如果含有多个标签,正则表达式的贪婪模式会匹配第一个和最后一个
解决方法在 .* 后面加个? 取消贪婪模式

$str = '<b>abc</b><b>bcd</b>';  //将其中的b替换成其他
$pattern  = '/<b>(.*?)<\/b>/';
$result   = preg_replace($pattern,'\\1',$str); //去掉b标签
var_dump($result);
3.4 PHP正则表达式匹配中文

中文字符在utf-8模式下的 0x4e00-0X9fa5
gbk需要加chr() 函数

注意:中文字符匹配需要加+

$str = '我爱我家';
$pattern = '/[\x4e00-\x9fa5]+/';
preg_match($pattern,$str,$match);
var_dump($match);
3.5 练习 写一个139开头的手机号
$str     = '13968547896';
$pattern = '/139[0-9]{8}/';
preg_match($pattern,$str,$match);
var_dump($match);
$str = 'https://www.baidu.com';
$pattern = '/^(http|https):\/\/(.*)+/';
preg_match($pattern,$str,$match);
var_dump($match);
请写出一个正则表达式,取出页面中的所有的img标签的src值
$str     = '<img class="index-top" src="http://www.baidu.com/1" id="index" /><p><video src="aaa"></video></p><img class="index-top-2" src="http://www.baidu.com/2" width="100%" />';
$pattern = '/<img.*?src="(.*?)".*? \/?>/i';
$result  = preg_replace($pattern,'\\1',$str);
var_dump($result);

=====================4. PHP常用的文件系统 =====================

真题:向一个已知的文件中的头部插入 Hello World

1.打开文件
$file    = './test.txt';
$content = '';
//2.以只读的方式,读取文件中的内容
if (file_exists($file)){
    $handle  = fopen($file,'r');
    $content = fread($handle,filesize($file));
    //3.关闭文件
    fclose($handle);
}
//4.以只写的方式打开文件
$handle  = fopen($file,'w');
//5.拼接新的字符串进行写入
$content = "Hello World \t" . $content;
fwrite($handle,$content);
//6.关闭文件
fclose($handle);
4.1 PHP常用的文件函数复习
$file = './test.txt';
var_dump(basename($file));  //basename()返回文件名
var_dump(copy($file,'./test1.txt'));  //copy() 拷贝文件,如果目标文件已经存在,则会进行覆盖 overwrite
var_dump(unlink('./test1.txt'));  //unlink() 删除文件,如果文件不存在,返回fasle,并且产生一个警告,所以在删除前需要先判断文件是否真的存在
if (file_exists('./test1.txt')){
    unlink('./test1.txt');
}
var_dump(dirname(__FILE__));  //dirname()返回当前文件的文件目录,只会返回目录。如果文件使用的是相对路径,则只会返回相对路径的地址
  • fopen() //没什么好说的,在读取和写入文件之前首先要打开文件,打开的几种方式 r只读 r+读写,指针在文件的头部,如果直接使用则会将后面的字符替换掉 w只写w+读写指针在文件的头部 a只写,相当于在文件的尾部进行追加

a+读写文件尾部进行追加 append的简写 x创建并以写入方式打开,指针在文件的头部 x+类似x=,读写方式打开 b打开一个二进制文件

注意:当写入一个文本文件并想插入一个新行时,需要使用符合操作系统的行结束符号。基于 Unix 的系统使用 \n 作为行结束字符,基于 Windows 的系统使用 \r\n 作为行结束字符,基于 Macintosh 的系统使用 \r 作为行结束字符。

fread() //没什么还说的,读取文件的内容。需要两个参数,第一个为打开的文件资源,第二个为要读取的内容的大小

var_dump(filesize($file));  //文件的大小
fwrite(); //三个参数 第一个已经打开的文件资源 第二个为要插入的文件的内容 第三个要插入的文件的大小 和fputs()用法一致
fclose();  //没什么好说的,打开文件操作完之后要关闭文件,需要传递已经打开的文件的资源
fclose(fopen($file,'r'));
var_dump(fileatime($file)); //返回上次访问                                                                                                                                                                                                                                                                                                                                                         

文件的时间戳

filectime(); //上次修改的时间戳
var_dump(flock($file));  //为文件加锁,比如对临界资源的等待
fgetc()  //从文件中读取字符
fgets() //从文件中读取一行
unlink($file); //删除文件
4.2 对目录的操作

通过PHP函数的方式对目录进行遍历
涉及到的函数 opendir() mkdir() rmdir() readdir()只会删除空的文件夹

使用递归的方法

$dir = './test';

递归要使用函数

function loopDir($dir){
    //1.判断传递进去的是不是文件夹
    if (!is_dir($dir)){
        return false;
    }
    //2.打开文件夹
    $handle = opendir($dir);
    //3.循环读取文件夹中的每一个文件
    while(false !== ($file = readdir($handle))){
        //4.过滤当前目录和上级目录
        if ($file != '.' && $file != '..'){
            //5.判断当前文件是不是DIR类型
            if (filetype($dir . '/' .$file) == 'dir'){
                loopDir($dir . '/' . $file);
            }else{
                //6.打印
                echo $file . PHP_EOL;
            }
        }
    }
}

loopDir($dir);
4.3 注意事项
  1. 在删除文件的时候,注意要过滤..文件夹,有可能无限向上删除
  2. 在操作文件的时候,必须先要打开文件

=====================5. PHP 会话控制技术=====================

5.1 为什么要使用会话技术

由于http协议是无状态的,同一个用户连续两次请求不同的页面会认为不是同一个用户进行的访问。这就有问题了

比如用户已经登录了,然后再跳转到订单页面发现自己还是未登录的状态,因此需要使用会话技术来记录用户的状态,以便知道用户是否进行了页面的跳转

涉及到 cookie的函数

setcookie($name,$value,$expire,$path,$domain,$secure) //键 值 过期时间 路径 域名 安全
$_COOKIE() 读取cookie
  • 优点:将用户的信息储存在用户的客户端不会占用服务端的资源
  • 缺点:不安全,用户可以禁用cookie
5.3 session

session信息存储在服务端,客户端存的是sessionId session是基于cookie

session相关的函数
session_start() //开启session
$_SESSION() 获取session的值
session_destroy();


session.auto_start =; //自动开启session
session.cookie_domain =; //存取的sessionId的cookie的有效域名
session.cookie_lifetime =; //cookie的过期时间i
session.cookie_path =; //cookie的路径
session.session_save_path =; //

session的垃圾回收机制
session.gc.probability = 1;
session.gc.divisor = 100;
session.gc.maxlifetime = 1440;  //当前的时间-最后的修改时间 > 1440  每清除一百次会有一次清除成功的机会


session.save_handle = 'redis';
5.4 session存储,如果有多台服务器,可以将session存储到数据库 memcache redis中
session_set_save_handler();  //将session储存到redis等

=====================6. PHP面向对象=====================

6.1 PHP类的权限控制符
public protected private
6.2 继承
6.3 多态

抽象类 有抽象方法一定是抽象类

6.4 常用的设计模式
  • 工厂模式
  • 单例模式
  • 注册树模式
  • 适配器模式
  • 观察者模式
  • 策略模式

=====================7.Tcp/IP协议=====================

7.1 HTTP 协议状态码
1XX
2XX 成功,响应成功 200 204 206
3XX 重定向 301 302
4XX 客户端请求错误 400请求错误 401 认证信息 403 拒绝 404 not found
5XX 服务器错误 503 服务器无法处理
7.2 OSI 七层模型

物理层 数据链路层 网络层 传输层 会话层 表示层 应用层

1.物理层  //建立 维护 断开物理连接
2.数据链路层  //建立逻辑连接 进行硬件物理寻址 差错校验等
3.网络层 //进行逻辑地址寻址,实现不同网络之间的选择
4.传输层 //定义传输数据协议的端口号 以及流控和差错校验 TCP UDP
5.会话层 //建立 管理 终止会话
6.表示层 //数据的表示 安全 压缩
7.应用层 //网络协议与用户的最终接口 HTTP FTP SMTP DNS HTTPS
7.3 HTTP协议工作原理

1.客户端发送请求给服务端,创建一个tcp连接,指定端口号 默认为80

2.连接到服务器后,服务器会监听浏览请求,分析请求类型,返回数据和内容

Content-Type
Accept
Origin
Cookie
Cache-Control
user-Agent
Referrer
Access-control-Allow-origin //跨域使用
7.4 HTTP的请求方法

get(查看 幂等) post(非幂等 创建) put(幂等 修改) delete(幂等) (head options trace 查看服务器性能)

幂等 非幂等

get和post有什么区别

1.get后退操作不会造成影响,post后退会重新提交
2.post不能被缓存
3.get url参数有限制
4.get不安全 post比较安全
7.5 常见的网络协议和端口
FTP 文件传输协议 21
TELNET 远程登录 23
SMTP 邮件发送协议 25
POP3 邮件接收协议 110
HTTP 超文本传输协议 80
DNS  域名解析 53

=====================8.PHP开发环境 (nginx + php-fpm)=====================

8.1 cgi协议 为了实现语言解析器和webserver之间的通信
8.2 fastcgi是cgi的改良

cgi的效率很低,webserver每收到一个请求就会fork一个cgi进程,请求处理完再kill掉这个进程,这样很浪费
fastcgi 每次处理请求之后不会kill掉这个进程,保留这个进程,一个进程可以处理多个请求,不需要每次都fork

8.3 php-fpm php:fastcgi process manager fastcgi的进程管理器

master进程 work进程(多个)一个进程嵌套PHP解析器 端口9000 通过nginx的反向代理,代理9000端口

8.4 PHP常见的配置项
register_globals 注册全局变量,不建议打开
allow_url_fopen 打开远程文件
allow_url_include 是否远程包含文件
date_timezone 时间
display_errors
error_reporting 错误级别
safe_mode 安全模式
upload_max_filesize 允许上传的文件大小
max_file_uploads 允许同时上传的数量
post_max_size 允许post上传的大小

真题:请简述cgi fastcgi 和 php-fpm的区别

cgi是一种协议,是为了实现webServer和语言解析器之间通信的协议。每当浏览器用请求出现时,webServer就会fork一个cgi进程,在这个请求处理完之后就会kill掉这个进程
fastcgi是cgi协议的改良版。当webServer收到请求并且处理完之后,不会kill掉这个进程而是用来处理其他进程

php-fpm是fastcgi的进程管理器。包括master进程和work进程。通常master进程负责和网络进行通信,而且work进程负责语言解析,每一个work进程包含一语言解析器

=====================9.PHP 使用js jq vue.js等=====================

9.1 ajax技术运用了什么原理
async -javascript - and - xml

xMLHttpRequest()是实现ajax的基础

=====================10.PHP linux基础知识点=====================

10.1 系统安全性
//sudo
//su
//chmod
//setfacl
10.2 进程管理
//w
//top
//ps
//kill
//pkill
//pstree
//killall
10.3 用户管理
10.4 文件系统
10.5 网络
10.6 文件查看
tail less head more
10.7 目录操作
crontab**分 时 日 月 周

=====================11.Mysql相关操作点=====================

11.1 mysql数据类型
tinyint smallint bigint
  • 整数类型 int(11) 这个11只是显示的宽度,并不会影响取值范围,最小宽度 整形括号里面的数据对于大多数应用是没有意义的

  • 实数类型 float double decimal decimal是比bigint还大的整数,但是会被当做字符串来处理
    varchar(可变长度,超出长度会被截断) char(固定长度,会根据需要补充空格,适合比较短的字符串,或者长度都差不多的,比如密码 唯一标识等,超出长度会被截断) text blob

对于经常变更的数据,char比varchar更好,插入不容易产生碎片,对于比较短的字符,char比varchar更有效率

进行不使用text和blob,会先查询临时表,造成不必要的开销

  • 枚举类型

日期和时间类型 尽量使用timestamp 比 datetime 的 空间效率要高 ,如果要储存微秒,需要使用bigint

11.2 列属性
auto_increment 自增
default 默认值
not null 非空
zerofill 0填充
11.3 mysql的基本操作
mysql -u -h -p _P  //u username h host p password P port mysql连接

\G //垂直显示 \c 取消mysql命令 \q 退出mysql \s 服务器状态 \h 帮助信息 \d 改变符号

11.4 mysql数据表引擎

InnoDb 默认事务型引擎,数据存在共享表空间可以通过配置分开 对主键查询的性能要高于其他引擎 从磁盘读取数据时自动在内存构建hash索引 插入数据自动构建缓冲区 支持行级锁 支持外键

MyISAM 5.1版本前默认的存储引擎 拥有全文检索 压缩和空间函数 不支持事务和行级锁 不支持热备份和安全

11.5 mysql的锁机制

当多个查询同一时刻进行数据修改的时候,就会产生并发控制的问题,这个时候mysql会进行锁表。包括共享锁(读锁)和排它锁(互斥锁,写锁)
写锁是临界资源,互斥的。同一个时候只能有一个进行写入
事务处理 InnoDB

11.6 mysql触发器

可以通过数据表中的中间表(外键)进行级联修改,不建议使用

11.7 mysql索引基础和类型

mysql先去索引中找到对应的值,然后根据匹配的索引找到对应的数据行
大大减少服务器需要扫描的数据量,帮助服务器避免排序和临时表 将随机IO变成顺序IO 大大提升查询速度 (影响:减低写的速度 占用磁更多的磁盘空间)

对于数据量比较小的表,不要使用索引,性能会更高。对于中大型表需要使用索引。特大型的表使用索引的代价也会变大,可以使用分区技术解决

索引的类型 普通索引 唯一索引(唯一约束) 主键索引 一个表只能有一个主键索引,可以有多个唯一索引;主键索引一定是唯一索引,但是唯一索引不一定是主键索引 主键可以和外键参照建立约束,防止数据的不统一

联合索引 将多个列组合在一起构成索引,涉及到多个列,为了减低索引的范围 外键索引 全文索引(只能对英文进行全文索引,没啥意思)

11.8 mysql索引创建的规则 !!!
  1. 最适合做索引的列是出现在where字句里面的列,而不是select关键字后面的列
  2. 索引列的基数越大,索引的效果越好
  3. 对于字符串的索引,应该指定一个前缀长度,可以节省大量的索引空间
  4. 根据情况创建符合索引,符合索引可以大大提高查询的效率
  5. 避免创建过多的索引,索引会额外的占用磁盘空间,降低写操作的效率
  6. 主键尽可能选择较短的数据类型,可以有效减少索引占用磁盘空间,提高查询效率
注意:
  1. 符合索引遵循前缀原则
  2. like查询,%不能在前,可以使用全文检索解决问题 where name like “wang%”
  3. column is null 可以使用索引
  4. 如果mysql估计使用索引比全表扫描更慢,会放弃使用索引
  5. 如果or前的条件有索引 后面没有,那么索引不会被用到
  6. 列类型是字符串类型,查询的时候一定要给值加引号,不然用不到索引
11.9 mysql语句的编写
//关联更新
$sql = <<<EOL
UPDATE A,B SET A.c1 = B.c1,A.c2 = B.c2 WHERE A.id = B.id AND B.age > 50;
UPDATE A AS t1 INNER JOIN B AS t2 ON ti.id = t2.id SET t1.c1 = t2.c1,t1.c2 = t2.c2 WHERE t2.age > 50;
EOL;
//关联查询
//六种关联查询 cross join(笛卡尔积,没有意义)、inner join、left(right) join、union(union all)、full join
//内连接 等值连接 不等值连接 自连接 inner join = join inner可以省略不写
$sqlInner = <<<EOL
SELECTFROM A,B WHERE A.id = B.id AND B.id > 50;
SELECTFROM A t1 INNER JOIN B t2 ON t1.id = t2.id WHERE t2.age > 50;
SELECTFROM A t1 JOIN A t2 ON t1.id = t2.pid WHERE t1.age > 50;
EOL;
//外连接 left join 以左表为主 和right join 以右表为主 如果匹配不到用null填充
//联合查询union 把多条结果集集中在一起,以union前的结果为准,需要注意的是联合查询的列数要相等,相同的记录行会合并 union all
$sqlUnion = <<<EOL
SELECTFROM A UNION SELECTFROM B....
EOL;
//全连接 mysql不支持全连接,可以使用left join 和 union 和 right join 联合使用
$sqlFull = <<<EOL
SELECTFROM A LEFT JOIN B ON A.id = B.id union SELECTFROM A RIGHT join  B ON A.id = B.id;
EOL;
//嵌套查询 子查询
$sqlInclude = <<<EOL
SELECTFROM A WHERE (SELECT id FROM B WHERE B.age > 50);
EOL;

//example
$sqlExample = <<<EOF
SELECT t1.teamName,m.matchResult,t2.teamName,m.matchTime

FROM `match` as m LEFT JOIN `team` as t1 ON t1.teamId = m.hostTeamId,left join `team` as t2 ON t2.teamId = m.guestTeamId

WHERE m.matchTime between "2016-6-1" AND "2016-9-1";
EOF;
坚持原创技术分享,您的支持将鼓励我继续创作!