PHP基础巩固

想要潜心深入一门语言,就得先打好基础…
千里之行,始于足下~

该篇文章,每天我都会拿出最起码半小时的时间来更新,目录结构和很多一部分内容参考:https://www.php.net/manual/zh/index.php ,很多补充和我自己的理解,我会以自问自答的方式给出,我觉得这样的印象会比较深刻,也希望对看这篇文章的新手可以更友好.🤤

惯例: php是世界上最好的语言

简介

php是什么?

php全称 “Hypertext Preprocessor”,即超文本与预处理器. php可以嵌入到html网页中,非常适合进行web开发.

1
2
3
4
5
6
7
8
9
10
<html>
<head>
<title>Example</title>
</head>
<body>
<?php
echo "Hi, I'm a PHP script!";
?>
</body>
</html>

php可以做什么?

PHP 能做任何事。PHP 主要是用于服务端的脚本程序,因此可以用 PHP 来完成任何其它的 CGI 程序能够完成的工作,例如收集表单数据,生成动态网页,或者发送/接收 Cookies。但 PHP 的功能远不局限于此。

公共网关接口(Common Gateway Interface,CGI)是Web 服务器运行时外部程序的规范,按CGI 编写的程序可以扩展服务器功能。CGI 应用程序能与浏览器进行交互,还可通过数据API与数据库服务器等外部数据源进行通信,从数据库服务器中获取数据。格式化为HTML文档后,发送给浏览器,也可以将从浏览器获得的数据放到数据库中。几乎所有服务器都支持CGI,可用任何语言编写CGI,包括流行的C、C ++、Java、VB 和Delphi 等。CGI分为标准CGI和间接CGI两种。标准CGI使用命令行参数或环境变量表示服务器的详细请求,服务器与浏览器通信采用标准输入输出方式。间接CGI又称缓冲CGI,在CGI程序和CGI接口之间插入一个缓冲程序,缓冲程序与CGI接口间用标准输入输出进行通信(来自百度百科)

安装php环境

  1. mac自带php环境
  2. windows本地可以使用phpstudy(可自行百度)
  3. 推荐docker部署

基本语法

php标记

当解析一个文件时,PHP 会寻找起始和结束标记,也就是 ,这告诉 PHP 开始和停止解析二者之间的代码。此种解析方式使得 PHP 可以被嵌入到各种不同的文档中去,而任何起始和结束标记之外的部分都会被 PHP 解析器忽略。

如果文件内容是纯 PHP 代码,最好在文件末尾删除 PHP 结束标记。这可以避免在 PHP 结束标记之后万一意外加入了空格或者换行符,会导致 PHP 开始输出这些空白,而脚本中此时并无输出的意图。
such as:

1
2
3
4
<?php
echo "hhhh";
?>dididi
// result: hhhhdididi

分隔符

同 C 或 Perl 一样,PHP 需要在每个语句后用分号结束指令。一段 PHP 代码中的结束标记隐含表示了一个分号;在一个 PHP 代码段中的最后一行可以不用分号结束。如果后面还有新行,则代码段的结束标记包含了行结束。

1
2
3
4
5
6
7
<?php
echo "This is a test";
?>

<?php echo "This is a test" ?>

<?php echo 'We omitted the last closing tag';

类型

简介

基础类型
  • boolean 布尔值
  • integer 整数
  • string 字符串
  • float 浮点数
    复合类型
  • array
  • object
  • callable

    这里callable类型是什么意思呢?

特殊类型
  • resource
  • NULL
    伪类型
  • mixed
  • number
  • callback
  • array|object
  • void

类型判断函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php
$a_bool = TRUE; // 布尔值 boolean
$a_str = "foo"; // 字符串 string
$a_str2 = 'foo'; // 字符串 string
$an_int = 12; // 整型 integer

// 判断变量类型不建议使用gettype函数
echo gettype($a_bool); // 输出: boolean
echo gettype($a_str); // 输出: string

// 如果是整型,就加上 4
if (is_int($an_int)) {
$an_int += 4;
}

// 如果 $bool 是字符串,就打印出来
// (啥也没打印出来)
if (is_string($a_bool)) {
echo "String: $a_bool";
}
?>

boolean(布尔类型)

要指定一个布尔值推荐使用大写的常量TRUE和FALSE

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
// == 是一个操作符,它检测两个变量是否相等,并返回一个布尔值
if ($action == "show_version") {
echo "The version is 1.23";
}

// 这样做是不必要的...
if ($show_separators == TRUE) {
echo "<hr>\n";
}

// ...因为可以使用下面这种简单的方式:
if ($show_separators) {
echo "<hr>\n";
}
?>
类型转换

当发生转换时,以下值会被认为是FALSE

  • FALSE
  • 0
  • 0.0
  • ‘’
  • ‘0’
  • []
  • NULL
  • 从空标记生成的 SimpleXML 对象
