php之基础知识

发布时间 2023-10-09 18:22:01作者: songxia777

视频教程

1. 简介和概述

  • PHP 脚本在服务器上执行然后向浏览器发送回纯文本的 HTML 结果
  • PHP 是一种创建动态交互性站点的强有力的服务器端脚本语言
  • 超文本预处理器,服务器端脚本语言,在服务器上执行
  • PHP是脚本语言,不需要事先编译,可以在服务器端运行
  • PHP 是 "PHP Hypertext Preprocessor" 的首字母缩略词
  • PHP 没有成本,可供免费下载和使用
  • PHP可以用于收集表单数据,生成动态网页,字符串处理,动态输出图像,处理服务器端文件,与数据库交互,会话跟踪,处理XML文件,支持大量网络协议,服务器端的其他相关操作
  • PHP可以运行在windows,Linux等各种操作系统上
  • PHP是一种运行在服务器端的HTML的脚本/编程语言,主要是用来生成动态网页

1.1 什么是 PHP 文件?

  • PHP 文件能够包含文本、HTML、CSS 以及 PHP 代码
  • PHP 代码在服务器上执行,而结果以纯文本返回浏览器
  • PHP 文件的后缀是 ".php"

1.2 URL地址格式解释

  • 格式:http://host[:post][abs_path]
  • http:// 表示要通过HTTP协议定位网络资源
  • host:表示合法的Internet主机域名或IP地址
  • post:是指定一个端口号,默认是80
  • abs_path:是被请求资源的位置

1.3 PHP 能够做什么?

  • PHP 能够生成动态页面内容
  • PHP 能够创建、打开、读取、写入、删除以及关闭服务器上的文件
  • PHP 能够接收表单数据
  • PHP 能够发送并取回 cookies
  • PHP 能够添加、删除、修改数据库中的数据
  • PHP 能够限制用户访问网站中的某些页面
  • PHP 能够对数据进行加密

1.4 为什么使用 PHP?

  • PHP 运行于各种平台(Windows, Linux, Unix, Mac OS X 等等)
  • PHP 兼容几乎所有服务器(Apache, IIS 等等)
  • PHP 支持多种数据库
  • PHP 是免费的
  • PHP 易于学习,并可高效地运行在服务器端

1.5 网站的基本概念

1.5.1 服务器

  • 服务器(server),也称伺服器,是提供计算服务的设备。由于服务器需要响应服务请求,并进行处理,因此一般来说服务器应具备承担服务并且保障服务的能力。
  • 服务器的构成包括处理器、硬盘、内存、系统总线等,和通用的计算机架构类似,但是由于需要提供高可靠的服务,因此在处理能力、稳定性、可靠性、安全性、可扩展性、可管理性等方面要求较高。
  • 在网络环境下,根据服务器提供的服务类型不同,分为文件服务器,数据库服务器,应用程序服务器,WEB服务器等。

服务器:能够提供服务的机器,取决于机器上所安装的软件(服务软件)
Web服务器:提供web服务(网站访问),就需要安装web服务软件,Apache,tomcat,iis等

1.5.2 IP的概念

域名(Domain Name),是由一串用点分隔的名字组成(www.itcast.cn)的Internet上某一台计算机或计算机组的名称,用于在数据传输时标识计算机的电子方位(有时也指地理位置,地理上的域名,指代有行政自主权的一个地方区域)。域名是一个IP地址上有“面具” 。一个域名的目的是便于记忆和沟通的一组服务器的地址(网站,电子邮件,FTP等)。域名作为力所能及难忘的互联网参与者的名称。

特殊IP:127.0.0.1,代表本机
特殊域名:localhost

1.5.3 DNS域名系统

DNS(Domain Name System,域名系统),因特网上作为域名和IP地址相互映射的一个分布式数据库,能够使用户更方便的访问互联网,而不用去记住能够被机器直接读取的IP数串。

通过主机名,最终得到该主机名对应的IP地址的过程叫做域名解析(或主机名解析)。

用户输入域名localhost—》DNS(localhost 127.0.0.1)--》服务器电脑

1.5.4 端口

端口(Port),可以认为是设备与外界通讯交流的出口。端口可分为虚拟端口和物理端口,其中虚拟端口指计算机内部或交换机路由器内的端口,不可见。例如计算机中的80端口、21端口、23端口等。物理端口又称为接口,是可见端口,计算机背板的RJ45网口,交换机路由器集线器等RJ45端口。

用户输入域名localhost:端口—》DNS(localhost 127.0.0.1)--》服务器电脑—》软件(服务)

2. 基 础 语 法

PHP是一种运行在服务器端的脚本语言,可以嵌入到HTML中

  • PHP 脚本可放置于文档中的任何位置
  • PHP 脚本以 <?php 开头,以 ?> 结尾,一般是建议省略不写
  • PHP 文件的默认文件扩展名是 .php
  • PHP 文件通常包含 HTML 标签以及一些 PHP 脚本代码
  • PHP 语句以分号()结尾
  • PHP 代码块的关闭标签也会自动标明分号(因此在 PHP 代码块的最后一行不必使用分号)
  • PHP大小写敏感
    • 所有用户定义的函数、类和关键词(例如 if、else、echo 等等)都对大小写不敏感
    • 所有 变量 都对大小写敏感
<?php
	// 此处是 PHP 代码
?>
    

2.1 PHP注释

单行注释
// XXX

单行注释
# XXX

/*

这是多行注释块
它横跨了
多行
*/

2.2 PHP脚本标记

在PHP历史发展中,可以使用多种标记来区分PHP脚本

1 ASP标记:<% php代码 %> 和 短标记:<? Php代码 ?>,但是以上两种基本弃用,如果要使用那么需要在配置文件中开启 php.ini
image

2 脚本标记:<script language="php">php代码</script>
image

3 标准标记(常用):<?php php代码?>
image

2.3 PHP语句分隔符 ;分号

语句分隔符:在PHP中,代码是以行为单位,系统需要通过判断行的结束,该结束通常都是一个符号:分号“;”(英文状态下的分号)

$a = 5; // 如果没有以 分号 结束,会报语法错误

Echo ‘hello world’ // 最后结尾的分号可以省略

备注:

1、 PHP中标记结束符?>有自带语句结束符的效果,最后一行PHP代码可以没有语句结束符“;”

<?php
 echo 'hello world';
 echo 'hello world';

image

2、 PHP中其实很多代码的书写并不是嵌入到HTML中,而是单独存在,通常书写习惯中就不建议使用标记结束符?>,PHP会自动从开始到最后全部认为是PHP代码,从而解析

image

3. PHP打印输出

PHP 是通过 print 和 echo 语句来动态输出 HTML 内容

3.1 echo和print打印输出

  • echo - 可以输出一个或多个字符串
  • print - 只能输出简单类型变量的值,如int,string
  • print_r - 可以输出复杂类型变量的值,如数组,对象
  • 二者的区别:

    echo可以输出一个或多个字符串;print只允许输出一个字符串,返回值总是1
    echo的输出速度比print块

echo 'hello world'
print 'hello world'

image

3.2 var_dump 打印输出对象和数组

4. PHP变量:是 存储信息 的容器

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

PHP 是一门类型松散的语言(弱类型语言),可以不必告知 PHP 变量的数据类型,php可以根据它的值,自动把变量转换为正确的数据类型

<?php
    
$txt="Hello world!";
$x=5;
$y=10.5;
$var; // 定义变量
$var=10; // 定义变量同时赋值

?>
    

将变量从内存中删除 unset

unset($var)

4.1 变量规则

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

4.2 变量作用域

  • 在 PHP 中,可以在脚本的任意位置对变量进行声明
  • 变量的作用域指的是变量能够被引用/使用的那部分脚本
  • PHP 有三种不同的变量作用域:全局变量、局部变量、超全局变量
  • PHP 有四种不同的变量作用域:local global static parameter

4.2.1 全局变量和局部变量

全局变量

函数之外声明的变量,就是用户普通定义的变量,只能在函数以外进行访问

注意:如果函数内部想要访问,可以使用global特殊关键字,是因为定义的全局变量默认会被纳入超全局变量$GLOBALS中

$name = 'James';
function test()
{
  // 可以使用超全局变量访问
  $GLOBALS['name'];
  // 或者
  global $name;
} 

脚本周期:直到脚本运行结束(最后一行代码执行完)

局部变量

就是在函数内部声明的变量,只能在函数内部进行访问

函数周期:函数执行结束(函数是在栈区中开辟独立内存空间运行)

您可以在不同的函数中创建名称相同的局部变量,因为局部变量只能被在其中创建它的函数识别

<?php
$x=5; // 全局作用域

function myTest() {
  $y=10; // 局部作用域
  echo "<p>测试函数内部的变量:</p>";
  echo "变量 x 是:$x";
  echo "<br>";
  echo "变量 y 是:$y";
} 

