没有不值得去解决的问题,也没有不值得去学习的技术!

Create a GitHub Repository for yiisoft/yii2-app-advanced and Add an RPC Application with Hprose 2.0 for PHP

Open Windows PowerShell, execute the init command, and select dev as the environment; the environment configuration files required by the api application are generated automatically

1. Implement the corresponding RESTful-style Web Service API for Pages in the api directory, then adjust it to act as an RPC client.

2. After all the corresponding APIs for Pages are implemented, execute a POST request in Postman; the response is normal, as shown in Figure 1.

After all the corresponding APIs for Pages are implemented, execute a POST request in Postman; the response is normal
Figure 1
JSON
{
	"title":"title-20180731-1",
	"body":"body-20180731-1"
}

JSON
{
    "code": 10000,
    "message": "创建页面成功",
    "data": {
        "title": "title-20180731-1",
        "body": "body-20180731-1",
        "slug": "title-20180731-1",
        "created_at": 1533015414,
        "updated_at": 1533015414,
        "id": 1
    }
}

3. Execute a PUT /pages/1 request in Postman; the response is normal.

JSON
{
	"slug":"slug-20180731-1",
	"title":"title-20180731-1",
	"body":"body-20180731-1",
	"status":2
}

JSON
{
    "code": 10000,
    "message": "更新页面成功",
    "data": {
        "id": 1,
        "slug": "slug-20180731-1",
        "title": "title-20180731-1",
        "body": "body-20180731-1",
        "view": 0,
        "status": 2,
        "created_at": 1533015414,
        "updated_at": 1533015770
    }
}

4. Execute a GET /pages request in Postman; the response is normal.

JSON
{
    "code": 10000,
    "message": "获取页面列表成功",
    "data": {
        "items": [
            {
                "id": 1,
                "slug": "slug-20180731-1",
                "title": "title-20180731-1",
                "body": "body-20180731-1",
                "view": 0,
                "status": 2,
                "created_at": 1533015414,
                "updated_at": 1533015770
            }
        ],
        "_links": {
            "self": {
                "href": "http://api.github-shuijingwan-yii2-app-advanced.localhost/v1/pages?page=1"
            }
        },
        "_meta": {
            "totalCount": 1,
            "pageCount": 1,
            "currentPage": 1,
            "perPage": 20
        }
    }
}

5. Execute a GET /pages/1 request in Postman; the response is normal.

JSON
{
    "code": 10000,
    "message": "获取用户详情成功",
    "data": {
        "id": 1,
        "slug": "slug-20180731-1",
        "title": "title-20180731-1",
        "body": "body-20180731-1",
        "view": 0,
        "status": 2,
        "created_at": 1533015414,
        "updated_at": 1533015770
    }
}

6. Execute a DELETE /pages/1 request in Postman; the response is normal.

JSON
{
    "code": 10000,
    "message": "删除页面成功"
}

7. Execute a GET /pages request in Postman; the response is normal.

Plaintext
filter[title][like]:title
filter[slug][like]:2018
filter[status]:2

JSON
{
    "code": 10000,
    "message": "获取页面列表成功",
    "data": {
        "items": [
            {
                "id": 1,
                "slug": "slug-20180731-1",
                "title": "title-20180731-1",
                "body": "body-20180731-1",
                "view": 0,
                "status": 2,
                "created_at": 1533015414,
                "updated_at": 1533019394
            }
        ],
        "_links": {
            "self": {
                "href": "http://api.github-shuijingwan-yii2-app-advanced.localhost/v1/pages?filter%5Btitle%5D%5Blike%5D=title&filter%5Bslug%5D%5Blike%5D=2018&filter%5Bstatus%5D=2&page=1"
            }
        },
        "_meta": {
            "totalCount": 1,
            "pageCount": 1,
            "currentPage": 1,
            "perPage": 20
        }
    }
}

8. Install Hprose using the composer command line.