1
2
3
<?php
//true
var_dump((bool)'false' );

上面列举的这些拿empty()去判断都会返回true,php笔试题常考,往周知~(我是不会承认自己曾经笔试做错过的😡)

integer(整形)

1
2
3
4
5
6
7
<?php
$a = 1234; // 十进制数
$a = -123; // 负数
$a = 0123; // 八进制数 (等于十进制 83)
$a = 0x1A; // 十六进制数 (等于十进制 26)
$a = 0b11111111; // 二进制数字 (等于十进制 255)
?>

float(浮点数)

略~,int和float这块我有点怀疑人生,有必要重新看看计算机组成这本书了…,待我看懂了再补充上吧.

string(字符串)

单引号

要表达一个单引号自身的话,需要在前面加上反斜线\来转义,要表达一个反斜线自身,则用两个反斜线(\)。其它任何方式的反斜线都会被当成反斜线本身:也就是说如果想使用其它转义序列例如 \r 或者 \n,并不代表任何特殊含义,就单纯是这两个字符本身。

1
2
3
4
5
<?php
echo '\''; // '
echo '\\'; // \
echo '\n\r'; // \n\r
?>
双引号

如果字符串是包围在双引号(”)中, PHP 将对一些特殊的字符进行解析:

  • \n 换行
  • \r 回车
  • \t 水平制表符(ASCII 字符集中的 HT 或 0x09 (9))
  • \v 垂直制表符(ASCII 字符集中的 VT 或 0x0B (11))(自 PHP 5.2.5 起)
  • \e Escape
  • \ 反斜线
  • $ 美元标记
  • " 双引号
  • [0-7]{1,3} 符合该正则表达式序列的是一个以八进制方式来表达的字符
  • \x[0-9A-Fa-f]{1,2} 符合该正则表达式序列的是一个以十六进制方式来表达的字符
1
2
3
4
5
6
7
<?php
$var = 100;
echo "\${$var}"; //$100
echo "\$$$var"; //$100
echo "i have \{$var}.\n"; //i have \{100}.
echo "i have \$$var.\n"; //i have $100.
?>

和单引号字符串一样,转义任何其它字符都会导致反斜线被显示出来。PHP 5.1.1 以前,{$var} 中的反斜线还不会被显示出来。

用双引号定义的字符串最重要的特征是变量会被解析

变量

基础

1
2
3
4
5
6
7
8
9
<?php
$var = 'Bob';
$Var = 'Joe';
echo "$var, $Var"; // 输出 "Bob, Joe"

$4site = 'not yet'; // 非法变量名;以数字开头
$_4site = 'not yet'; // 合法变量名;以下划线开头
$i站点is = 'mansikka'; // 合法变量名;可以用中文
?>

哈哈哈哈牛皮,居然还支持中文

变量默认总是传值赋值。那也就是说,当将一个表达式的值赋予一个变量时,整个原始表达式的值被赋值到目标变量。这意味着,例如,当一个变量的值赋予另外一个变量时,改变其中一个变量的值,将不会影响到另外一个变量。有关这种类型的赋值操作,请参阅表达式一章。

PHP 也提供了另外一种方式给变量赋值:引用赋值。这意味着新的变量简单的引用(换言之,“成为其别名” 或者 “指向”)了原始变量。改动新的变量将影响到原始变量,反之亦然。

1
2
3
4
5
6
7
<?php
$foo = 'Bob'; // 将 'Bob' 赋给 $foo
$bar = &$foo; // 通过 $bar 引用 $foo
$bar = "My name is $bar"; // 修改 $bar 变量
echo $bar;
echo $foo; // $foo 的值也被修改
?>

提一嘴… php这好像有点儿戏啊,难道没有指针类型么..

有一点重要事项必须指出,那就是只有有名字的变量才可以引用赋值。

1
2
3
4
5
6
7
8
9
10
11
12
<?php
$foo = 25;
$bar = &$foo; // 合法的赋值
$bar = &(24 * 7); // 非法; 引用没有名字的表达式

function test()
{
return 25;
}

$bar = &test(); // 非法
?>

变量范围

变量的范围即它定义的上下文背景(也就是它的生效范围)。大部分的 PHP 变量只有一个单独的范围。这个单独的范围跨度同样包含了 include 和 require 引入的文件。例如:

1
2
3
4
<?php
$a = 1;
include 'b.inc';
?>
1
2
3
4
5
6
7
8
9
10
<?php
$a = 1; /* global scope */

function Test()
{
echo $a; /* reference to local scope variable */
}

Test();
?>