myTest();

echo "<p>测试函数之外的变量:</p>";
echo "变量 x 是:$x";
echo "<br>";
echo "变量 y 是:$y";
?>

    /*
        返回结果

        在函数内部测试变量:函数之外声明的变量不能在函数内部使用
        变量 x 是:          
        变量 y 是:10

        在函数之外测试变量:函数内部声明的变量不能在函数外部使用
        变量 x 是:5
        变量 y 是:
*/
    

4.2.2 global 关键词

  • 可以用于在函数内访问全局变量(一般定义在函数外部的全局变量,在函数内部是不可以访问的),那么只要在(函数内部)变量前面使用 global 关键词即可 global $x,$y
  • 能够实现全局访问局部,同时局部也可以访问全局
<?php
    
$x=5;
$y=10;
function myTest() {
  global $x,$y;
  $y=$x+$y;
}

myTest();

echo $x; // 输出 5
echo $y; // 输出 15

?>

Global关键字:是一种在函数里面定义变量的一种方式

1、 如果使用global定义的变量名在外部存在(全局变量),那么系统在函数内部定义的变量直接指向外部全局变量所指向的内存空间(同一个变量)

2、 如果使用global定义的变量名在外部不存在(全局变量),系统会自动在全局空间(外部)定义一个与局部变量同名的全局变量

本质的形式:在函数的内部和外部,对一个同名变量(全局和局部)使用同一块内存地址保存数据,从而实现共同拥有

global 变量名;    // 不能赋值
变量名 = 值;     // 修改

<?php

$global_name='James';

function display() {
  global $global_name;  // 在函数内部访问 全局变量
  echo $global_name;

  global $inner_name;
  $inner_name='Amary';
}

display();

echo $inner_name; // 在函数外部访问 函数内部的局部变量

虽然以上方式可以实现局部与全局的互访,但是通常不会这么用

一般如果会存在特殊使用,也会使用参数的形式来访问。(还可以使用常量:define定义的)

4.2.3 static 关键词:静态变量

是在函数内部定义的变量,使用static关键字修饰,主要是用来实现跨函数共享数据(是指同一个被调用多次):函数运行结束所有局部变量都会清空,如果重新运行一下函数,所有的局部变量又会重新初始化

function 函数名(){
	// 定义静态变量
	static $变量名 = 值;		// 通常会在定义的时候就直接赋值
}

通常,当函数完成或执行后,会自动删除所有变量;不过,有时我需要不删除某个局部变量,那么这时就是在首次声明变量时使用 static 关键词:

<?php

function display() {
  $count1=10; // 局部变量
  static $count2=10; // 静态变量

  echo $count1,$count2;

  $count1++;
  $count2++;
  
}

display(); // 输出:10 10
display(); // 输出:10 11
display(); // 输出:10 12
/*
 每当函数被调用时,这个变量所存储的信息都是函数最后一次被调用时所包含的信息
 但是该变量仍然是函数的局部变量
*/
  

4.2.4 参数作用域

  • 参数是通过调用代码将值传递给函数的局部变量
  • 参数是在参数列表中声明的,作为函数声明的一部分
  • 所有的形参都可以理解为 局部变量
<?php
    
function myTest($x) {
  echo $x;
}
myTest(4);  //返回结果:4

?> 
    

4.2.5 作用域总结

  • 定义在函数外部的就是全局变量,它的作用域从定义处一直到文件结尾
  • 函数内定义的变量就是局部变量,它的作用域就在函数定义范围内
  • 函数之间存在作用域互不影响
  • 函数内部访问全局变量需要使用global关键字,或者使用$GLOBAL[index]数组

4.3 PHP 超全局变量

  • 超全局变量在 PHP 4.1.0 中引入,是在 全部作用域中 始终可用的 内置变量,也称为 预定义变量
  • 在脚本的任何位置都访问,没有限制
  • 超全局变量会将全局变量自动纳入到$GLOBALS里面,而$GLOBALS没有作用域限制,所以能够帮助局部去访问全局变量:但是必须使用数组方式 $GLOBALS[变量名]
  • 如果想函数内部使用外部的全局变量:除了$GLOBALS之外,通过参数传值(如果要统一战线还可以使用引用传值)
$GLOBALS   PHP中所有的全局变量
$_SERVER   服务器信息
$_REQUEST   GET和POST提交的都会保存
$_POST   POST提交的数据都会保存在此
$_GET   获取所有表单以get方式提交的数据
$_FILES   用户上传的文件信息
$_ENV   环境信息
$_COOKIE   cookie会话数据
$_SESSION  session会话数据

4.3.1 $GLOBALS — 引用全局作用域中可用的全部变量

  • $GLOBALS 这种全局变量用于在 PHP 脚本中的任意位置访问全局变量(从函数或方法中均可)。
  • PHP 在名为 $GLOBALS[index] 的数组中存储了所有全局变量。变量的名字就是数组的键。
<?php 
    $x = 75; 
    $y = 25;

    function addition() { 
      $GLOBALS['z'] = $GLOBALS['x'] + $GLOBALS['y']; 
    }
    addition(); 
    echo $z;

?>
    

4.3.2 $_SERVER 保存关于报头、路径和脚本位置的信息

元素/代码 描述
$_SERVER['PHP_SELF'] 当前执行脚本的文件名,与 document root 有关。例如,在地址为 http://example.com/test.php/foo.bar 的脚本中使用 $_SERVER['PHP_SELF'] 将得到 /test.php/foo.bar。FILE 常量包含当前(例如包含)文件的完整路径和文件名。 从 PHP 4.3.0 版本开始,如果 PHP 以命令行模式运行,这个变量将包含脚本名。之前的版本该变量不可用。
$_SERVER['GATEWAY_INTERFACE'] 服务器使用的 CGI 规范的版本;例如,"CGI/1.1"。
$_SERVER['SERVER_ADDR'] 当前运行脚本所在的服务器的 IP 地址。
$_SERVER['SERVER_NAME'] 当前运行脚本所在的服务器的主机名。如果脚本运行于虚拟主机中,该名称是由那个虚拟主机所设置的值决定。(如: www.w3cschool.cn)
$_SERVER['SERVER_SOFTWARE'] 服务器标识字符串,在响应请求时的头信息中给出。 (如:Apache/2.2.24)
$_SERVER['SERVER_PROTOCOL'] 请求页面时通信协议的名称和版本。例如,"HTTP/1.0"。
$_SERVER['REQUEST_METHOD'] 访问页面使用的请求方法;例如,"GET", "HEAD","POST","PUT"。
$_SERVER['REQUEST_TIME'] 请求开始时的时间戳。从 PHP 5.1.0 起可用。 (如:1377687496)
$_SERVER['QUERY_STRING'] query string(查询字符串),如果有的话,通过它进行页面访问。
$_SERVER['HTTP_ACCEPT'] 当前请求头中 Accept: 项的内容,如果存在的话。
$_SERVER['HTTP_ACCEPT_CHARSET'] 当前请求头中 Accept-Charset: 项的内容,如果存在的话。例如:"iso-8859-1,*,utf-8"。
$_SERVER['HTTP_HOST'] 当前请求头中 Host: 项的内容,如果存在的话。
$_SERVER['HTTP_REFERER'] 引导用户代理到当前页的前一页的地址(如果存在)。由 user agent 设置决定。并不是所有的用户代理都会设置该项,有的还提供了修改 HTTP_REFERER 的功能。简言之,该值并不可信。)
$_SERVER['HTTPS'] 如果脚本是通过 HTTPS 协议被访问,则被设为一个非空的值。
$_SERVER['REMOTE_ADDR'] 浏览当前页面的用户的 IP 地址。
$_SERVER['REMOTE_HOST'] 浏览当前页面的用户的主机名。DNS 反向解析不依赖于用户的 REMOTE_ADDR。
$_SERVER['REMOTE_PORT'] 用户机器上连接到 Web 服务器所使用的端口号。
$_SERVER['SCRIPT_FILENAME'] 当前执行脚本的绝对路径。
$_SERVER['SERVER_ADMIN'] 该值指明了 Apache 服务器配置文件中的 SERVER_ADMIN 参数。如果脚本运行在一个虚拟主机上,则该值是那个虚拟主机的值。(如:someone@w3cschool.cn)
$_SERVER['SERVER_PORT'] Web 服务器使用的端口。默认值为 "80"。如果使用 SSL 安全连接,则这个值为用户设置的 HTTP 端口。
$_SERVER['SERVER_SIGNATURE'] 包含了服务器版本和虚拟主机名的字符串。
$_SERVER['PATH_TRANSLATED'] 当前脚本所在文件系统(非文档根目录)的基本路径。这是在服务器进行虚拟到真实路径的映像后的结果。
$_SERVER['SCRIPT_NAME'] 包含当前脚本的路径。这在页面需要指向自己时非常有用。FILE 常量包含当前脚本(例如包含文件)的完整路径和文件名。
$_SERVER['SCRIPT_URI'] URI 用来指定要访问的页面。例如 "/index.html"。