Bash
composer require "hprose/hprose-yii:^2.0"

Plaintext
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 2 installs, 0 updates, 0 removals
  - Installing hprose/hprose (v2.0.35): Downloading (100%)
  - Installing hprose/hprose-yii (v2.0.0): Downloading (100%)
hprose/hprose suggests installing ext-hprose (Faster serialize and unserialize hprose extension.)
hprose/hprose-yii suggests installing ext-hprose (Faster serialize and unserialize hprose extension.)
Writing lock file
Generating autoload files

9. Add the RPC application (rpc). Copy frontend to rpc, environments/dev/frontend to environments/dev/rpc, and environments/prod/frontend to environments/prod/rpc.

10. Delete all files in the \rpc\runtime\debug directory, delete all files except .gitignore in the \rpc\tests\_output directory, and delete \rpc\runtime\logs\app.log. In the /rpc directory, adjust the namespaces and paths to start with rpc (replace frontend with rpc), as shown in Figure 2.

Delete all files in the \rpc\runtime\debug directory, delete all files except .gitignore in the \rpc\tests\_output directory, delete \rpc\runtime\logs\app.log, and in the /rpc directory, adjust the namespaces and paths to start with rpc (replace frontend with rpc)
Figure 2

11. Add Yii::setAlias(‘rpc’, dirname(dirname(__DIR__)) . ‘/rpc’) to common\config\bootstrap.php.

12. Edit environments/index.php. Search this file and find 6 instances of frontend; copy them accordingly and replace them with rpc.

13. In \vagrant\nginx\app.conf, add a new virtual host rpc.

14. Edit \vagrant\nginx\log\.gitignore to configure the rpc log files to be ignored.

15. Edit \Vagrantfile to add rpc-related configurations.

16. Configure the web server based on Nginx. Configure the virtual hosts: www, backend, api, and rpc. Edit C:\nginx-1.10.1\conf\vhosts\github-shuijingwan-yii2-app-advanced.conf.

Nginx
## FRONTEND ##
server {
    charset utf-8;
    client_max_body_size 128M;

    listen 80; ## listen for ipv4
    #listen [::]:80 default_server ipv6only=on; ## listen for ipv6

    server_name www.github-shuijingwan-yii2-app-advanced.localhost;
    root        E:/wwwroot/github-shuijingwan-yii2-app-advanced/frontend/web;
    index       index.php;

    access_log  logs/www.github-shuijingwan-yii2-app-advanced.localhost.access.log;
    error_log   logs/www.github-shuijingwan-yii2-app-advanced.localhost.error.log;

	location / {
		# Redirect everything that isn't a real file to index.php
		try_files $uri $uri/ /index.php$is_args$args;
	}

	# uncomment to avoid processing of calls to non-existing static files by Yii
	#location ~ \.(js|css|png|jpg|gif|swf|ico|pdf|mov|fla|zip|rar)$ {
	#    try_files $uri =404;
	#}
	#error_page 404 /404.html;

	# deny accessing php files for the /assets directory
	location ~ ^/assets/.*\.php$ {
		deny all;
	}

	location ~ \.php$ {
		include fastcgi_params;
		fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
		fastcgi_pass 127.0.0.1:9000;
		#fastcgi_pass unix:/var/run/php5-fpm.sock;
		try_files $uri =404;
	}

	location ~* /\. {
		deny all;
	}
}