这个脚本不会有任何输出,因为 echo 语句引用了一个局部版本的变量 $a,而且在这个范围内,它并没有被赋值。你可能注意到 PHP 的全局变量和 C 语言有一点点不同,在 C 语言中,全局变量在函数中自动生效,除非被局部变量覆盖。这可能引起一些问题,有些人可能不小心就改变了一个全局变量。PHP 中全局变量在函数中使用时必须声明为 global

global 关键字

Example #1 使用 global

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
$a = 1;
$b = 2;

function Sum()
{
global $a, $b;
$b = $a + $b;
}

Sum();
echo $b; // 输出3
?>

以上脚本的输出将是“3”。在函数中声明了全局变量 $a 和 $b 之后,对任一变量的所有引用都会指向其全局版本。对于一个函数能够声明的全局变量的最大个数,PHP 没有限制。

Example #2 使用 $GLOBALS 替代 global

1
2
3
4
5
6
7
8
9
10
11
12
<?php
$a = 1;
$b = 2;

function Sum()
{
$GLOBALS['b'] = $GLOBALS['a'] + $GLOBALS['b'];
}

Sum();
echo $b;
?>

$GLOBALS 是一个关联数组,每一个变量为一个元素,键名对应变量名,值对应变量的内容。
$GLOBALS 之所以在全局范围内存在,是因为 $GLOBALS 是一个超全局变量

静态变量

变量范围的另一个重要特性是静态变量(static variable)。静态变量仅在局部函数域中存在,但当程序执行离开此作用域时,其值并不丢失。看看下面的例子:

Example #4 演示需要静态变量的例子

1
2
3
4
5
6
7
8
9
<?php
function Test()
{
$a = 0;
echo $a;
$a++;
}
?>
// 重复调用Test()一直为0

本函数没什么用处,因为每次调用时都会将 $a 的值设为 0 并输出 0。将变量加一的 $a++ 没有作用,因为一旦退出本函数则变量 $a 就不存在了。要写一个不会丢失本次计数值的计数函数,要将变量 $a 定义为静态的

1
2
3
4
5
6
7
8
9
<?php
function test()
{
static $a = 0;
echo $a;
$a++;
}
?>
// 重复调用Test()一直为a数值重复+1

静态变量也提供了一种处理递归函数的方法。递归函数是一种调用自己的函数。写递归函数时要小心,因为可能会无穷递归下去。必须确保有充分的方法来中止递归。以下这个简单的函数递归计数到 10,使用静态变量 $count 来判断何时停止:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
function test()
{
static $count = 0;

$count++;
echo $count;
if ($count < 10) {
test();
}
$count--;
echo $count;
}
test();
//输出的序列?
123456789109876543210
?>

声明中用表达式的结果对其赋值会导致解析错误。

1
2
3
4
5
6
7
8
9
10
<?php
function foo(){
static $int = 0; // correct
static $int = 1+2; // wrong (as it is an expression)
static $int = sqrt(121); // wrong (as it is an expression too)

$int++;
echo $int;
}
?>
全局和静态变量的引用

在一个函数域内部用 global 语句导入的一个真正的全局变量实际上是建立了一个到全局变量的引用。这有可能导致预料之外的行为

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
function test_global_ref() {
global $obj;
$obj = &new stdclass;
}

function test_global_noref() {
global $obj;
$obj = new stdclass;
}

test_global_ref();
var_dump($obj);
test_global_noref();
var_dump($obj);
?>

以上例程会输出:

1
2
3
NULL
object(stdClass)(0) {
}

类似的行为也适用于 static 语句。引用并不是静态地存储的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<?php
function &get_instance_ref() {
static $obj;

echo 'Static object: ';
var_dump($obj);
if (!isset($obj)) {
// 将一个引用赋值给静态变量
$obj = &new stdclass;
}
$obj->property++;
return $obj;
}

function &get_instance_noref() {
static $obj;

echo 'Static object: ';
var_dump($obj);
if (!isset($obj)) {
// 将一个对象赋值给静态变量
$obj = new stdclass;
}
$obj->property++;
return $obj;
}

$obj1 = get_instance_ref();
$still_obj1 = get_instance_ref();
echo "\n";
$obj2 = get_instance_noref();
$still_obj2 = get_instance_noref();
?>

以上例程会输出:

1
2
3
4
5
6
7
8
Static object: NULL
Static object: NULL

Static object: NULL
Static object: object(stdClass)(1) {
["property"]=>
int(1)
}

常量

表达式

运算符

流程控制

函数

类与对象

命名空间

Errors

异常处理

生成器

引用的解释

预定义变量

预定义异常

预定义接口

上下文(context)选项和参数

支持的协议和封装的协议

补充

文章作者: Luis
文章链接: https://warrest.github.io/2020/04/08/PHP%E5%9F%BA%E7%A1%80%E5%A4%8D%E4%B9%A0/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Luis's Blog