4.3.3 $_REQUEST 收集 HTML 表单提交的数据

案例:

  • 下面的例子展示了一个包含输入字段及提交按钮的表单。
  • 当用户通过点击提交按钮来提交表单数据时, 表单数据将发送到
    标签的 action 属性中指定的脚本文件。
  • 在这个例子中,我们指定文件本身来处理表单数据。
  • 如果您需要使用其他的 PHP 文件来处理表单数据,请修改为您选择的文件名即可。
  • 然后,我们可以使用超级全局变量 $_REQUEST 来收集 input 字段的值:
<html>
<body>
// $_SERVER['PHP_SELF'] 返回当前执行脚本的文件名

<form method="post" action="<?php echo $_SERVER['PHP_SELF'];?>">
    Name: <input type="text" name="fname">
    <input type="submit">
</form>

<?php 
    $name = $_REQUEST['fname']; 
    echo $name; 
?>

</body>
</html>

4.3.4 $_POST

  • 广泛用于收集提交 method="post" 的 HTML 表单后的表单数据
  • $_POST 也常用于传递变量
  • 下面的例子展示了一个包含输入字段和提交按钮的表单。当用户点击提交按钮来提交数据后,表单数据会发送到 标签的 action 属性中指定的文件。
  • 在本例中,我们指定文件本身来处理表单数据。如果您希望使用另一个 PHP 页面来处理表单数据,请用更改为您选择的文件名。然后,我们可以使用超全局变量 $_POST 来收集输入字段的值:
<html>
<body>

<form method="post" action="<?php echo $_SERVER['PHP_SELF'];?>">
Name: <input type="text" name="fname">
<input type="submit">
</form>

<?php 
$name = $_POST['fname'];
echo $name; 
?>

</body>
</html>

4.3.5 $_GET

  • PHP $_GET 也可用于收集提交 HTML 表单 (method="get") 之后的表单数据。
  • $_GET 也可以收集 URL 中的发送的数据

假定我们有一个包含参数的超链接HTML页面:

 <html>
 <body>

 <a href="test_get.php?subject=PHP&web=w3cschool.cn">Test $GET</a>

 </body>
 </html> 

当用户点击链接 "Test $GET", 参数 "subject" 和 "web" 将发送至"test_get.php",你可以在 "test_get.php" 文件中使用 $_GET 变量来获取这些数据

test_get.php文件代码

<html>
<body>

<?php
echo "Study " . $_GET['subject'] . " at " . $_GET['web'];
?>

</body>
</html>

4.4 变量传值

变量传值是指将一个变量赋值给另外一个变量。主要分为:值传递,引用传递

在内存中,通常有以下几个分区

  • 栈区:程序可以操作的内存部分(不存数据,运行程序代码),少但是快
  • 代码段:存储程序的内存部分(不执行)
  • 数据段:存储普通数据(全局区和静态区)
  • 堆区:存储复杂数据,大但是效率低

4.4.1 值传递

将变量保存的值赋值一份,然后将新的值给另外一个变量保存(两个变量没有关系)
image

4.4.2 引用传递

引用传递:将变量保存的值所在的内存地址,传递给另外一个变量:两个变量指向同一块内存空间(两个变量是同一个值)

$新变量 = &$老变量
image
image

8. PHP常量

  • 常量的作用和变量相似,但是常量一旦被定义就无法更改或撤销定义
  • 常量是单个值的标识符(名称)。在脚本中无法改变该值。
  • 有效的常量名以字符或下划线开头(常量名称前面没有 $ 符号)。
  • 常量是自动全局的,而且可以贯穿整个脚本使用
  • 常量的名字通常是以大写字母为主(与变量以示区别)

8.1 定义常量

如需设置常量,一般是使用 define() 函数 - 它使用三个参数:define(name,value,false)

  • 参数1-name:常量名(必选)
  • 参数2-value:常量值(必选)
  • 参数3-boolean:(选填)规定常量名是否对大小写不敏感,默认false(大小写敏感)

5.3版本后可以使用 const 关键字 定义常量 const API=3.14

<?php
    
// 默认是大小写敏感
define("GREETING", "Welcome to W3School"); 
echo GREETING;

// 大小写不敏感
define("GREETING", "Welcome to W3School", true);
echo greeting;

// 常量是自动全局的,而且可以贯穿整个脚本使用
function myTest() {
    echo GREETING;
}

// 使用const定义常量
const API=3.14  
    

8.2 系统常量

系统常量:系统帮助用户定义的常量,用户可以直接使用

8.2.1 常用的几个系统常量

PHP_VERSION:PHP版本号

PHP_INT_SIZE:整形大小

PHP_INT_MAX:整形能表示的最大值(PHP中整形是允许出现负数:带符号)

8.2.2 系统魔术常量

在PHP中还有一些特殊的常量,他们有双下划线开始+长两名+双下划线结束,这种常量称之为系统魔术常量:魔术常量的值通常会跟着环境变化,但是用户改变不了

__DIR__:当前被执行的脚本所在电脑的绝对路径

__FILE__:当前被执行的脚本所在的电脑的绝对路径(带自己文件的名字)

__LINE__:当前所属的行数

__NAMESPACE__:当前所属的命名空间

__CLASS__:当前所属的类

__METHOD__:当前所属的方法

5. PHP EOF(heredoc)php定界符

PHP EOF(heredoc)是一种在命令行shell(如sh,csh,bash,PowserShell,zsh)和程序语言(如Perl,PHP,Python,Ruby)里定义一个字符串的方法

所用就是按照原样,包括换行格式什么的,输出其在内的东西

在EOF中的任何特殊字符都不需要转义

使用规则:

  • 以<<<EOF开始标记开始,以EOF结束标记结束,结束标记必须顶头写,不能有缩进和空格即必须从行首开始,前后不能衔接任何空白字符和字符而且必须分号;结尾
  • EOF可以用其他任意字符代替,只需要保证开始标识和结束标识一致;比如常见的EOF,EOD,EOT等
  • 开始标识可以不带引号或带单引号,不带引号与带双引号效果一致,解释内嵌的变量和转义字符,带单引号则不解释内嵌的变量和转义字符
  • 当内容需要内嵌引号(单引号或双引号)时,不需要加转义符,本身可以对单双引号转义,里面的变量也不需要使用 . . 连接字符串
// 结构化定义
<?php 
$trs=<<<EOD
  <div>Hello world</div>
  <span>你好</span>
EOD;

var_dump($trs);

6. PHP数据类型

在PHP中指的是存储的数据本身的类型,而不是变量的类型。PHP是一种弱类型语言,变量本身没有数据类型。

常用数据类型:

String(字符串)

Integer(整型)

Float/Double(浮点型)

Boolean(布尔型)

Array(数组)

Object(对象)

NULL(空值)

6.1 各个数据类型

6.1.1 字符串=String

字符串语法定义

1、 单引号字符串:使用单引号包裹

2、 双引号字符串:使用双引号包裹

<?php 
    
$x = "Hello world!";
echo $x;

$y = 'Hello world 2';
echo $y;

?>

3、 nowdoc字符串:没有单引号的单引号字符串

/*
$str = <<<’边界符’
	字符串内容
边界符;
*/

4、 heredoc字符串:没有双引号的双引号字符串

/*
$str = <<<边界符
	字符串内容
边界符;
*/

$str=<<<EOT
    内容区域
EOT;  

比较适合定义那些比较短(不超过一行)或者没有结构要求的字符串

如果有结构要求,或者内容超过一行,可以使用 nowdoc 或者 heredoc方式定义

// 结构化定义
<?php 
$trs=<<<EOD
  <div>Hello world</div>
  <span>你好</span>
EOD;

var_dump($trs);
    
字符串转义:反斜杠+字母

在PHP中系统常用的转义符号如下:

\’:在单引号字符串中显示单引号

\”:在双引号字符串中显示双引号

\r:代表回车(理论上是回到当前行的首位置)

\n:代表新一行

\t:类似tab键,输出4个空格

\$:在PHP中使用$符号作为变量符号,因此需要特定识别
单引号和双引号的区别

1、 单引号中只能够识别 \’,双引号中只有 \’不能识别

<?php
$str1='你\r\n好\t呀\'嘿\"哈\$';
$str2="你\r\n好\t呀\'嘿\"哈\$";

echo $str1.'</br>'; // 输出: 你\r\n好\t呀'嘿\"哈\$
echo $str2;         // 输出: 你 好 呀\'嘿"哈$

2、 双引号可以解析变量(是因为双引号能够识别$符号),单引号不可以

<?php
$a='hello';

$str1='$a world';
$str2="$a world";
$str3="{$a} world"; // 使用专业的标识符解析变量

