Home > Article > Backend Development > Yii2 advanced version API interface development Configuration, implementation and testing based on RESTful architecture
Environment configuration:
Enable server pseudo-static
This article takes apache as an example. Check httpd.conf in apache's conf directory and find the following code
LoadModule rewrite_module modules/mod_rewrite.so
Remove the # in front of it, and add it if not found .
Find the code
<Directory "C:/phpStudy/Apache/cgi-bin"><span> AllowOverride All Options None </span><span>Require</span><span> all granted </span></Directory>
Change the original AllowOverride None to AllowOverride All.
Then create an .htaccess file in the root directory of the site with the following content:
<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
The configuration of yii2 will not be described here. If necessary, you can read the YII2 Practical Manual .
YII2 actual operation:
1. Configure URL rules and modules
(1) Create a new modules folder and implement api interface version control. For example, V1 version, V2 version...
Create a new controllers folder (controller), models folder (model), and Module.php configuration file under the v1 folder.
Module.php file is as follows:
<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> }
Lines 2 and 7 change with version expansion (v1->v2...).
(2) Configure the main.php file under the config folder
<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
Pay attention to the component configuration of lines 10~17 and 20~44. I believe you can understand it if you read it carefully , I won’t go into details here. Please pay special attention to lines 33 to 35 of the code. This represents the v1/site controller. As the number of interface controllers increases, you can directly add them to the array. This article strives to quickly configure the implementation of RESTful architecture.
(3) v2 and v3 represent future version changes, and the configuration is similar to the v1 folder.
2. Create a model
Prepare a data table named mxq_guide in the database
<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>
After creation, please pay attention to add several pieces of data information to the database in time.
Create the guide.php model through scaffolding gii (see the yii2 authoritative guide for usage instructions). Pay attention to rewriting the generated file and modify it into the following form to meet RESTful requirements. Then move from the models folder to the v1/models folder and pay attention to the modification of the namespace.
<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. Create a controller
<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
Please create the controller under the modules/controllers folder and pay attention to the namespace Modifications.
It should be noted that the controller here is different from the ordinary controller that inherits Controller. It needs to inherit the ActiveController class.
The 20~30 lines of commented code are based on the access_token authentication of the RESTful architecture. It has not been tested yet and will be added later.
At this point, all configurations based on YII2 have been basically completed. Next, we will introduce the api interface testing tools and methods.
RESTful testing tool PostMAN:
First, let’s introduce the postman plug-in, which is a practical plug-in based on Google Chrome that simulates requests. The specific use involves screenshots during the following test process. Please forgive me for any shortcomings in the introduction. This is my first time using it.
It is recommended to use the above APP version to facilitate subsequent packaging of the api interface written by yourself. The following is the web version.
YII2 supports four RESTful request methods: GET to view information, POST to create information, PUT to update information, and DELETE to delete information.
The following is a demonstration of four ways to request data. (This is just a screenshot to demonstrate the effect. You still need to explore the specific use by yourself.)
What is demonstrated here is the GET method to request database data. Corresponding to the modules/controllers/SiteController/actionIndex method.
Please pay attention to the URL address in the top box. By default, REST will make plural requests to the controller http://api.mxq.com/v1/sites. Here are the default rules of REST.
The positions marked with * show normal results. If an error occurs, you can go to YII Authoritative Guide - Error to check the cause of the error.
YII2’s ActiveController implements data paging effect by default.
What is demonstrated here is the data of the new database created by the POST method. Corresponding to the modules/controllers/SiteController/actionCreate method.
If you write data verification rules in the data layer of the database, corresponding errors will be displayed when the data submitted here does not meet the requirements. This is also one of the advantages of REST. For example, in the following situation, I define the flag as int type:
The next demonstration is the PUT method to update the data in the database. Corresponding to the modules/controllers/SiteController/actionUpdate method.
Please pay attention to the top URL again: http://api.mxq.com/v1/sites/15 Here 15 represents the data with database ID 15, which means updating the database ID to 15 data information. Please pay attention. When RESTful uses update and delete data operations, the id cannot be submitted in the form of a form and must follow the URL.
The next demonstration is the DELETE method to delete data from the database. Corresponding to the modules/controllers/SiteController/actionDelete method.
When the return value is 1, it means that the deletion operation was successfully executed. For the specific principle, please carefully observe the functions in the sitecontroller controller.
The above is some brief introduction, implementation methods and test results of RESTful based on yii2. If there are any errors or omissions, please feel free to add them. Subsequent updates will be made on this basis. This is my first time coming into contact with the yii2 framework and RESTful architecture. Please forgive me if there are any mistakes in my description.
The above introduces the configuration, implementation, and testing of Yii2 advanced version API interface development based on RESTful architecture, including aspects of it. I hope it will be helpful to friends who are interested in PHP tutorials.