0

0

Yii2 advanced版API接口开发 基于RESTful架构的 配置、实现、测试

php中文网

php中文网

发布时间:2016-08-08 09:24:15

|

1205人浏览过

|

来源于php中文网

原创

环境配置:

开启服务器伪静态

本处以apache为例,查看apache的conf目录下httpd.conf,找到下面的代码

LoadModule rewrite_module modules/mod_rewrite.so

将其前面的#去掉,如果没有找到则添加进去。

找到一下代码

<Directory "C:/phpStudy/Apache/cgi-bin"><span>    AllowOverride All
    Options None
    </span><span>Require</span><span> all granted
</span></Directory>

将原本的AllowOverride None改为AllowOverride All。

然后在站点根目录下创建一个.htaccess文件,内容如下:

<IfModule mod_rewrite.c><span>  Options </span>+<span>FollowSymlinks
  RewriteEngine On
  RewriteCond </span>%{REQUEST_FILENAME} !-<span>d
  RewriteCond </span>%{REQUEST_FILENAME} !-<span>f
  RewriteRule </span>. index.<span>php
</span></IfModule>
.htaccess

此处不再赘述yii2的配置,如果需要可以看YII2实战手册

YII2实际操作:

1、配置URL规则及modules

(1)新建modules文件夹,实行api接口版本控制。例如V1版本、V2版本……

在v1文件夹下新建controllers文件夹(控制器)、models文件夹(模型)、Module.php配置文件。

Module.php文件如下:

<span> 1</span> <?<span>php
</span><span> 2</span><span>namespace api\modules\v1;
</span><span> 3</span><span> 4</span><span>class</span> Module <span>extends</span><span> \yii\base\Module
</span><span> 5</span><span>{
</span><span> 6</span><span> 7</span><span>public</span><span>$controllerNamespace</span> = 'api\modules\v1\controllers'<span>;
</span><span> 8</span><span> 9</span><span>public</span><span>function</span><span> init()
</span><span>10</span><span>    {
</span><span>11</span>         parent::<span>init();
</span><span>12</span><span>    }
</span><span>13</span> }

第2行和第7行随版本扩展而变化(v1->v2...)。

(2)配置config文件夹下的main.php文件

<span> 1</span> <?<span>php
</span><span> 2</span><span>$params</span> = <span>array_merge</span>(<span>require</span> (__DIR__ . '/../../common/config/params.php'), <span>require</span> (__DIR__ . '/../../common/config/params-local.php'), <span>require</span> (__DIR__ . '/params.php'), <span>require</span> (__DIR__ . '/params-local.php'<span>));
</span><span> 3</span><span> 4</span><span>return</span><span> [
</span><span> 5</span>     'id' => 'app-api',
<span> 6</span>     'basePath' => <span>dirname</span>(__DIR__),
<span> 7</span>     'bootstrap' =><span> [
</span><span> 8</span>         'log'
<span> 9</span>     ],
<span>10</span>     'modules' =><span> [
</span><span>11</span>         'v1' =><span> [
</span><span>12</span>             'class' => 'api\modules\v1\Module'
<span>13</span>         ],
<span>14</span>         'v2' =><span> [
</span><span>15</span>             'class' => 'api\modules\v2\Module'
<span>16</span><span>        ]
</span><span>17</span>     ],
<span>18</span>     'controllerNamespace' => 'api\controllers',
<span>19</span>     'components' =><span> [
</span><span>20</span>         'user' =><span> [
</span><span>21</span>             'identityClass' => 'common\models\User',
<span>22</span>             'enableAutoLogin' => <span>false</span>,
<span>23</span>             'enableSession' => <span>false</span>,
<span>24</span>             'loginUrl' => <span>null</span><span>25</span>         ],
<span>26</span>         'urlManager' =><span> [
</span><span>27</span>             'enablePrettyUrl' => <span>true</span>, <span>//</span><span> 启用美化URL</span><span>28</span>             'enableStrictParsing' => <span>true</span>, <span>//</span><span> 是否执行严格的url解析</span><span>29</span>             'showScriptName' => <span>false</span>, <span>//</span><span> 在URL路径中是否显示脚本入口文件</span><span>30</span>             'rules' =><span> [
</span><span>31</span><span>                [
</span><span>32</span>                     'class' => 'yii\rest\UrlRule',
<span>33</span>                     'controller' =><span> [
</span><span>34</span>                         'v1/site'
<span>35</span><span>                    ]
</span><span>36</span>                 ],
<span>37</span><span>                [
</span><span>38</span>                     'class' => 'yii\rest\UrlRule',
<span>39</span>                     'controller' =><span> [
</span><span>40</span>                         'v2/site'
<span>41</span><span>                    ]
</span><span>42</span><span>                ]
</span><span>43</span><span>            ]
</span><span>44</span>         ],
<span>45</span>         'log' =><span> [
</span><span>46</span>             'traceLevel' => YII_DEBUG ? 3 : 0,
<span>47</span>             'targets' =><span> [
</span><span>48</span><span>                [
</span><span>49</span>                     'class' => 'yii\log\FileTarget',
<span>50</span>                     'levels' =><span> [
</span><span>51</span>                         'error',
<span>52</span>                         'warning'
<span>53</span><span>                    ]
</span><span>54</span><span>                ]
</span><span>55</span><span>            ]
</span><span>56</span>         ],
<span>57</span>         'errorHandler' =><span> [
</span><span>58</span>             'errorAction' => 'site/error'
<span>59</span><span>        ]
</span><span>60</span>     ],
<span>61</span>     'params' => <span>$params</span><span>62</span> ];
main.php