echo $str1.'</br>';   // 输出:$a world
echo $str2.'</br>';   // 输出:hello world
echo $str3;          // 输出:hello world

建议:使用专业的标识符 {$变量名} 解析变量

6.1.2 整数=Integer

  • 整数是没有小数的数字
  • 整数规则
    • 整数必须有至少一个数字(0-9)
    • 整数不能包含逗号或空格
    • 整数不能有小数点
    • 整数正负均可
    • 可以用三种格式规定整数:十进制、十六进制(前缀是 0x)或八进制(前缀是 0)

PHP中不需要用户这么复杂的去计算,提供了很多的函数进行转换

Decbin():十进制转二进制

Decoct():十进制转八进制

Dechex():十进制转十六进制

Bindec():二进制转十进制

6.1.3 浮点数=Float

  • 浮点数是有小数点或指数形式的数字

    浮点型定义有两种方式:
    $f = 1.23;
    $f = 1.23e10;	//科学计数法,其中e表示底10
    
  • 浮点型:小数类型以及超过整型所能存储范围的整数(不保证精度),精度范围大概在15个有效数字左右

  • 尽量不用用浮点数做精确判断:浮点数保存的数据不够精确,而且在计算机中凡是小数基本上存的都不准确

6.1.4 逻辑=Boolean

逻辑是 true 或 false,通常是用于判断比较
image

在进行某些数据判断的时候,需要特别注意类型转换

empty():判断数据的值是否为“空”,不是NULL,如果为空返回true,不为空返回false

isset():判断数据存储的变量本身是否存在,存在变量返回true,不存在返回false

6.1.5 数组=Array

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

<?php
// 创建数值数组
$cars = array("Volvo", "BMW", "SAAB");
var_dump($cars);

// 创建索引数组
$cars2=array('name'=>'James',"age"=>19);
var_dump($cars2);

// 创建索引数组
$order = array(0 => array('id' => 1, 'type' => 'kecheng'), 1 => array('id' => 2, 'type' => 'shipin'));
var_dump($order);
    

image

6.1.6 对象=Object

  • 对象是存储数据和有关如何处理数据的信息的数据类型。
  • 在 PHP 中,必须明确地声明对象
  • 首先我们必须声明对象的类。对此,我们使用 class 关键词。类是包含属性和方法的结构;然后我们在对象类中定义数据类型,然后在该类的实例中使用此数据类型

6.1.7 NULL 值

  • 特殊的 NULL 值表示变量无值。NULL 是数据类型 NULL 唯一可能的值。
  • NULL 值标示变量是否为空。也用于区分空字符串与空值数据库。
  • 可以通过把值设置为 NULL,将变量清空:

6.1.8 伪类型

Mixed:混合的,可以是多种PHP中的数据类型

Number:数值的,可以是任意数值类型(整形和浮点型)

6.2 类型转换

类型转换:在很多的条件下,需要指定的数据类型,需要外部数据(当前PHP取得的数据)转换成目标数据类型

6.2.1 自动转换

自动转换:系统根据需求自己判定,自己转换(用的比较多,效率偏低)

6.2.2 强制转换

在变量之前增加一个括号(),然后在里面写上对应类型:int/integer….其中NULL类型用到unset()

在转换过程中,用的比较多的就是转布尔类型(判断)转数值类型(算术运算

1. 其他类型转布尔类型

true或者false,在PHP中比较少类型换变成false

image

2. 其他类型转数值类型
  • 布尔true为1,false为0
  • 字符串转数值有自己的规则
    • 以字母开头的字符串,永远为0
    • 以数字开头的字符串,取到碰到字符串为止(不会同时包含两个小数点)

6.3 类型判断

通过一组类型判断函数,来判断变量,最终返回这个变量所保存数据的数据类型(相同结果为true,失败为false):是一组以is_开头后面跟类型名字的函数:is_XXX(变量名)

Bool类型不能用echo来查看,可以使用var_dump结构查看

Var_dump(变量1,变量2…)

image

6.3.1 获取类型Gettype(变量名)

Gettype(变量名):获取类型,得到的是该类型对应的字符串
image

6.3.2 设置数据类型Settype(变量名,类型)

设定数据类型:但是强制转换还是不同的

强制转换(类型)变量名,是对数据值复制的内容进行处理(不会处理实际存储的内容)

settype 会直接改变数据本身

10. PHP运算符

image
image
image
image
image
image

11. PHP函数

11.1 简介和概述

  • 函数是可以在程序中重复使用的语句块。
  • 页面加载时函数不会立即执行,函数只有在被调用时才会执行
  • 函数:function,是一种语法结构,将实现某一个功能的代码块(多行代码)封装到一个结构中,从而实现代码的重复利用(复用)

11.2 PHP自定义函数

11.2.1 函数命名规范

函数名字:在一个脚本周期中,不允许出现同名函数(通常在一个系统开发中都不会使用同名函数)

  • 函数名由字母、数字和下划线组成,但是不能以数字开头
  • 函数名对大小写不敏感
  • 函数名应该能够反映函数所执行的任务。
function functionName() {
  // 被执行的代码;
}


<?php
    
//自定义函数
function sayHi() {
  echo "Hello world!";
}

sayhi(); // 调用函数(函数名对于大小写不敏感)

?>
    

函数作为一种常用的结构,一般遵循以下规则:函数通常名字代表着函数的功能,而有些功能会比较复杂,可能一个单词不足以表达,需要多个组合。

1、 驼峰法:除了左边第一个单词外,后面所有的单词首字母都大写:showParentInfo()

2、 下划线法:单词之间通过下划线连接,单词都是小写:show_parent_info()

11.2.2 PHP函数参数

  • 可以通过参数向函数传递信息。
  • 参数被定义在函数名之后,括号内部。您可以添加任意多参数,只要用逗号隔开即可。
<?php
    
// 一个参数
function familyName($fname) {
  echo "$fname Zhang.<br>";
}

familyName("Li");

// 多个参数
function familyName($fname,$year) {
  echo "$fname Zhang. Born in $year <br>";
}

// 设置默认参数
function setHeight($minheight=50) {
  echo "The height is : $minheight <br>";
}
setHeight(350);

?>

11.2.3 函数返回值,rerurn返回

如需使函数返回值,请使用 return 语句

function sum($x,$y) {
  $z=$x+$y;
  return $z;
}

11.3 常用的系统函数

11.3.1 有关输出的函数:print和print_r

print()==类似于echo输出提供的内容,本质是一种结构(不是函数),返回1,可以不需要使用括号
print_r()==类似于var_dump,但是比var_dump简单,不会输出数据的类型,只会输出值(数组打印使用比较多)

image

11.3.2 有关时间的函数

date()格式化时间

按照指定格式对对应的时间戳(从1970年格林威治时间开始计算的秒数)转换成指定的格式,如果没有指定特定的时间戳,那么就是默认解释当前时间戳

// 当前系统时间
echo date('Y-m-d H:i:s');

// 第2个参数是指定时间戳,表示指定时间戳的时间
echo date('Y-m-d H:i:s',5689562323);  

time()当前时间的时间戳
$curWeek= date('Y-m-d H:i:s');
echo '当前日期:'.$curWeek;

$nextWeek=date('Y-m-d H:i:s',time()+7*24*60*60);
echo '下周:'.$nextWeek;

microtime()获取微秒级别的时间
strtotime()按照规定格式的字符串(必须是英文的)转换成时间戳
$nextWeek=date('Y-m-d H:i:s',strtotime('tomorrow 10 hours'));
echo '明天10点:'.$nextWeek;

image

11.3.3 有关数字的函数

max()==指定参数中最大的值
min()==比较两个数中较小的值
rand()==得到一个随机数,指定区间的随机整数
mt_rand()==与rand一样,只是底层结构不一样,效率比rand高(建议使用)
round()==四舍五入
ceil()==向上取整
floor()==向下取整
pow()==求指定数字的指定指数次结果:pow(2,8) == 2^8 == 256
abs()==绝对值
sqrt()==求平方根

11.3.4 有关函数的函数

function_exists():判断指定的函数名字是否在内存中存在(帮助用户不去使用一个不存在的函数,让代码安全性更高)

func_get_arg():在自定义函数中去获取指定数值对应的参数

func_get_args():在自定义函数中获取所有的参数(数组)

func_num_args():获取当前自定义函数的参数数量

11.4 可变函数:回调函数

当前有一个变量所保存的值,刚好是一个函数的名字,那么就可以使用$变量名()来充当函数名使用

$变量名 = ‘display’;
function display(){
}
// 可变函数
$变量名();

<?php
// 可变函数:变量的值和函数名 同名,就可以使用 $变量名() 的方式访问函数
$name='display';

function display() {
  echo 'hello';
}
$name();

可变函数在系统使用的过程中还是比较多的,尤其是使用很多系统函数的时候:需要用户在外部定义一个自定义函数,但是是需要传入到系统函数内部使用

将一个用户自定义函数传入给另外一函数去使用的过程叫做回调过程,被传入函数就是回调函数

<?php
// 可变函数:变量的值和函数名 同名,就可以使用 $变量名() 的方式访问函数
function sys_func($arg,$callback) {
 $arg+=10;
 return $callback($arg);
}

// 获取一个数的4次方 : 回调函数
function user_func($arg){
  return $arg*$arg*$arg*$arg;
}

// 输出 10的4次方(实际上是获取20的4次方)
echo  sys_func(10,'user_func');


// 或者使用下面的方式
function sys_func($arg,$callback) {
 $arg+=10;
 return $callback($arg);
};

// 输出 10的4次方(实际上是获取20的4次方)
echo  sys_func(10,function($arg){
  return $arg*$arg*$arg*$arg;
});

11.5 匿名函数

就是没有名字的函数

$变量名 = function(){
	函数体
};
// 调用函数
$变量名();


<?php
// 匿名函数:就是没有名字的函数
$sys_func=function() {
 return 'hello world';
};
// 调用匿名函数:可变函数
echo $sys_func();


变量保存匿名函数,本质得到的是一个对象类型 Closure
image

闭包(closure)

函数内部有一些局部变量(要执行的代码块),在函数执行之后没有被释放,是因为在函数内部还有对应的函数在引用(函数的内部函数:匿名函数)

<?php
// 匿名函数:就是没有名字的函数
function display(){
  $name='hello';

  // 匿名函数:函数内部的函数
  // $userInfo=function(){
  //   echo $name; // 访问不到 $name局部变量
  // };

  $userInfo=function() use($name){
     // 访问 $name局部变量:use就是将外部变量($name)保留给内部使用(就是所谓的闭包)
     echo $name;
  };

  // 调用 匿名函数
  $userInfo();
};

 display();

12 PHP数组

12.1 简介和概述

  • 数组:数据的组合,指将一组数据(多个)存储到一个指定的容器中,用变量指向该容器,然后可以通过变量一次性得到该容器中的所有数据
  • 数组能够在单独的变量名中存储一个或多个值
  • 数组是特殊的变量,它可以同时保存一个以上的值
  • 数组的分类:
    • 索引数组:带有数字索引的数组==数组下标是整数
    • 关联数组:带有指定键的数组==数组下标是字符串
    • 多维数组:包含一个或多个数组的数组

12.2 数组的特点

1) 数组的下标:可以是整数,或者字符串

