php
一. php项目启动
*注意!!! 本章只针对如果从零开始启动一个PHP项目, 在更多的情况下, 都是使用类似于 PHPstudy 或者wamp 的站点搭建工具一键生成PHP项目 *
1.1 Apache的启动
下载Apache ( 我选用的是: httpd-2.4.43-o111f-x64-vc15 版本 )
将Apache解压至预先设置好路径上 ( 我的是直接安装在D盘的根目录下 )
将: Apache24\bin 配置进环境变量中
cmd输入httpd -t 检测是否可以正常运行
提示报错则按报错信息修改相关内容
当 httpd -t 提示 Syntax OK时 , 则表示可以正常使用Apache服务器
cmd 内 输入 httpd , 即可启动Apache服务
此时可以访问 localhost:80 来查看Apache服务的主页 ( Apache服务器默认开启的是80端口 )
一般而言, 在没有过多的配置下, Apache网页显示内容主要是存放在 Apache24\htdocs 内, 默认显示目录的index.html文件
1.2 PHP的安装
PHP 作为一种解释型语言, 不能像js一样直接被浏览器解释执行 (其实浏览器底层也是借用V8引擎才能解释执行), 因此需要 PHP 解释器解释执行
- 下载php, 一般选择php7之后的版本, php5的版本已经算过时了 ( 我选用的是php-7.4.4-Win32-vc15-x64版本 )
- 将下载好的php解压至预先设置好的路径( 自定义路径 )
- 找到 php.ini-delevopment 文件将其命名为: php.ini
- 找到extension=mysql, 将其注释解开 ( 开启php的mysql资源 )
1.3 php 和 Apache的关联
要想在浏览器渲染出 php 执行的内容, 需要 web 服务器的支持, 不一定是用Apache服务器, 也可以使用Nginx服务器, 这里以常用的Apache服务器为例子
打开Apache的 httpd.conf文件
加载php解释器
增加可执行文件的后缀名,( 让Apache可以执行php文件 )
设置php.ini 文件所在的路劲, ( 让Apache服务器可以与PHP关联起来 )
1
2
3
4
5
6# 加载php解释器
LoadModule php7_module "F:\PHP\php7apache2_4.dll"
# 增加可执行文件的后缀名
AddType application/x-httpd-php .php .html .htm
# 设置php.ini文件所在路径
PHPIniDir "F:\PHP"
1.4 Apache的端口映射 (多站点布置)
因为一台服务器 ( 或者说好一点的服务器 ) 价格是很贵的, 一般来说, 如果一台服务器只搭建一台网站, 是很不经济的方案, 因此需要配置对个站点 ( 网站 );
1.4.1 基于IP的虚拟机主机
一般来说, 一台电脑只会配置一个网卡, 因此一般来说一台电脑只有一个IP地址
但是, 有的服务器可以配置多个网卡槽, 可以拥有多个IP地址, 因为并不是很常见因此在这里不做过多的介绍
1.4.2 基于域名的虚拟机主机
一台电脑只有一个IP, 但是IP下可以制作多个网站, 需要的是给不同的网站起不同的名字
修改本机host 文件 (host文件的修改以及路径详见百度, 当然在学习的过程中, 这个也可以跳过)
如: 我想在我本机中运行 www.wangermazi.com, www.huangwei.com 这两个域名
(即将多个域名都映射到本机地址上)
1
2
3127.0.0.1 localhost
127.0.0.1 www.wangermazi.com
127.0.0.1 www.huangwei.com打开Apache的安装目录, 找到Apache服务器的配置文件, httpd.conf , 去除下面两行代码的 # 号注释
1
2
3
4# 开启Apache的虚拟主机功能
LoadModule vhost_alias_module modules/mod_vhost_alias.so
# 从conf/extra/httpd-vhosts.conf 这个文件中导入虚拟主机配置
Include conf/extra/httpd-vhosts.conf打开conf/extra/httpd-vhosts.conf 这个路劲的文件, 把默认设置
注意, 这个配置文件实际上是一个XML配置文件
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
34
35
36
37
38
39
40<!-- 配置虚拟主机, 监听的端口 -->
<VirtualHost *:80>
#
ServerAdmin webmaster@dummy-host.localhost
# 设置监听网页的根目录文件
DocumentRoot "/www/docs/dummy-host.localhost"
ServerName dummy-host.localhost
ServerAlias http://www.dummy-host.localhost/
ErrorLog "logs/dummy-host.localhost-error_log"
CustomLog "logs/dummy-host.localhost-access_log common"
</VirtualHost>
<VirtualHost *:80>
ServerAdmin webmaster@dummy-host2.localhost
DocumentRoot "/www/docs/dummy-host2.localhost"
ServerName dummy-host2.localhost
ErrorLog "logs/dummy-host2.localhost-error_log"
CustomLog "logs/dummy-host2.localhost-access_log common"
</VirtualHost>
# 可以将上面的内容改成自己下面的想要的目录和域名
<VirtualHost *:80>
ServerAdmin webmaster@dummy-host.localhost
DocumentRoot "D:/wamp/www/"
ServerName localhost
ServerAlias localhost
ErrorLog "logs/localhost-error_log"
</VirtualHost>
<VirtualHost *:80>
# 服务器名称 ( 这个可以跳过 )
ServerAdmin webmaster@dummy-host.localhost
# 网页根路径
DocumentRoot "D:/wamp/www/web/" (这个必须写)
ServerName test.com (填主域名, 这个可以跳过, 用localhost启动)
# 要绑多少个域名都可以写在 ServerAlias, 记得多个域名用空格隔开, ServerAlias 会将这这些域名指向同一个项目
ServerAlias *.test.com (这里的服务器别名可以支持泛解析,即所有的子域名都可以解析绑定到该虚拟主机)
ErrorLog "logs/localhost-error_log"
</VirtualHost>如果 弄完之后 出现403错误 那在httpd.conf里设置目录的访问权限 步骤:找到
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21<Directory />
Options FollowSymLinks ExecCGI Indexes
AllowOverride None
Order deny,allow
Deny from all
Satisfy all
</Directory>
更改为
<!-- Directory 为目录访问权限 -->
# Indexes 当没有指明访问文件夹下面的哪个文件而且也没有指定默认文件时, 会返回文件夹下的文件目录
# 该选项在正式开发中不会使用, 一般用于Apache或者php的学习
# 项目文件的根路径
<Directory "这里可以写入文件路径" />
Options FollowSymLinks ExecCGI Indexes
AllowOverride None
# Order deny,allow
# Deny from all
# Satisfy all
</Directory>
值得注意的是, 在修改Apache相关的文件之后, 都要重启Apache服务器才会生效
在重启Apache之前, 建议先使用 httpd -t 测试配置是否生效
1.5 PHP的时间配置
如果使用的是PHP原生安装包的话, 因为PHP默认配置的是零时区, 而我们中国是在东八区, 因此需要额外配置
PHP的配置文件, php.ini
打开文件找到,
1
;data.timezone =
将前面的分号去除
将等号后面改为 : PRC ( RPC代表着中国市区 )
1
;data.timezone = PRC
重启Apache (修改Apache和php的配置文件, 都需要重启Apache服务器, 让Apache重新加载这些配置 )
二. PHP基础
在php文件中 输入 echo phpinfo() 可输出php所有的状态信息
注意!!! 不同于js, 所有的php语句结尾必须要用分号; 声明, 不然会报错 ( 这点跟Java类似 )
2.1 变量的名称与使用
与Python类似, php定义变量没有特别关键字
1 | // 定义变量 |
2.2 全局变量
php内部内置了很多变量, 方便开发人员直接调用, 例如获取get参数的$_GET[] 数组变量
$_REQUEST[] 无论是get方法请求还是post方法请求都会获取到
值得注意的是
在外部的变量, 无法直接在函数中使用
需要通过使用函数形参传递的方法, 将函数外部的变量传进函数体内
或者使用 global关键字定义全局变量
2.3 字符串的拼接
与js不同的是, 字符串的拼接在php中是以 . 来进行连接的, 而不是 + 号
1 | $str = "hello"; |
并且 php 也支持 类似ES6 中的 js 模板语法
1 | $name = "王"; |
2.4 数据 ( 链表 )
2.4.1 数组的定义
1 | // 第一种定义数组的方式: |
2.4.2 冒泡算法
1 |
|
2.4.3 选择排序
选择排序原理:
1.遍历数组, 在此过程中, 找到数组的最大值及其下标位置, 然后将最大值的单元, 跟数组的最后一个单元”交换位置”, 这样进行一趟之后, 数组中的最大值就一定放在最后位置;
- 将上述过程中, 剩余的数据继续遍历一次, 并做同样的事情, 则此时剩余部分的最大值也能够放在剩余部分的最后位置–对整体而言就是倒数第二的位置排序
1 | $arr1 = [18, 22, 12, 15, 23, 9]; |
2.4.4 二分查找
此查找算法针对的数组有以下条件:
1. 索引数组 (数组的元素必须是数字)
2. 数组是已经排序好的了 (已经通过升序或者降序排序好了)
1 | $arr1 = [18, 22, 12, 15, 23, 9, 32,111, 3, 4, 123, 445]; |
2.4.5 数组指针
数组或者说链表中 forEach函数本质就是使用指针不断进行下一个的切换
1 | // 在php 中, 存在以下几个函数 |
2.5 PHP数据类型
- String(字符串)
- Integer(整型)
- Float(浮点型)
- Boolean(布尔型)
- Array(数组)
- Object(对象)
- NULL(空值)
三. PHP-mysql
3.1 PHP连接mysql数据库
- $link= @mysqli_connect($db_host.”:”.$db_port, $db_user, $db_pass), 连接mysql服务, 返回一个连接句柄
- mysqli_select_db($link, $db_name) , 连接数据库, 返回数据库句柄
- mysqli_set_charset($link, $charset); // 设置字符集
1 | <?php |
3.2 PHP对mysql数据库的增删改查
php 对mysql的curd 无非就是定义一个mysql工具类,
类中 有两个共有的类静态方法 (static修饰的方法)
四. PHP图像编辑
主要是应用到了 PHP的GD2 扩展, 但前端的canvas画图功能已经非常强大了, 因此对于后端的画图并没有多大的需求
pass
五. PHP文件上传
PHP内置了文件上传功能
pass
六. session与cookies
cookie和session均为PHP的超全局变量, 值得注意的是, cookie相应头的设置,需要放在php脚本的最前面
session和cookies都是PHP内置用于临时存储数据的超全局变量, 只是存放的位置不同, session存放于服务器会话中, cookie 存放于浏览器中
6.1 session
6.2 cookies
七. 类与对象
7.1 类与对象的关系
类就是分类,性别,模板,概念等, 类是无形,看不见,摸不着,不实际的 (抽象)
类是具有相同属性和行为的一组对象的集合(集合为抽象概念, 不是实体概念)
客观世界中的任何一个对象都可称之为类的对象, 具有属性和行为
在任何编程中, 都是先定义类, 再实例化成对象 ( 即先有类再有对象 )
7.2 类的定义 ( 或者说类的设计 )
一般定义一个类都是用 class 关键字进行修饰, 而且为了方便区别, 类名的头一个字母都是大写
类中只有两种内容: 成员变量和成员方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20class Student {
// 定义成员属性 (对象属性)
// public 是访问权限的修饰 (权限修饰符)
public $name = "wang";
public $age = 23;
private $id = '111'; // 私有权限, 只能在本类中被访问, 在类外和子类中都无权访问
protected $money = "222"; // 受保护的权限, 只能在本类中和子类中被访问, 在类外不能被访问
// define("DB_HOST", "localhost"); // 此时程序一运行就会报错
// 类中不允许存放普通代码
// 可以将普通代码放入成员方法中
// 定义成员方法 (对象方法)
public function showInfo(){
// __FILE__ 魔术常量, 获取当前文件的路径
echo __FILE__;
}
}
7.3 类的使用
1 | class student_02 { |
7.4 $this 关键字 和 self 关键字
7.5 类常量
7.5 类的生命周期函数 (内置方法)
构造函数
1
2
3// 构造函数
// 析构方法析构函数
7.6 静态属性与静态方法
静态属性和静态方法 都是在定义的前面用 static 关键字修饰, 此时的方法和属性都只于当前类相关, 而不与实例化出来的对象相关
1 | class Student_Static |
八. 数据库工具类
pass
九. PDO类
pass
十. Smarty
pass
十一. TP5
TP5是国人自己开发的框架,有中文官网, 中文帮助文档, 中文社区, 丰富的资源,虽然TP5已经是较为晚一代的产品, 但对于了解MVC的运行原理帮助很大
注意, 如需切换TP的版本, 只需要更换thinkPHP的目录即可
11.1 配置文件
11.2 函数文件
11.3 框架请求的生命周期
- 请求开始
- 入口文件
- 进入底层执行
- 引导文件 start.php
- 注册自动加载
- 注册错误和异常机制
- 应用初始化
- URL访问检测
- 路由检测
- 请求分发
- 进入控制器方法
- 视图输出
- 模型
11.4 控制器
11.4.1 控制器的后缀
打开控制器配置文件 application/config.php 有如下配置
1 | // 控制器类后缀 |
上面表达的是, controller控制器默认不带 前缀, controller下index控制器就叫index
如需改动, 则需将上述代码改成:
1 | // 控制器类后缀 |
上述表达的是, controller下的index控制器叫 WangIndex.php
11.5 url访问
在TP5.0的框架中, 默认使用PATH_INFO方式的url进行访问
即: http://域名/入口文件/模块名/控制器名称/操作方法/参数1/参数2
例如, 访问前台 index 模块下的index控制器的 index方法, 路径为:
http://localhost:8080/public/index.php/index/test/index
index.php为入口文件
隐藏入口文件
可以参考TP5.0的官方 URL重写方法:
打开httpd.conf
1
2# 将这行注释去电, 允许修改模块配置
LoadModule rewrite_module modules/mod_rewrite.so检索 AllowOverride All
1
2
3
4
5<Directory "${SRVROOT}/htdocs">
AllowOverride All
Options None
Require all granted
</Directory>通过在虚拟主机配置中也修改成上述内容
11.6 开启调试模式
在application中下的config.php, 将 “app_debug”的false改为true
1 | // 应用调试模式 |
11.7 模块
application下的目录称之为模块
在application下config.php配置了默认的模块和默认的控制器名称
1 | // 默认模块名 |
有上述可知, 按项目最开始访问的是, index模块下的index控制下的index方法
11.7.1 创建模块
手动创建模块, 一个模块的要包含以下几个要素
- controller
- view
- model
- config.php
- common.php
命令行创建模块
用命令行创建模块需要前往到项目根目录, 即think文件所在的目录
1
php think build --module home
命令行创建控制器
1
2
3
4php think make:controller 模块名/控制器名
例如: php think make:controller admin/edit
或者: php think make:controller admin/edit --plain ( 没有默认的7个方法 )
11.8 依赖注入
一般来说, 当我们想从B类中调用A的方法时, 会存在以下的方法:
1 |
|
但是如果明知, A类一定会实例化于B类的时候, 可以使用依赖注入的写法:
1 |
|
这种依赖的写法注入的写法用于controller控制器中
11.9 模板视图 (view)
模板的定义
为了方便模板的划分, TP框架对模板文件进行了目录划分, 默认的定义规则为: 视图目录 / 控制器名 (小写, 控制器大写, 则用_小写代替) / 操作名 ( 小写 ) + 模板后缀 ( 默认是.html )
值得注意的是, 当你不知道当前控制器实际会调用的是哪个目录下的模板时, 可以在调试模式下直接返回 模板, 错误信息会提示你在哪里创建模板, 因此并不需要太在意模板的目录结构
渲染模板的方式
1
2
3
4
5// 1.
return view();
// 2.
return $this->fetch();模板赋值方式:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15// 第一种方法
$user = ["id"=>"wang", "age"=>20];
$this->assign("user", $user);
return view();
// 第二种方法
$user=["id"=>"wang", "age"=>20];
$school="unknown";
return view("edit", ["user"=>$user, "school"=>$school]);
// 第三种方法
$user=["id"=>"wang", "age"=>20];
$school="unknown";
return view("edit", compact("user","school"));
// 上述这种写法类似于js Es6中的对象解构写法模板中的控制语句块
1.输出变量
1
2
3
4
5{php}/* 1.输出变量 */{/php}
我的id是: {$id}
我的年龄是: {$age}
我的学校是: {$school}
我的名字是: {$name}2.循环语法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19{php}/* 2. 循环语法 */{/php}
{php}/* 第一种循环语法, 较为常用 */{/php}
<ul>
{foreach name="list" item="vo" key="key"}
<li>
{$key} ==> {$vo}
</li>
{/foreach}
</ul>
{php}/* 循环的另外一种语法, 功能性更强 */{/php}
<ul>
{volist name="list" id="ov" key="index" }
<li>
{$key} ==> {$ov}
</li>
{/volist}
</ul>3.条件判断语法
1
2
3
4
5
6
7
8
9
10
11{php}/* 3. 条件判断语法 */{/php}
{if condition=" $is_member == 1 "}
<h4>这是会员</h4>
{else/}
<h4>不是会员</h4>
{/if}
{php}/* 注意!!!判断语句记得加上if */{/php}
11.10 模型 ( model )
十二. TP&RestFul
12.1 RestFul接口设计
12.1.1 API 设计六要素
资源路径( URL )
http动词( Method )
对于一个资源, 一般存在以下4个操作
GET:
从服务器中获取资源, 一项或者多项
POST:
从服务器中新建一个资源
PUT:
从服务器更新资源, 服务器返回完整的属性 (一般指的是实体)
DELETE:
从服务器删除资源, 服务器返回操作状态码
过滤信息 ( query-string )
状态码 ( Status-code )
常见的状态码一般存在以下几种
状态码 含义 说明 201 create 创建成功 204 delete 删除成功 400 bad request 语法错误 403 forbidden 请求没有权限 500 internal serve error 服务器处理错误 错误信息 ( error )
如果状态码是4XX或者5XX, 需要告诉客户端对应的错误信息, 通常以json格式返回:
1
2
3{
"error":"这是一个错误信息"
}
返回结果 ( Result )
针对不同的操作, 服务器需要返回的结果应该符合这样的规范
GET / collections –> 返回资源列表组
GET / collection/:id –> 返回资源列表 ( 列表 )
POST / collections –> 返回新生成的资源
POST / collection / :id –> 返回资源的完整属性
DELETE / collections / :id –> 返回204状态码 + 空文档
在实际开发中, 通常会将 状态码, 错误信息,返回数据, 都放在返回结果中
比如:
1
2
3
4
5
6
7
8{
"code":200,
"msg":"success",
"data":{
"id":1,
"user_name":"wang"
}
}
12.1.2 接口设计风格
RestFul是一种软件设计风格, 主要用于有客户端与服务端交互的设计
RestFul 是目前最流行的API设计规范, 用于Web数据接口的设计
以新闻资源的接口设计为例: URI ( URL + URN )以及HTTP动词设计:
| HTTP 动词 | URL 路径 | 说明 |
|---|---|---|
| GET | http://域名/news | 获取列表数据 |
| GET | http://域名/news/:id | 获取根据ID的单一数据 |
| POST | http://域名/news | 添加一条数据 |
| PUT | http://域名/news/:id | 根据ID修改一条数据 |
| DELETE | http://域名/news/:id | 根据id删除一条信息 |
12.2 RestFul & TP5实战
12.2.1 TP框架的资源路由
创建API模块
1
php think build --module api
创建new控制器
1
php think make:controller api/News
设置路由 ( application/route.php )
设置资源路由, 默认使用的是RestFul API的风格
1
\think\Route::resource("news", "api/news")