注意10~17行、20~44行的组件配置,相信大家仔细阅读就能明白,此处不再赘述原理,请大家尤其注意33~35行的代码,此处表示的是v1/site控制器,随着接口控制器的增多,可以直接在数组中增加即可。本文力求快速配置出RESTful架构的实现。

(3)v2、v3表示以后的版本变化,配置都类似于v1文件夹。

2、创建一个模型

数据库准备一个名为mxq_guide的数据表

<span>CREATE TABLE `mxq_guide` (
  `id` int(</span>11) NOT <span>NULL</span> AUTO_INCREMENT,<span>  `imgurl` varchar(</span>255) <span>DEFAULT</span><span>NULL </span>COMMENT '图片路径'<span>,</span><span><br>  `status` int(</span><span>11) </span><span>DEFAULT</span><span>NULL</span><span> COMMENT '1启用 0禁用',<br></span><span>  `flag` int(</span><span>11) </span><span>DEFAULT</span><span>NULL</span><span> COMMENT '1安卓 2苹果',</span><span><br>   PRIMARY </span><span>KEY</span><span> (`id`) <br>   ) ENGINE</span><span>=MyISAM AUTO_INCREMENT=24 </span><span>DEFAULT</span><span> CHARSET=utf8 COMMENT='APP导航图';</span>

创建后请注意及时往数据库添加几条数据信息。

通过脚手架gii来创建guide.php模型(使用方法请看yii2权威指南)。生成后的文件注意改写,修改为如下形式以满足RESTful的需求。之后从models文件夹中转移到v1/models文件夹中,并注意命名空间的修改。