如果数组下标都为整数:索引数组

如果数组下标都为字符串:关联数组

2) 不同下标可以混合存在:混合数组

3) 数字下标的自增长特性

从0开始自动增长,如果中间手动出现较大的,那么后面的自增长元素从最大的值+1开始

4) 特殊值下标的自动转换

​ 布尔值:true和false

​ 空:NULL

image

5) PHP中数组元素没有类型限制、也没有长度限制

PHP中的数组是很大的数据,所以存储位置是堆区,为当前数组分配一块连续的内存

12.3 数组的定义 array()函数

方式一:使用 array 关键字(推荐使用)

<?php
	$cars=array("porsche","BMW","Volvo");
	print_r($cars); 
	// Array ( [0] => porsche [1] => BMW [2] => Volvo )
    

方式二:可以使用中括号来包裹数据

<?php
	$cars=["porsche","BMW","Volvo"];
	print_r($cars); 
  
  // Array ( [0] => porsche [1] => BMW [2] => Volvo )

方式三:隐形定义数组:给变量增加一个中括号,系统自动变成数组

// 如果不提供下标也可以,系统自动生成(数字:从0开始)
$变量[] = 值1;

// 或者下面的
$变量[下标] = 值; 
<?php

$arr[]='hello1';
$arr[]='hello2';
$arr[20]='hello3';
$arr[]='hello4';
$arr[]='hello6';
$arr['name']='hello7';

var_dump($arr);

image

12.3.1 创建索引数组

// 方式一:自动分配索引(从0开始)
$cars=array("porsche","BMW","Volvo");

// 方式二:手动分配索引
$cars[0]="porsche";
$cars[1]="BMW";
$cars[2]="Volvo";

12.3.2 创建关联数组

// 方式一:
$age=array("Bill"=>"35","Steve"=>"37","Elon"=>"43");

// 方式二
$age['Bill']="63";
$age['Steve']="56";
$age['Elon']="47";

12.3.3 创建多维数组

简介和概述
  • 多维数组指的是包含一个或多个数组的数组(数组里面的元素又是数组)
  • PHP 能理解两、三、四或五级甚至更多级的多维数组
  • 数组的维度指示您需要选择元素的索引数
    • 对于二维数组,您需要两个索引来选取元素
    • 对于三维数组,您需要三个索引来选取元素
二维数组:数组中所有的元素都是一维数组

定义一个二维数组:

<?php
$info=array(
  array('name'=>'Tom','age'=>10),
  array('name'=>'Mary','age'=>20),
  array('name'=>'Jack','age'=>30)
);

var_dump($info);

image

多维数组

在第二维的数组元素中可以继续是数组,在PHP中没有维度限制(PHP本质并没有二维数组)

但是:不建议使用超过三维以上的数组,会增加访问的复杂度,降低访问效率

异形数组(不规则数组)

异形数组:数组中的元素不规则,有普通基本变量也有数组。

在实际开发中,并不常用,尽量让数组元素规则化(便于进行访问)

12.4 数组的遍历

数组遍历:普通数组数据的访问都通过数组元素的下标来实现访问,如果说数组中所有的数据都需要依次输出,就需要我们使用到一些简化的规则来实现自动获取下标以及输出数组元素

<?php
$info=array(
  array('name'=>'Tom','age'=>10),
  array('name'=>'Mary','age'=>20),
  array('name'=>'Jack','age'=>30)
);

var_dump($info[1]);

// 访问二维数组
echo $info[1]['name'];

image

12.4.1 foreach遍历

基本语法如下:

foreach($数组变量 as [$下标 =>] $值){
    //通过$下标访问元素的下标;通过$值访问元素的值
}

// 索引数组:可以直接访问,key就是数组的下标 (一维数组)
$info=array('Tom','Mary','Jack');
foreach($info as $key=>$val){
  echo $key .'=' .$val;  // 0=Tom    1=Mary   2=Jack
};

// 关联数组(一维数组)
$info=array('name'=>'Tom','age'=>10);
foreach($info as $key=>$val){
  echo $key . '===' . $val; // name===Tom   age===10
};

// 关联二维数组
$info=array(
  array('name'=>'Tom','age'=>10),
  array('name'=>'Mary','age'=>20),
  array('name'=>'Jack','age'=>30)
);

foreach($info as $key=>$val){
  echo 'name is '.$val['name']. 'and age is '. $val['age'] . '</br>'; 
};

// name is Tom and age is 10
// name is Mary and age is 20
// name is Jack and age is 30

7. PHP 日期和时间

7.1 date() 格式化日期

把时间戳格式化为更易读的日期和时间,会返回服务器的当前日期/时间

date(format,timestamp)
format	必需。规定时间戳的格式。
timestamp	可选。规定时间戳。默认是当前时间和日期。时间戳是一种字符序列,它表示具体事件发生的日期和事件

格式化日期:
d - 表示月里的某天(01-31)
m - 表示月(01-12)
Y - 表示年(四位数)
1 - 表示周里的某天

h - 带有首位零的 12 小时小时格式
i - 带有首位零的分钟
s - 带有首位零的秒(00 -59)
a - 小写的午前和午后(am 或 pm)

echo "当前时间是 " . date("Y-m-d h:i:s");

7.2 mktime() 返回日期的 Unix 时间戳

<?php
$d=mktime(9, 12, 31, 6, 10, 2015);
echo "创建日期是 " . date("Y-m-d h:i:sa", $d);

//返回结果:创建日期是 2015-06-10 09:12:31am
?>
    

7.3 strtotime() 用字符串来创建日期

strtotime() 函数用于把字符串转换为 Unix 时间

strtotime(time,now)

<?php
$d=strtotime("10:38pm April 15 2015");
echo "创建日期是 " . date("Y-m-d h:i:sa", $d);'

//返回结果:创建日期 2015-04-15 10:38:00pm
?>

7.4 一些比较灵活的日期

<?php
$d=strtotime("tomorrow");
echo date("Y-m-d h:i:sa", $d);  

$d=strtotime("next Saturday");
echo date("Y-m-d h:i:sa", $d);

$d=strtotime("+3 Months");
echo date("Y-m-d h:i:sa", $d);
?>

13. 文件包含

在一个PHP脚本中,去将另外一个文件(PHP)包含进来,去合作完成一件事情

13.1 简介和概述