## BACKEND ##
server {
    charset utf-8;
    client_max_body_size 128M;

    listen 80; ## listen for ipv4
    #listen [::]:80 default_server ipv6only=on; ## listen for ipv6

    server_name backend.github-shuijingwan-yii2-app-advanced.localhost;
    root        E:/wwwroot/github-shuijingwan-yii2-app-advanced/backend/web;
    index       index.php;

    access_log  logs/backend.github-shuijingwan-yii2-app-advanced.localhost.access.log;
    error_log   logs/backend.github-shuijingwan-yii2-app-advanced.localhost.error.log;

	location / {
		# Redirect everything that isn't a real file to index.php
		try_files $uri $uri/ /index.php$is_args$args;
	}

	# uncomment to avoid processing of calls to non-existing static files by Yii
	#location ~ \.(js|css|png|jpg|gif|swf|ico|pdf|mov|fla|zip|rar)$ {
	#    try_files $uri =404;
	#}
	#error_page 404 /404.html;

	# deny accessing php files for the /assets directory
	location ~ ^/assets/.*\.php$ {
		deny all;
	}

	location ~ \.php$ {
		include fastcgi_params;
		fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
		fastcgi_pass 127.0.0.1:9000;
		#fastcgi_pass unix:/var/run/php5-fpm.sock;
		try_files $uri =404;
	}

	location ~* /\. {
		deny all;
	}
}

## API ##
server {
    charset utf-8;
    client_max_body_size 128M;

    listen 80; ## listen for ipv4
    #listen [::]:80 default_server ipv6only=on; ## listen for ipv6

    server_name api.github-shuijingwan-yii2-app-advanced.localhost;
    root        E:/wwwroot/github-shuijingwan-yii2-app-advanced/api/web;
    index       index.php;

    access_log  logs/api.github-shuijingwan-yii2-app-advanced.localhost.access.log;
    error_log   logs/api.github-shuijingwan-yii2-app-advanced.localhost.error.log;

	location / {
		# Redirect everything that isn't a real file to index.php
		try_files $uri $uri/ /index.php$is_args$args;
	}

	# uncomment to avoid processing of calls to non-existing static files by Yii
	#location ~ \.(js|css|png|jpg|gif|swf|ico|pdf|mov|fla|zip|rar)$ {
	#    try_files $uri =404;
	#}
	#error_page 404 /404.html;

	# deny accessing php files for the /assets directory
	location ~ ^/assets/.*\.php$ {
		deny all;
	}

	location ~ \.php$ {
		include fastcgi_params;
		fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
		fastcgi_pass 127.0.0.1:9000;
		#fastcgi_pass unix:/var/run/php5-fpm.sock;
		try_files $uri =404;
	}

	location ~* /\. {
		deny all;
	}
}

## RPC ##
server {
    charset utf-8;
    client_max_body_size 128M;

    listen 80; ## listen for ipv4
    #listen [::]:80 default_server ipv6only=on; ## listen for ipv6

    server_name rpc.github-shuijingwan-yii2-app-advanced.localhost;
    root        E:/wwwroot/github-shuijingwan-yii2-app-advanced/rpc/web;
    index       index.php;

    access_log  logs/rpc.github-shuijingwan-yii2-app-advanced.localhost.access.log;
    error_log   logs/rpc.github-shuijingwan-yii2-app-advanced.localhost.error.log;

	location / {
		# Redirect everything that isn't a real file to index.php
		try_files $uri $uri/ /index.php$is_args$args;
	}

	# uncomment to avoid processing of calls to non-existing static files by Yii
	#location ~ \.(js|css|png|jpg|gif|swf|ico|pdf|mov|fla|zip|rar)$ {
	#    try_files $uri =404;
	#}
	#error_page 404 /404.html;

	# deny accessing php files for the /assets directory
	location ~ ^/assets/.*\.php$ {
		deny all;
	}

	location ~ \.php$ {
		include fastcgi_params;
		fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
		fastcgi_pass 127.0.0.1:9000;
		#fastcgi_pass unix:/var/run/php5-fpm.sock;
		try_files $uri =404;
	}

	location ~* /\. {
		deny all;
	}
}

## MISC ##

### WWW Redirect ###
server {
    listen       80;
    server_name  github-shuijingwan-yii2-app-advanced.localhost;
    return       301 http://www.github-shuijingwan-yii2-app-advanced.localhost$request_uri;
}