<span> 1</span> <?<span>php
</span><span> 2</span><span>namespace api\modules\v1\models;
</span><span> 3</span><span> 4</span><span>use</span><span> Yii;
</span><span> 5</span><span>use</span><span> yii\db\ActiveRecord;
</span><span> 6</span><span>use</span><span> yii\web\IdentityInterface;
</span><span> 7</span><span> 8</span><span>/*</span><span>*
</span><span> 9</span><span> * This is the model class for table "{{%guide}}".
</span><span>10</span><span> *
</span><span>11</span><span> * @property integer $id
</span><span>12</span><span> * @property string $imgurl
</span><span>13</span><span> * @property integer $status
</span><span>14</span><span> * @property integer $flag
</span><span>15</span><span>*/</span><span>16</span><span>class</span> Guide <span>extends</span> ActiveRecord <span>implements</span><span> IdentityInterface
</span><span>17</span><span>{
</span><span>18</span><span>19</span><span>public</span><span>static</span><span>function</span> findIdentityByAccessToken(<span>$token</span>, <span>$type</span> = <span>null</span><span>)
</span><span>20</span><span>    {
</span><span>21</span><span>return</span><span>static</span>::<span>findOne([
</span><span>22</span>             'access_token' => <span>$token</span><span>23</span><span>        ]);
</span><span>24</span><span>    }
</span><span>25</span><span>26</span><span>public</span><span>function</span><span> getId()
</span><span>27</span><span>    {
</span><span>28</span><span>return</span><span>$this</span>-><span>id;
</span><span>29</span><span>    }
</span><span>30</span><span>31</span><span>public</span><span>function</span><span> getAuthKey()
</span><span>32</span><span>    {
</span><span>33</span><span>return</span><span>$this</span>-><span>authKey;
</span><span>34</span><span>    }
</span><span>35</span><span>36</span><span>public</span><span>function</span> validateAuthKey(<span>$authKey</span><span>)
</span><span>37</span><span>    {
</span><span>38</span><span>return</span><span>$this</span>->authKey === <span>$authKey</span><span>;
</span><span>39</span><span>    }
</span><span>40</span><span>41</span><span>public</span><span>static</span><span>function</span> findIdentity(<span>$id</span><span>)
</span><span>42</span><span>    {
</span><span>43</span><span>return</span><span>static</span>::findOne(<span>$id</span><span>);
</span><span>44</span><span>    }
</span><span>45</span><span>46</span><span>public</span><span>static</span><span>function</span><span> tableName()
</span><span>47</span><span>    {
</span><span>48</span><span>return</span> '{{%guide}}'<span>;
</span><span>49</span><span>    }
</span><span>50</span><span>51</span><span>public</span><span>function</span><span> rules()
</span><span>52</span><span>    {
</span><span>53</span><span>return</span><span> [
</span><span>54</span><span>            [
</span><span>55</span><span>                [
</span><span>56</span>                     'imgurl',
<span>57</span>                     'status',
<span>58</span>                     'flag'
<span>59</span>                 ],
<span>60</span>                 'required'
<span>61</span>             ],
<span>62</span><span>            [
</span><span>63</span><span>                [
</span><span>64</span>                     'status',
<span>65</span>                     'flag'
<span>66</span>                 ],
<span>67</span>                 'integer'
<span>68</span>             ],
<span>69</span><span>            [
</span><span>70</span><span>                [
</span><span>71</span>                     'imgurl'
<span>72</span>                 ],
<span>73</span>                 'string',
<span>74</span>                 'max' => 255
<span>75</span><span>            ]
</span><span>76</span><span>        ];
</span><span>77</span><span>    }
</span><span>78</span><span>79</span><span>public</span><span>function</span><span> attributeLabels()
</span><span>80</span><span>    {
</span><span>81</span><span>return</span><span> [
</span><span>82</span>             'id' => Yii::t('app', 'ID'),
<span>83</span>             'imgurl' => Yii::t('app', 'imgurl'),
<span>84</span>             'status' => Yii::t('app', 'status'),
<span>85</span>             'flag' => Yii::t('app', 'flag'<span>)
</span><span>86</span><span>        ];
</span><span>87</span><span>    }
</span><span>88</span> }
guide.php

3、创建一个控制器

悟智写作
悟智写作

易开即用的AI写作平台

下载