13.1.1 文件包含的作用

  • 使用被包含文件中的内容,实现代码的共享(重用):向上包含

    向上包含:先包含文件,后使用文件中的内容
    image

  • 自己有东西可以给别的文件使用,实现代码的共享(重用):向下包含

    向下包含:先准备内容,然后包含另外的文件,在另外的文件中,使用当前的内容

image

最大的作用:分工协作,每个脚本做的事情不一样,因此可以使用协作方式,让多个脚本共同完成一件事情

13.1.2 文件包含的4种形式

Include:包含文件

Include_once:系统会自动判断文件包含过程中,是否已经包含过(一个文件最多被包含一次)

Require:与include相同

Require_once:以include_once相同

include ‘文件名字’;

include(‘文件名字’);	

13.1.3 文件加载的原理

PHP代码的执行流程
  • 1、 读取代码文件(PHP程序)
  • 2、 编译:将PHP代码转换成字节码(生成opcode)
  • 3、zendengine来解析opcode,按照字节码去进行逻辑运算
  • 4、 转换成对应的HTML代码
文件加载原理
  • 1、 在文件加载(include或者require)的时候,系统会自动的将被包含文件中的代码相当于嵌入到当前文件中
  • 2、 加载位置:在哪加载,对应的文件中的代码嵌入的位置就是对应的include位置
  • 3、 在PHP中被包含的文件是单独进行编译的

PHP文件在编译的过程中如果出现了语法错误,那么会失败(不会执行);但是如果被包含文件有错误的时候,系统会在执行到包含include这条语句的时候才会报错

13.2 includerequire的区别

本质都是包含文件,唯一的区别在于包含不到文件的时候,报错的形式不一样

Include的错误级别比较轻:不会阻止代码执行
image

Require要求较高:如果包含出错代码不再执行(require后面的代码)

image

includerequire语句
  • 通过 includerequire 语句,可以将 php 文件的内容插入另一个 'php' 文件(在服务器执行它之前)

  • 语法:includerequire语法是相同的

    include 'filename';
    require 'filename';
    
    
  • includerequire 的异同

    • include 与 require 有一个巨大的差异:如果用 include 语句引用某个文件并且 PHP 无法找到它,脚本会继续执行

    • 如果我们使用 require 语句完成相同的案例,echo 语句不会继续执行,因为在 require 语句返回严重错误之后脚本就会终止执行

    • 当文件被应用程序请求时,一般使用require

    • 当文件不是必需的,且应用程序在文件未找到时应该继续运行时,一般使用include

      require 会生成致命错误(E_COMPILE_ERROR)并停止脚本
      include 只生成警告(E_WARNING),并且脚本会继续
      

13.3 文件加载路径

文件在加载的时候需要指定文件路径才能保证PHP正确的找到对应的文件

13.3.1 绝对路径

1、从磁盘的根目录开始(本地绝对路径)

​ Windows:盘符C:/路径/PHP文件

​ Linux:/路径/PHP文件

2、 从网站根目录开始(网络绝对路径)

​ / 相对于网站主机名字对应的路径

13.3.2 相对路径

相对路径:从当前文件所在目录开始的路径

./  表示当前文件夹
../  上级目录(当前文件夹的上一层文件夹)

13.3.3 绝对路径和相对路径的区别

1、 绝对路径相对效率偏低,但是相对安全(路径不会出问题)

2、 相对路径相对效率高些,但是容易出错(相对路径会发生改变)

14. PHP 错误和异常处理

14.1 错误处理

错误处理:指的是系统(或者用户)在对某些代码进行执行的时候,发现有错误,就会通过错误处理的形式告知程序员

14.1.1 错误的分类

语法错误、运行时错误、逻辑错误

  • 语法错误:用户书写的代码不符合PHP的语法规范,语法错误会导致代码在编译过程中不通过,所以代码不会执行(Parse error)
  • 运行时错误:代码编译通过,但是代码在执行的过程中会出现一些条件不满足导致的错误(runtime error)
  • 逻辑错误:程序员在写代码的时候不够规范,出现了一些逻辑性的错误,导致代码正常执行,但是得不到想要的结果

14.1.2 错误代号

所有看到的错误代号在PHP中都被定义成了系统常量(可以直接使用)

1、系统错误:

E_PARSE:编译错误,代码不会执行

E_ERROR:fatal error,致命错误,会导致代码不能正确继续执行(出错的位置断掉)

E_WARNING:warning,警告错误,不会影响代码执行,但是可能得到意想不到的结果

E_NOTICE:notice,通知错误,不会影响代码执行

2、 用户错误:E_USER_ERROR, E_USER_WARNING, E_USER_NOTICE

用户在使用自定义错误触发的时候,会使用到的错误代号(系统不会用到)

3、 其他:E_ALL,代表着所有从错误(通常在进行错误控制的时候使用比较多),建议在开发过程中(开发环境)使用

所有以E开头的错误常量(代号)其实都是由一个字节存储,然后每一种错误占据一个对应的位,如果想进行一些错误的控制,可以使用位运算进行操作

排除通知级别notice:E_ALL & ~E_NOTICE

只要警告和通知:E_WARNING | E_NOTICE
image

14.1.3 错误触发

1、 程序运行时触发:系统自动根据错误发生后,对比对应的错误信息,输出给用户:主要针对代码的语法错误和运行时错误

2、 人为触发:知道某些逻辑可能会出错,从而使用对应的判断代码来触发响应的错误提示

trigger_error(错误提示),具体参数可以参考 trigger_error的使用
image

14.1.4 PHP错误显示设置(配置)

错误显示设置:哪些错误该显示,以及该如何显示

方法一:设置配置文件 php.ini

display_errors:是否显示错误

display_errors = on  显示错误
display_errors = off 不显示错误

error_reporting:显示什么级别的错误

error_reporting= E_ALL & ~E_DEPRECATED & ~E_STRICT
error_reporting = E_ALL & ~E_NOTICE & ~E_DEPRECATED & ~E_WARNING
error_reporting = E_ALL | E_STRICT
方法二:直接在运行的脚本中设置

在脚本中定义的配置项级别比配置文件高(通常在开发当中都会在代码中去进行控制和配置)

Error_reporting():设置对应的错误显示级别

Ini_set(‘配置文件中的配置项’,配置值)

Ini_set(‘error_reporting’,E_ALL);

Ini_set(‘display_errors’,1);

14.1.5 错误日志设置

在实际生产环境中,不会直接让错误赤裸裸的展示给用户:

1、 不友好

2、 不安全:错误会暴露网站很多信息(路径、文件名)

所以在生产环境中,一般不显示错误(错误也比较少),但是不可能避免会出现错误(测试的时候不会发现所有的问题),这个时候不希望看到,但是又希望捕捉到可以让后台程序员去修改:需要保存到日志文件中,需要在PHP配置文件中(php.ini)或者代码中 (ini_set) 设置对应 error_log配置项

  • 开启日志功能 log_errors = On

image

  • 指定日志的路径

image

14.1.6 自定义错误处理

在 PHP 中,默认的错误处理很简单:一条消息会被发送到浏览器,这条消息带有文件名、行号以及一条描述错误的消息

不同的错误处理方法:

  • 简单的 "die()" 语句
  • 自定义错误和错误触发器
  • 错误报告
1. 基本的错误处理:使用 die() 函数

下面的案例功能是:判断文件是否存在,如果存在就打开该文件;如果不存在,设置报错信息

<?php
// 在访问文件之前检测该文件是否存在:file_exists()函数
if (!file_exists("welcome.txt")) {
  die("File not found"); // 如果文件不存在,回向浏览器输出错误信息
} else {
  $file = fopen("welcome.txt", "r");
  
  /*
   * 如果不做文件是否存在的检测,直接 打开文件 那么浏览器会输出如下信息:
    Warning: fopen(welcome.txt) [function.fopen]: failed to open stream:
    No such file or directory in C:\webfolder\test.php on line 2
  */
}

2. 创建自定义错误处理器

PHP系统提供了一种用户处理错误的机制:用户自定义错误处理函数,然后将该函数增加操系统错误处理的句柄中,然后系统会在碰到错误之后,使用用户定义的错误函数

1、 如何将用户自定义的函数放到系统中?set_error_handler()

2、创建自定义错误处理函数

error_function(error_level,error_message,error_file,error_line,error_context)

image

3、 注册自定义函数:修改错误处理机制

set_error_handler('customError');

案例如下:

<?php
// 自定义错误处理
// 1. 自定义错误处理函数
function my_error_func($error_level, $error_message, $error_file, $error_line, $error_context)
{
  if (!(error_reporting() & $error_level)) {
    return;
    // error_reporting()没有参数时,获取所有的错误处理级别
  };
  
  // 不同的错误类型的处理
  switch ($error_level) {
    case E_ERROR:
    case E_USER_ERROR:
      echo 'fatal error in file ' . $error_file . ' on line ' . $error_line . '</br>';
      echo 'error info:' . $error_message;
      break;
    case E_WARNING:
    case E_USER_WARNING:
      echo 'warning in file ' . $error_file . ' on line ' . $error_line . '</br>';
      echo 'error info:' . $error_message;
      break;
    case E_NOTICE:
    case E_USER_NOTICE:
      echo 'Notice in file ' . $error_file . ' on line ' . $error_line . '</br>';
      echo 'error info:' . $error_message;
      break;
  };
  return true;
}
echo $name; // 会提示报错,但是是系统原本的体系报的错误
// 设置 自定义的错误处理机制
set_error_handler('my_error_func');
echo $name; // 修改机制后,使用自定义的错误机制报错

image

14.2 异常处理

异常(Exception)用于在指定的错误发生时改变脚本的正常流程

14.2.1 简介

  • PHP 5 提供了一种新的面向对象的错误处理方法

  • 异常处理用于在指定的错误(异常)情况发生时改变脚本的正常流程。这种情况称为异常

  • 当异常被触发时,通常会发生:

    • 当前代码状态被保存
    • 代码执行被切换到预定义的异常处理器函数
    • 根据情况,处理器也许会从保存的代码状态重新开始执行代码,终止脚本执行,或从代码中另外的位置继续执行脚本
  • 不同的错误处理方法:

    • 异常的基本使用
    • 创建自定义的异常处理器
    • 多个异常
    • 重新抛出异常
    • 设置顶层异常处理器
  • 待续。。。

14.2.2 异常的基本使用

异常的工作流程:

  • 当异常被抛出时,其后的代码不会继续执行,PHP 会尝试查找匹配的 "catch" 代码块。
  • 如果异常没有被捕获,而且又没用使用 set_exception_handler() 作相应的处理的话,那么将发生一个严重的错误(致命错误),并且输出 "Uncaught Exception" (未捕获异常)的错误消息
/*
代码尝试抛出一个异常,同时不去捕获它,那么就会抛出类似这样的一个错误:
Fatal error: Uncaught exception 'Exception' 
with message 'Value must be 1 or below' in C:\webfolder\test.php:6 
Stack trace: #0 C:\webfolder\test.php(12): 
checkNum(28) #1 {main} thrown in C:\webfolder\test.php on line 6
*/
<?php
function checkNum($number){
     if($number>1){
        throw new Exception("Value must be 1 or below");
      }
      return true;
    }

//trigger exception
checkNum(2);
    
  • try, throw 和 catch捕获异常
    • Try - 使用异常的函数应该位于 "try" 代码块内。如果没有触发异常,则代码将照常继续执行。但是如果异常被触发,会抛出一个异常
    • Throw - 这里规定如何触发异常。每一个 "throw" 必须对应至少一个 "catch"
    • Catch - "catch" 代码块会捕获异常,并创建一个包含异常信息的对象
<?php
// 创建可抛出一个异常的函数
function checkNum($number){
     if($number>1){
        throw new Exception("Value must be 1 or below");
      }
      return true;
 }

// 在 "try" 代码块中触发异常
try
 {
     checkNum(2);
     //If the exception is thrown, this text will not be shown
     echo 'If you see this, the number is 1 or below';
 }
// 捕获异常
catch(Exception $e)
 {
   echo 'Message: ' .$e->getMessage();
 }
 
 // 返回结果: Message: Value must be 1 or below 

14.2.3 创建一个自定义的 Exception 类

  • 我们简单地创建了一个专门的类,当 PHP 中发生异常时,可调用其函数。
  • 该类必须是 exception 类的一个扩展。
<?php
class customException extends Exception
 {
 public function errorMessage()
  {
  //error message
  $errorMsg = 'Error on line '.$this->getLine().' in '.$this->getFile()
  .': <b>'.$this->getMessage().'</b> is not a valid E-Mail address';
  return $errorMsg;
  }
 }

$email = "someone@example...com";

try
 {
 //check if 
 if(filter_var($email, FILTER_VALIDATE_EMAIL) === FALSE)
  {
  //throw exception if email is not valid
  throw new customException($email);
  }
 }

catch (customException $e)
 {
 //display custom message
 echo $e->errorMessage();
 }
?>

image

14.2.4 多个异常

  • 可以为一段脚本使用多个异常,来检测多种情况
  • 可以使用多个 if..else 代码块,或一个 switch 代码块,或者嵌套多个异常。这些异常能够使用不同的 exception 类,并返回不同的错误消息:
<?php
class customException extends Exception
{
public function errorMessage()
{
//error message
$errorMsg = 'Error on line '.$this->getLine().' in '.$this->getFile()
.': <b>'.$this->getMessage().'</b> is not a valid E-Mail address';
return $errorMsg;
}
}

$email = "someone@example.com";

try
 {
 //check if 
 if(filter_var($email, FILTER_VALIDATE_EMAIL) === FALSE)
  {
  //throw exception if email is not valid
  throw new customException($email);
  }
 //check for "example" in mail address
 if(strpos($email, "example") !== FALSE)
  {
  throw new Exception("$email is an example e-mail");
  }
 }

catch (customException $e)
 {
 echo $e->errorMessage();
 }

catch(Exception $e)
 {
 echo $e->getMessage();
 }
?>

image

14.2.5 重新抛出异常

  • 有时,当异常被抛出时,也希望以不同于标准的方式对它进行处理。可以在一个 "catch" 代码块中再次抛出异常。
  • 脚本应该对用户隐藏系统错误。对程序员来说,系统错误也许很重要,但是用户对它们并不感兴趣。为了让用户更容易使用,您可以再次抛出带有对用户比较友好的消息的异常:
<?php
class customException extends Exception
 {
 public function errorMessage()
  {
  //error message
  $errorMsg = $this->getMessage().' is not a valid E-Mail address.';
  return $errorMsg;
  }
 }

$email = "someone@example.com";

try
 {
 try
  {
  //check for "example" in mail address
  if(strpos($email, "example") !== FALSE)
   {
   //throw exception if email is not valid
   throw new Exception($email);
   }
  }
 catch(Exception $e)
  {
  //re-throw exception
  throw new customException($email);
  }
 }

catch (customException $e)
 {
 //display custom message
 echo $e->errorMessage();
 }
?>

image

15. PHP 过滤器

PHP 过滤器用于验证和过滤来自非安全来源的数据,比如用户的输入

15.1 简介和概述

15.1.1 什么是 PHP 过滤器?

  • PHP 过滤器用于验证和过滤来自非安全来源的数据。
  • 验证和过滤 用户输入 或自定义数据 是任何 Web 应用程序的重要组成部分。
  • 设计 PHP 的过滤器扩展的目的是 使数据过滤更轻松快捷。

15.1.2 什么是外部数据?

  • 来自表单的输入数据
  • Cookies
  • 服务器变量
  • 数据库查询结果

15.1.3 为什么使用过滤器?

  • 几乎所有 web 应用程序都依赖外部的输入。
  • 这些数据通常来自用户或其他应用程序(比如 web 服务)。通过使用过滤器,您能够确保应有程序获得正确的输入类型。

15.2 函数和过滤器

如需过滤变量,请使用下面的过滤器函数之一:

filter_has_var() - 检查是否存在指定输入类型的变量
filter_id() - 返回指定过滤器的ID号
filter_var() - 通过一个指定的过滤器来  过滤单一的变量
filter_var_array() - 通过相同的或不同的过滤器来  过滤多个变量
filter_input() - 获取一个输入变量,并对它进行过滤
filter_input_array() - 获取多个输入变量,并通过相同的或不同的过滤器对它们进行过滤
filter_list() - 返回包含所有得到支持的过滤器的一个数组

15.3 Validating 和 Sanitizing

有两种过滤器:Validating 过滤器和Sanitizing 过滤器

15.3.1 Validating 过滤器

  • 用于验证用户输入
  • 严格的格式规则(比如 URL 或 E-Mail 验证)
  • 如果成功则返回预期的类型,如果失败则返回 FALSE

15.3.2 Sanitizing 过滤器

  • 用于允许或禁止字符串中指定的字符
  • 无数据格式规则
  • 始终返回字符串

15.4 选项和标志

  • 选项和标志用于向指定的过滤器添加额外的过滤选项。
  • 不同的过滤器有不同的选项和标志。
 /*
 使用filter_var() 和 "min_range" 以及 "max_range" 选项验证了一个整数
 选项必须放入一个名为 "options" 的相关数组中。
 如果使用标志,则不需在数组内
 */
 
<?php
$var=300;

$int_options = array(
"options"=>array
 (
 "min_range"=>0,
 "max_range"=>256
 )
);

if(!filter_var($var, FILTER_VALIDATE_INT, $int_options))
 {
 echo("Integer is not valid");
 }
else
 {
 echo("Integer is valid");
 }
?>