17. Open Windows PowerShell, execute the init command, and select dev as the environment. The environment configuration files required by the api application are generated automatically, as shown in Figure 3.

Open Windows PowerShell, execute the init command, and select dev as the environment; the environment configuration files required by the api application are generated automatically
Figure 3
Plaintext
.\init
0
yes
All

18. Open: http://rpc.github-shuijingwan-yii2-app-advanced.localhost/ . It works as expected.

19. Edit codeception.yml to configure tests that include all applications.

20. Because the console application uses a different request component, edit \common\config\test.php and comment out the request component (it needs to be uncommented in web applications).

PHP
    'components' => [
        'user' => [
            'class' => 'yii\web\User',
            'identityClass' => 'common\models\User',
        ],
        /*
        'request' => [
            'cookieValidationKey' => 'test',
        ],
        */
    ],

21. Execute the migration command for testing, as shown in Figure 4.

Execute the migration command for testing
Figure 4
Bash
./yii_test migrate --migrationPath=@yii/log/migrations/
./yii_test migrate

22. Build the test suite, then run all sample tests.
Note: After executing the migration command (./yii_test migrate), you must uncomment the request component; otherwise, an error will occur:

Plaintext
 Test  ..\common\tests\unit\models\LoginFormTest.php:testLoginCorrect

  [yii\base\InvalidConfigException] yii\web\Request::cookieValidationKey must be configured with a secret key.

Bash
vendor/bin/codecept build
vendor/bin/codecept run

23. Edit README.md to add rpc to the directory structure.

Markdown
<p align="center">
    <a href="https://github.com/yiisoft" target="_blank">
        <img src="https://avatars0.githubusercontent.com/u/993323" height="100px">
    </a>
    <h1 align="center">Yii 2 Advanced Project Template</h1>
    <br>
</p>
 