<span> 1</span> <?<span>php
</span><span> 2</span><span>namespace api\modules\v1\controllers;
</span><span> 3</span><span> 4</span><span>use</span><span> Yii;
</span><span> 5</span><span>use</span><span> yii\rest\ActiveController;
</span><span> 6</span><span>use</span><span> yii\filters\auth\CompositeAuth;
</span><span> 7</span><span>use</span><span> yii\filters\auth\QueryParamAuth;
</span><span> 8</span><span>use</span><span> yii\data\ActiveDataProvider;
</span><span> 9</span><span>10</span><span>class</span> SiteController <span>extends</span><span> ActiveController
</span><span>11</span><span>{
</span><span>12</span><span>13</span><span>public</span><span>$modelClass</span> = 'api\modules\v1\models\guide'<span>;
</span><span>14</span><span>15</span><span>public</span><span>$serializer</span> =<span> [
</span><span>16</span>         'class' => 'yii\rest\Serializer',
<span>17</span>         'collectionEnvelope' => 'items'
<span>18</span><span>    ];
</span><span>19</span><span>20</span><span>//</span><span> public function behaviors()
</span><span>21</span><span>    // {
</span><span>22</span><span>    // $behaviors = parent::behaviors();
</span><span>23</span><span>    // $behaviors['authenticator'] = [
</span><span>24</span><span>    // 'class' => CompositeAuth::className(),
</span><span>25</span><span>    // 'authMethods' => [
</span><span>26</span><span>    // QueryParamAuth::className()
</span><span>27</span><span>    // ]
</span><span>28</span><span>    // ];
</span><span>29</span><span>    // return $behaviors;
</span><span>30</span><span>    // }</span><span>31</span><span>public</span><span>function</span><span> actions()
</span><span>32</span><span>    {
</span><span>33</span><span>$actions</span> = parent::<span>actions();
</span><span>34</span><span>//</span><span> 注销系统自带的实现方法</span><span>35</span><span>unset</span>(<span>$actions</span>['index'], <span>$actions</span>['update'], <span>$actions</span>['create'], <span>$actions</span>['delete'], <span>$actions</span>['view'<span>]);
</span><span>36</span><span>return</span><span>$actions</span><span>;
</span><span>37</span><span>    }
</span><span>38</span><span>39</span><span>public</span><span>function</span><span> actionIndex()
</span><span>40</span><span>    {
</span><span>41</span><span>$modelClass</span> = <span>$this</span>-><span>modelClass;
</span><span>42</span><span>$query</span> = <span>$modelClass</span>::<span>find();
</span><span>43</span><span>return</span><span>new</span><span> ActiveDataProvider([
</span><span>44</span>             'query' => <span>$query</span><span>45</span><span>        ]);
</span><span>46</span><span>    }
</span><span>47</span><span>48</span><span>public</span><span>function</span><span> actionCreate()
</span><span>49</span><span>    {
</span><span>50</span><span>$model</span> = <span>new</span><span>$this</span>-><span>modelClass();
</span><span>51</span><span>//</span><span> $model->load(Yii::$app->getRequest()
</span><span>52</span><span>        // ->getBodyParams(), '');</span><span>53</span><span>$model</span>->attributes = Yii::<span>$app</span>->request-><span>post();
</span><span>54</span><span>if</span> (! <span>$model</span>-><span>save()) {
</span><span>55</span><span>return</span><span>array_values</span>(<span>$model</span>->getFirstErrors())[0<span>];
</span><span>56</span><span>        }
</span><span>57</span><span>return</span><span>$model</span><span>;
</span><span>58</span><span>    }
</span><span>59</span><span>60</span><span>public</span><span>function</span> actionUpdate(<span>$id</span><span>)
</span><span>61</span><span>    {
</span><span>62</span><span>$model</span> = <span>$this</span>->findModel(<span>$id</span><span>);
</span><span>63</span><span>$model</span>->attributes = Yii::<span>$app</span>->request-><span>post();
</span><span>64</span><span>if</span> (! <span>$model</span>-><span>save()) {
</span><span>65</span><span>return</span><span>array_values</span>(<span>$model</span>->getFirstErrors())[0<span>];
</span><span>66</span><span>        }
</span><span>67</span><span>return</span><span>$model</span><span>;
</span><span>68</span><span>    }
</span><span>69</span><span>70</span><span>public</span><span>function</span> actionDelete(<span>$id</span><span>)
</span><span>71</span><span>    {
</span><span>72</span><span>return</span><span>$this</span>->findModel(<span>$id</span>)-><span>delete();
</span><span>73</span><span>    }
</span><span>74</span><span>75</span><span>public</span><span>function</span> actionView(<span>$id</span><span>)
</span><span>76</span><span>    {
</span><span>77</span><span>return</span><span>$this</span>->findModel(<span>$id</span><span>);
</span><span>78</span><span>    }
</span><span>79</span><span>80</span><span>protected</span><span>function</span> findModel(<span>$id</span><span>)
</span><span>81</span><span>    {
</span><span>82</span><span>$modelClass</span> = <span>$this</span>-><span>modelClass;
</span><span>83</span><span>if</span> ((<span>$model</span> = <span>$modelClass</span>::findOne(<span>$id</span>)) !== <span>null</span><span>) {
</span><span>84</span><span>return</span><span>$model</span><span>;
</span><span>85</span>         } <span>else</span><span> {
</span><span>86</span><span>throw</span><span>new</span> NotFoundHttpException('The requested page does not exist.'<span>);
</span><span>87</span><span>        }
</span><span>88</span><span>    }
</span><span>89</span><span>90</span><span>public</span><span>function</span> checkAccess(<span>$action</span>, <span>$model</span> = <span>null</span>, <span>$params</span> =<span> [])
</span><span>91</span><span>    {
</span><span>92</span><span>//</span><span> 检查用户能否访问 $action 和 $model
</span><span>93</span><span>        // 访问被拒绝应抛出ForbiddenHttpException
</span><span>94</span><span>        // var_dump($params);exit;</span><span>95</span><span>    }
</span><span>96</span> }
SiteController.php

控制器请创建在modules/controllers文件夹下,并注意命名空间的修改。

要注意的是,此处的控制器与普通的控制器继承Controller不同,此处需继承ActiveController类。

20~30行注释的代码是基于RESTful架构的access_token认证,目前还未测试通过,后续补充。

至此,基于YII2的所有配置已基本完成,接下来介绍api接口测试工具及方法。

RESTful的测试工具PostMAN:

 首先介绍一下postman这款插件,是基于谷歌浏览器的一款模拟请求的实用插件。具体使用,在下面测试过程中涉及截图,介绍不足之处请见谅,自己也是第一次使用。

推荐使用上面的APP版本,便于后续封装自己写好的api接口,下面的是网页版本。

YII2支持的RESTful有四种请求方式:GET查看信息,POST创建信息,PUT更新信息,DELETE删除信息。

下面开始演示四种请求数据的方式。(只是截图演示效果,具体使用还需要大家自己去摸索。)

此处演示的是GET方法请求数据库的数据。对应的是modules/controllers/SiteController/actionIndex方法。

请大家注意最上面方框内的URL地址,rest默认将控制器进行复数请求http://api.mxq.com/v1/sites,此处就是rest的默认规则。

打*星号位置显示的是正常的效果,如若出现错误,大家可以去YII权威指南——错误检查错误原因。

YII2的ActiveController默认实现了数据的分页效果。

此处演示的是POST方法新建数据库的数据。对应的是modules/controllers/SiteController/actionCreate方法。

如果在数据库的数据层写好数据校验规则,此处提交数据不满足要求的时候就会显示相应的错误。这也是REST的优势之一。比如如下情况,flag我定义的是int型:

接下来演示的是PUT方法更新数据库的数据。对应的是modules/controllers/SiteController/actionUpdate方法。

此处请大家再次注意最上面的URL:http://api.mxq.com/v1/sites/15  此处15代表的是数据库id为15的数据,表示更新数据库ID为15的数据信息。请大家一定注意。RESTful在使用更新和删除数据操作的时候,id不能一表单的形式提交,必须紧跟在URL之后。

接下来演示的是DELETE方法删除数据库的数据。对应的是modules/controllers/SiteController/actionDelete方法。

当返回值为1的时候表示的就是删除操作执行成功。具体原理请大家仔细观察sitecontroller控制器内的函数。


以上就是基于yii2的RESTful的一些简单介绍、实现方法以及测试结果。有什么不正确或遗漏的地方,欢迎大家来补充。后续也会在此基础上进行更新。本人第一次接触yii2框架和RESTful架构,表述如有不对之处,请大家见谅。

以上就介绍了Yii2 advanced版API接口开发 基于RESTful架构的 配置、实现、测试,包括了方面的内容,希望对PHP教程有兴趣的朋友有所帮助。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法

本专题系统整理pixiv网页版官网入口及登录访问方式,涵盖官网登录页面直达路径、在线阅读入口及快速进入方法说明,帮助用户高效找到pixiv官方网站,实现便捷、安全的网页端浏览与账号登录体验。

705

2026.02.13

微博网页版主页入口与登录指南_官方网页端快速访问方法
微博网页版主页入口与登录指南_官方网页端快速访问方法

本专题系统整理微博网页版官方入口及网页端登录方式,涵盖首页直达地址、账号登录流程与常见访问问题说明,帮助用户快速找到微博官网主页,实现便捷、安全的网页端登录与内容浏览体验。

233

2026.02.13

Flutter跨平台开发与状态管理实战
Flutter跨平台开发与状态管理实战

本专题围绕Flutter框架展开,系统讲解跨平台UI构建原理与状态管理方案。内容涵盖Widget生命周期、路由管理、Provider与Bloc状态管理模式、网络请求封装及性能优化技巧。通过实战项目演示,帮助开发者构建流畅、可维护的跨平台移动应用。

117

2026.02.13

TypeScript工程化开发与Vite构建优化实践
TypeScript工程化开发与Vite构建优化实践

本专题面向前端开发者,深入讲解 TypeScript 类型系统与大型项目结构设计方法,并结合 Vite 构建工具优化前端工程化流程。内容包括模块化设计、类型声明管理、代码分割、热更新原理以及构建性能调优。通过完整项目示例,帮助开发者提升代码可维护性与开发效率。

22

2026.02.13

Redis高可用架构与分布式缓存实战
Redis高可用架构与分布式缓存实战

本专题围绕 Redis 在高并发系统中的应用展开,系统讲解主从复制、哨兵机制、Cluster 集群模式及数据分片原理。内容涵盖缓存穿透与雪崩解决方案、分布式锁实现、热点数据优化及持久化策略。通过真实业务场景演示,帮助开发者构建高可用、可扩展的分布式缓存系统。

61

2026.02.13

c语言 数据类型
c语言 数据类型

本专题整合了c语言数据类型相关内容,阅读专题下面的文章了解更多详细内容。

30

2026.02.12

雨课堂网页版登录入口与使用指南_官方在线教学平台访问方法
雨课堂网页版登录入口与使用指南_官方在线教学平台访问方法

本专题系统整理雨课堂网页版官方入口及在线登录方式,涵盖账号登录流程、官方直连入口及平台访问方法说明,帮助师生用户快速进入雨课堂在线教学平台,实现便捷、高效的课程学习与教学管理体验。

15

2026.02.12

豆包AI网页版入口与智能创作指南_官方在线写作与图片生成使用方法
豆包AI网页版入口与智能创作指南_官方在线写作与图片生成使用方法

本专题汇总豆包AI官方网页版入口及在线使用方式,涵盖智能写作工具、图片生成体验入口和官网登录方法,帮助用户快速直达豆包AI平台,高效完成文本创作与AI生图任务,实现便捷智能创作体验。

669

2026.02.12

PostgreSQL性能优化与索引调优实战
PostgreSQL性能优化与索引调优实战

本专题面向后端开发与数据库工程师,深入讲解 PostgreSQL 查询优化原理与索引机制。内容包括执行计划分析、常见索引类型对比、慢查询优化策略、事务隔离级别以及高并发场景下的性能调优技巧。通过实战案例解析,帮助开发者提升数据库响应速度与系统稳定性。

58

2026.02.12

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
AngularJS教程
AngularJS教程

共24课时 | 3.7万人学习

CSS3实现按钮特效视频教程
CSS3实现按钮特效视频教程

共15课时 | 3.3万人学习

细说PHP第三季
细说PHP第三季

共58课时 | 11.5万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号