15.5 使用 Filter Callback

  • 通过使用 FILTER_CALLBACK 过滤器,可以调用自定义的函数,把它作为一个过滤器来使用。这样,我们就拥有了数据过滤的完全控制权。
  • 您可以创建自己的自定义函数,也可以使用已有的 PHP 函数
  • 规定准备用到过滤器函数的方法,与规定选项的方法相同
<?php
//把 _ 转换为空格
function convertSpace($string)
{
return str_replace("_", " ", $string);
}

$string = "Peter_is_a_great_guy!";

echo filter_var($string, FILTER_CALLBACK, array("options"=>"convertSpace"));
?>

16. PHP 命名空间

16.1 简介和概述

  • 从广义上来说,命名空间是一种封装事物的方法
  • PHP 命名空间提供了一种将相关的类、函数和常量组合到一起的途径
  • PHP 命名空间可以解决以下两类问题
    • 用户编写的代码与PHP内部的类/函数/常量或第三方类/函数/常量之间的名字冲突
    • 为很长的标识符名称(通常是为了缓解第一类问题而定义的)创建一个别名(或简短)的名称,提高源代码的可读性

16.2 定义命名空间

  • 默认情况下,所有常量、类和函数名都放在全局空间下,就和PHP支持命名空间之前一样
  • 命名空间通过关键字 namespace 来声明
  • 如果一个文件中包含命名空间,它必须在其它所有代码之前声明。语法格式如下:
< ?php  
// 定义代码在 'MyProject' 命名空间中  
namespace MyProject;  
// ... 代码 ...
?>


// 也可以在同一个文件中定义不同的命名空间代码
< ?php  
namespace MyProject1;  
// MyProject1 命名空间中的PHP代码  
 
namespace MyProject2;  
// MyProject2 命名空间中的PHP代码    
 
// 另一种语法(推荐的使用方法)
namespace MyProject3 {  
 // MyProject3 命名空间中的PHP代码    
}  

?>

  • 将全局的非命名空间中的代码与命名空间中的代码组合在一起,只能使用大括号形式的语法。全局代码必须用一个不带名称的 namespace 语句加上大括号括起来
<?php
namespace MyProject {
  const CONNECT_OK = 1;
  class Connection { /* ... */ }
  function connect() { /* ... */  }
}

namespace { // 全局代码
  session_start();
  $a = MyProject\connect();
  echo MyProject\Connection::start();
}
?>
    
  • 在声明命名空间之前唯一合法的代码是用于定义源文件编码方式的 declare 语句。所有非 PHP 代码包括空白符都不能出现在命名空间的声明之前
<?php
declare(encoding='UTF-8'); 

// 定义多个命名空间和不包含在命名空间中的代码
namespace MyProject {
  const CONNECT_OK = 1;
  class Connection { /* ... */ }
  function connect() { /* ... */  }
}

namespace { // 全局代码
  session_start();
  $a = MyProject\connect();
  echo MyProject\Connection::start();
}
?>

16.3 子命名空间

与目录和文件的关系很象,PHP 命名空间也允许指定层次化的命名空间的名称

因此,命名空间的名字可以使用分层次的方式定义:

<?php
namespace MyProject\Sub\Level;  // 声明分层次的单个命名空间

const CONNECT_OK = 1;
class Connection { /* ... */ }
function Connect() { /* ... */  }

/*
    创建了常量 MyProject\Sub\Level\CONNECT_OK,类 MyProject\Sub\Level\Connection 和函数    MyProject\Sub\Level\Connect
*/
?>

16.4 命名空间使用

image

  • 注意访问任意全局类、函数或常量,都可以使用完全限定名称,例如 \strlen() 或 \Exception 或 \INI_ALL
  • 在命名空间内部访问全局类、函数和常量
<?php
namespace Foo;

function strlen() {}
const INI_ALL = 3;
class Exception {}

$a = \strlen('hi'); // 调用全局函数strlen
$b = \INI_ALL; // 访问全局常量 INI_ALL
$c = new \Exception('error'); // 实例化全局类 Exception
?>

16.5 namespace关键字和__NAMESPACE__常量

  • PHP支持两种抽象的访问当前命名空间内部元素的方法,NAMESPACE 魔术常量和 namespace 关键字。
  • 常量 NAMESPACE 的值是包含当前命名空间名称的字符串。在全局的,不包括在任何命名空间中的代码,它包含一个空的字符串。
  • NAMESPACE 示例, 在命名空间中的代码
<?php
namespace MyProject;

echo '"', __NAMESPACE__, '"'; // 输出 "MyProject"
?>
  • NAMESPACE_ 示例,全局代码
<?php

echo '"', __NAMESPACE__, '"'; // 输出 ""
?>

17. PHP JSON

常见的JSON函数

函数 描述
json_encode 对变量进行JSON编码
json_decode 对JSON格式的字符串进行编码,转换为PHP变量
json_last_error 返回最后发送的错误

17.1 json_encode

PHP json_encode() 用于对变量进行 JSON 编码,该函数如果执行成功返回 JSON 数据,否则返回 FALSE 。

<?php    
$arr = array('a' => 1, 'b' => 2, 'c' => 3, 'd' => 4, 'e' => 5);
echo json_encode($arr);

输出结果: 
{"a":1,"b":2,"c":3,"d":4,"e":5}

17.2 json_decode

PHP json_decode() 函数用于对 JSON 格式的字符串进行解码,并转换为 PHP 变量

<?php    
$json = '{"a":1,"b":2,"c":3,"d":4,"e":5}';     
var_dump(json_decode($json));   
var_dump(json_decode($json, true)); ?>

输出结果:
object(stdClass)#1 (5) {
    ["a"] => int(1)
    ["b"] => int(2)
    ["c"] => int(3)
    ["d"] => int(4)
    ["e"] => int(5)
}

array(5) {
    ["a"] => int(1)
    ["b"] => int(2)
    ["c"] => int(3)
    ["d"] => int(4)
    ["e"] => int(5)
}

18. PHP之条件控制语句

条件语句:

  • 条件语句用于基于不同条件执行不同的动作
  • if 语句 - 如果指定条件为真,则执行代码
  • if...else 语句 - 如果条件为 true,则执行代码;如果条件为 false,则执行另一端代码
  • if...elseif....else 语句 - 根据两个以上的条件执行不同的代码块
  • switch 语句 - 选择多个代码块之一来执行

18.1 ifif elese 语句

1、 if 语句用于在指定条件为 true 时执行代码

if (条件) {
  当条件为 true 时执行的代码;
}

2、 if....else 语句在条件为 true 时执行代码,在条件为 false 时执行另一段代码

if (条件) {
  条件为 true 时执行的代码;
} else {
  条件为 false 时执行的代码;
}

3、 if....elseif...else 语句来根据两个以上的条件执行不同的代码

if (条件) {
  条件为 true 时执行的代码;
} elseif (condition) {
  条件为 true 时执行的代码;
} else {
  条件为 false 时执行的代码;
}

18.2 switch 语句

  • switch 语句用于基于不同条件执行不同动作
  • 如果您希望有选择地执行若干代码块之一,请使用 Switch 语句
  • 使用 Switch 语句可以避免冗长的 if..elseif..else 代码块
switch (expression)
{
case label1:
  expression = label1 时执行的代码 ;
  break;  
case label2:
  expression = label2 时执行的代码 ;
  break;
default:
  表达式的值不等于 label1 及 label2 时执行的代码;
}
  • 工作原理:

    • 对表达式(通常是变量)进行一次计算
    1. 把表达式的值与结构中 case 的值进行比较
    2. 如果存在匹配,则执行与 case 关联的代码
    3. 代码执行后,break 语句阻止代码跳入下一个 case 中继续执行
    4. 如果没有 case 为真,则使用 default 语句

18.3 while 循环

  • while 循环在指定条件为 true 时执行代码块
  • 只要指定的条件为真,while 循环就会执行代码块
while (条件为真) {
  要执行的代码;
}

18.4 do...while 循环

  • do...while 循环首先会执行一次代码块,然后检查条件,如果指定条件为真,则重复循环,一直到条件为假时,停止循环
  • do while 循环只在执行循环内的语句之后才对条件进行测试。这意味着 do while 循环至少会执行一次语句,即使条件测试在第一次就失败了
do {
  要执行的代码;
} while (条件为真);

18.5 for 循环

for 循环执行代码块指定的次数

for (init counter; test counter; increment counter) {
  code to be executed;
}

init counter:初始化循环计数器的值
test counter:: 评估每个循环迭代。如果值为 TRUE,继续循环。如果它的值为 FALSE,循环结束。
increment counter:增加循环计数器的值

例如:
for ($x=0; $x<=10; $x++) {
  echo "数字是:$x ";
} 

18.6 foreach 循环--只适用 数组

foreach 循环只适用于数组,并用于遍历数组中的每个键/值对

foreach ($array as $value) {
  code to be executed;
}
或者
foreach ($array as $index=>$value) {
  code to be executed;
}