Yii 2 Advanced Project Template is a skeleton [Yii 2](http://www.yiiframework.com/) application best for
developing complex Web applications with multiple tiers.
 
The template includes four tiers: api, front end, back end, and console, each of which
is a separate Yii application.
 
The template is designed to work in a team development environment. It supports
deploying the application in different environments.
 
Documentation is at [docs/guide-zh-CN/README.md](docs/guide-zh-CN/README.md).
 
[![Latest Stable Version](https://img.shields.io/packagist/v/yiisoft/yii2-app-advanced.svg)](https://packagist.org/packages/yiisoft/yii2-app-advanced)
[![Total Downloads](https://img.shields.io/packagist/dt/yiisoft/yii2-app-advanced.svg)](https://packagist.org/packages/yiisoft/yii2-app-advanced)
[![Build Status](https://travis-ci.org/yiisoft/yii2-app-advanced.svg?branch=master)](https://travis-ci.org/yiisoft/yii2-app-advanced)
 
## TABLE OF CONTENTS
- [Basic info](docs/guide-zh-CN/README.md)
- [Installation](docs/guide-zh-CN/start-installation.md)
    - [Manual installation](docs/guide-zh-CN/start-installation.md)
    - [Vagrant installation](docs/guide-zh-CN/start-installation.md#使用vagrant安装)
- [Testing](docs/guide-zh-CN/start-testing.md)
 
DIRECTORY STRUCTURE
-------------------
 
```
common
    config/              contains shared configurations
    fixtures/            contains fixtures for common classes
    logics/              contains logic classes used in both backend and frontend and api and console
    mail/                contains view files for e-mails
    messages/            contains message files for I18N
    models/              contains model classes used in both backend and frontend and api and console
    tests/               contains various tests for common classes
    widgets/             contains common widgets
console
    config/              contains console configurations
    controllers/         contains console controllers (commands)
    migrations/          contains database migrations
    models/              contains console-specific model classes
    runtime/             contains files generated during runtime
backend
    assets/              contains application assets such as JavaScript and CSS
    config/              contains backend configurations
    controllers/         contains Web controller classes
    models/              contains backend-specific model classes
    runtime/             contains files generated during runtime
    tests/               contains various tests for backend application    
    views/               contains view files for the Web application
    web/                 contains the entry script and Web resources
frontend
    assets/              contains application assets such as JavaScript and CSS
    config/              contains frontend configurations
    controllers/         contains Web controller classes
    models/              contains frontend-specific model classes
    runtime/             contains files generated during runtime
    tests/               contains various tests for frontend application
    views/               contains view files for the Web application
    web/                 contains the entry script and Web resources
    widgets/             contains frontend widgets
api
    behaviors/           contains behaviors for api application
    config/              contains api configurations
    controllers/         contains Web controller classes
    fixtures/            contains fixtures for api application
    models/              contains api-specific model classes
    modules/             contains modules for api application
    rests/               contains rests for api application
    runtime/             contains files generated during runtime
    tests/               contains various tests for api application
    views/               contains view files for the Web application
    web/                 contains the entry script and Web resources
rpc
    assets/              contains application assets such as JavaScript and CSS
    config/              contains rpc configurations
    controllers/         contains Web controller classes
    models/              contains rpc-specific model classes
    runtime/             contains files generated during runtime
    tests/               contains various tests for rpc application
    views/               contains view files for the Web application
    web/                 contains the entry script and Web resources
    widgets/             contains rpc widgets
vendor/                  contains dependent 3rd-party packages
environments/            contains environment-based overrides
.gitignore               contains a list of directories ignored by git version system. If you need something never get to your source code repository, add it there.
composer.json            Composer config described in Configuring Composer.
init                     initialization script described in Configuration and environments.
init.bat                 same for Windows.
LICENSE.md               license info. Put your project license there. Especially when opensourcing.
README.md                basic info about installing template. Consider replacing it with information about your project and its installation.
requirements.php         Yii requirements checker.
yii                      console application bootstrap.
yii.bat                  same for Windows.
```
 
 

24. Test whether the Vagrant installation supports rpc. Reference URL: https://github.com/yiisoft/yii2-app-advanced/blob/master/docs/guide-zh-CN/start-installation.md . Install using Vagrant (Windows user manual).

25. Add the following code to the hosts file.

Plaintext
# github-shuijingwan-yii2-app-advanced Vagrant
192.168.83.137 y2aa-frontend.test y2aa-backend.test y2aa-api.test y2aa-rpc.test

26. Open Windows PowerShell, switch the path to the project root directory, and execute the following command (requires a VPN/proxy and may need to be executed multiple times). If an error occurs during the process, refer to step 20 for handling. Error: The name of your virtual machine couldn’t be set because VirtualBox
is reporting another VM with that name already exists. Open VirtualBox, delete the virtual machine ubuntu-16.04-amd64_1533104831432_66987, and delete the directory F:\VirtualBox VMs\ubuntu-16.04-amd64_1533105278434_57210.

Bash
vagrant plugin install vagrant-hostmanager
vagrant up

27. Wait for completion, then access the following URLs in a browser. They work as expected.

frontend: http://y2aa-frontend.test
backend: http://y2aa-backend.test
api: http://y2aa-api.test
rpc: http://y2aa-rpc.test

系列导航

关于作者 · 持续学习与技术实践

我是一名拥有 15 年以上开发经验的技术从业者,自 2013 年起持续运营个人技术博客,记录工作与个人项目中遇到的真实问题,以及解决问题过程中的探索、实践和思考。

除了技术写作,我也在持续开发和维护自己的独立项目,探索新技术和新工具在实际场景中的应用。我始终相信,没有不值得去解决的问题,也没有不值得去学习的技术。

如果这篇文章对你有所帮助,欢迎浏览博客中的其他文章,也欢迎交流技术经验与想法。

关于我  ·  GitHub  ·  邮件联系